Skip to content

Commit

Permalink
Server protocol: add PoW
Browse files Browse the repository at this point in the history
  • Loading branch information
piegamesde committed May 7, 2021
1 parent 4affa6f commit 42798a9
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion server-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -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": "<snip>"
}
```
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
Expand All @@ -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": "<snip>",
"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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 42798a9

Please sign in to comment.