diff --git a/server-protocol.md b/server-protocol.md index 1b36191..d58f178 100644 --- a/server-protocol.md +++ b/server-protocol.md @@ -100,6 +100,18 @@ and handle them accordingly, if present: expect the protocol to be `tcp` (expect websockets support in the future). Clients should make a preselection of viable relay servers (which may include entries from other sources as well), and randomly select one or two. +* `proof_of_work`: A proof of work task to mitigate DOS attacks. The difficulty is dictated + by the server based on its current load. The entry looks like this: + ```json + { + "challenge": "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABXXXX", + "sha256": "a66cdd7def34cb0267b83d21c37c429af0a15dcd00465da22402dab9f1cbf10e", + "mac": "" + } + ``` + The challenge contains exactly 32 hex-encoded bytes, of which the last nibbles are censored ('X'), + and the `sha256sum` of the uncensored challenge. The goal is to find the complete `challenge` with + the given hash. The first thing each client sends to the server, immediately after receiving the welcome message, is a `bind` message. This specifies the @@ -108,6 +120,23 @@ messages will be scoped to. While technically each message could be independent (with its own `appid` and `side`), I thought it would be less confusing to use exactly one WebSocket per logical wormhole connection. +Due to backwards compatibity, clients are not forced to give a proof of work. +However, it is strongly recommended. Here's how a full "bind" message may look like: + +```json +{ + "type": "bind", + "appid": "lothar.com/wormhole/text-or-file-xfer", + "side": "123456", + "proof_of_work": { + "challenge": "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABXXXX", + "sha256": "a66cdd7def34cb0267b83d21c37c429af0a15dcd00465da22402dab9f1cbf10e", + "mac": "", + "response": "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", + }, +} +``` + A `ping` will provoke a `pong`: these are only used by unit tests for synchronization purposes (to detect when a batch of messages have been fully processed by the server). NAT-binding refresh messages are handled by the @@ -216,7 +245,7 @@ This lists all message types, along with the type-specific keys for each (if any), and which ones provoke direct responses: * S->C welcome {welcome:} -* (C->S) bind {appid:, side:} +* (C->S) bind {appid:, side:, proof_of_work: {..},} * (C->S) list {} -> nameplates * S->C nameplates {nameplates: [{id: str},..]} * (C->S) allocate {} -> allocated