holochain / sbd

Simple websocket-based message relay servers and clients
Apache License 2.0
2 stars 0 forks source link

Initial SBD Client and Server #2

Closed neonphog closed 2 months ago

neonphog commented 2 months ago

RESOLVES: https://github.com/holochain/sbd/issues/6 RESOLVES: https://github.com/holochain/sbd/issues/7 RESOLVES: https://github.com/holochain/sbd/issues/10 RESOLVES: https://github.com/holochain/sbd/issues/12

The autobahn-style runners are largely placeholders at the moment, with single smoke tests in them. We'll need to fill those out in a follow-on PR.

I'm going to copy the spec.md file into this PR description so you can see a rendered version of it:


SBD Spec

This SBD spec defines the protocol for SBD servers and clients to communicate. SBD is a simple websocket-based message relay protocol.

1. Websocket Stack

The SBD protocol is built upon websockets.

1.1. Websocket Configuration

1.1.1. Message and Frame Size

The maximum SBD message size (including 32 byte header) is 20000 bytes.

SBD clients and servers MAY set the max message size in the websocket library to 20000 to help enforce this.

The maximum frame size MUST be set larger than 20000 so that sbd messages always fit in a single websocket frame.

2. Cryptography

2.1. TLS

Generally over the WAN SBD servers SHOULD be available over TLS (wss://), and on a LAN without (ws://).

2.2. Ed25519

Clients will be identified by ed25519 public key. Client sessions will be validated by ed25519 signature.

3. Protocol

3.1. Connect Path

Clients MUST specify exactly 1 http path item on the websocket connection url. This item must be the base64url encoded public key that this client will be identified by. This public key MUST be unique to this new connection.

3.2. Messages

3.2.1. Header

SBD messages always contain first a 32 byte header. Messages less than 32 bytes are invalid.

If the header starts with 28 zero bytes, the message is a "command". Otherwise, the message is a "forward".

If the header is a "command" the next four literal ascii bytes are interpreted as the command type:

If the header is a "forward" type, the 32 byte header is interpreted as the public key to forward the message to. The remaining bytes in the message are the data to forward.

3.2.2. Forward

When a client sends a "forward" message to the server, the first 32 bytes represent the peer the message should be forwarded to.

When a server sends a "forward" message to the client the message should be forwarded to the first 32 bytes will be altered to represent the peer from which the message originated.

3.2.3. Flow

sequenceDiagram
S->>C: lbrt
S->>C: lidl
S->>C: areq
C->>S: ares
S->>C: srdy
C->>S: "forward"
S->>C: "forward"
S->>C: lbrt
C->>S: keep

3.2.4. lidl and Keepalive

The lidl "Limit Idle Millis" message is the millisecond count the server will keep a connection around without having seen any messages sent from that client. If a client does not have any forward messages to send within this time period and wishes to keep the connection open they SHOULD send a keep message to maintain the connection. Note this keep message will be counted against rate limiting.

3.2.5. lbrt and rate limiting

The lbrt "Limit Byte Nanos" message indicates the nanoseconds of rate limiting used up by a single byte sent. This is intuitively backwards of a "limit" because higher values indicate you need to send data more slowly, but this direction is easier to work with in code. That is, if lbrt is 1, you can send one byte every nanosecond. A more reasonable librt value of 8000 means you can send 1 byte every 8000 nanoseconds. Or more reasonably, if you send a 16000 byte message, you should wait 8000 * 16000 nanoseconds before sending the next message.

A server MUST provide a "burst" grace window to account for message size.

A server MAY track rate limiting by some metric other than individual connection. IP address, for example. Then, if additional connections are established from the same other metric, all connections could be notified of needing to send data more slowly.

3.2.6. Extensibility

In order to make this protocol extensible without versioning, clients and servers MUST ignore unknown command types. (With the exception that servers should still count the raw bytes in rate limiting.)

3.3. Violations

If a server receives an invalid message from a client it MUST immediately drop the connection with no closing frame.

If a server receives a message that violates the rate limit, the connection MUST similarly be dropped with no closing frame. The server MAY also block connections (perhaps by IP address) for an unspecified amount of time.

jost-s commented 2 months ago

@neonphog What does SBD stand for? I suggest to mention that somewhere =)

neonphog commented 2 months ago

@jost-s

@neonphog What does SBD stand for? I suggest to mention that somewhere =)

https://github.com/holochain/sbd/pull/2/commits/185662835bf8586805dfb5f134c5f0a7aed3bed3

SBD doesn't stand for anything. Imagine it however you like. Secure By Design... STUN By Default... Silent But Deadly...