diff --git a/.aspell.en.pws b/.aspell.en.pws index 2c0d09fdf..3fc6da7c4 100644 --- a/.aspell.en.pws +++ b/.aspell.en.pws @@ -387,3 +387,5 @@ CHECKSIGVERIFY IFDUP sats anysegwit +WebSocket +websocket diff --git a/07-routing-gossip.md b/07-routing-gossip.md index b89c3d222..a8b35e60c 100644 --- a/07-routing-gossip.md +++ b/07-routing-gossip.md @@ -285,6 +285,7 @@ The following `address descriptor` types are defined: onion service addresses; Encodes: `[32:32_byte_ed25519_pubkey] || [2:checksum] || [1:version]`, where `checksum = sha3(".onion checksum" | pubkey || version)[:2]`. + * `6`: WebSocket port; data = `[2:port]` (length 2) ### Requirements @@ -306,12 +307,16 @@ The origin node: - MUST place address descriptors in ascending order. - SHOULD NOT place any zero-typed address descriptors anywhere. - SHOULD use placement only for aligning fields that follow `addresses`. - - MUST NOT create a `type 1` OR `type 2` address descriptor with `port` equal + - MUST NOT create a `type 1`, `type 2` or `type 6` address descriptor with `port` equal to 0. - SHOULD ensure `ipv4_addr` AND `ipv6_addr` are routable addresses. - MUST set `features` according to [BOLT #9](09-features.md#assigned-features-flags) - SHOULD set `flen` to the minimum length required to hold the `features` bits it sets. + - MUST NOT add a `type 6` address unless there is also at least one address of different type. + - if it adds a type 6 address: + - MUST allow unencrypted RFC6455[3](#reference-3) as a transport when a connection is made to at least one of the other addresses, with the type 6 `port` substituted for that address's `port` + - SHOULD allow this on ALL of the other addresses. The receiving node: - if `node_id` is NOT a valid compressed public key: @@ -359,6 +364,12 @@ to be ordered in ascending order, unknown ones can be safely ignored. Additional fields beyond `addresses` may also be added in the future—with optional padding within `addresses`, if they require certain alignment. +Websockets generally are run on adjacent ports (or even overloaded on +the same port) as existing "raw" transports, so including just the +port is a compromise which avoids replacating all the addresses. It's +ideal if all addresses support this, but it's not a hard requirement: +at least one must. + ### Security Considerations for Node Aliases Node aliases are user-defined and provide a potential avenue for injection @@ -1123,6 +1134,7 @@ above. 1. [RFC 1950 "ZLIB Compressed Data Format Specification version 3.3](https://www.ietf.org/rfc/rfc1950.txt) 2. [Maximum Compression Factor](https://zlib.net/zlib_tech.html) +3. [RFC 6455 "The WebSocket Protocol"](https://datatracker.ietf.org/doc/html/rfc6455) ![Creative Commons License](https://i.creativecommons.org/l/by/4.0/88x31.png "License CC-BY")
diff --git a/08-transport.md b/08-transport.md index 49ca45e05..6c654533d 100644 --- a/08-transport.md +++ b/08-transport.md @@ -18,6 +18,7 @@ of a node. * [Handshake State](#handshake-state) * [Handshake State Initialization](#handshake-state-initialization) * [Handshake Exchange](#handshake-exchange) + * [Alternate Transport Layers: WebSocket](#websocket) * [Lightning Message Specification](#lightning-message-specification) * [Encrypting and Sending Messages](#encrypting-and-sending-messages) * [Receiving and Decrypting Messages](#receiving-and-decrypting-messages) @@ -402,6 +403,36 @@ construction, and 16 bytes for a final authenticating tag. 10. `rn = 0, sn = 0` * The sending and receiving nonces are initialized to 0. +## Alternate Transport Layers: WebSocket + +Normally the transport protocol defined here is performed over TCP/IP, +but it can also be performed over other underlying transports, such as +the WebSocket protocol as specified in +RFC6455[4](#reference-4) on ports so-advertized (in the +[node_announcement message](07-routing-gossip.md#the-node_announcement-message). + +A client may connect to this port node and initiate a WebSocket; and +operate the protocol over binary WebSocket frames instead of raw TCP/IP. + + +### Requirements + +The initiator: +- MAY attempt to initiate an unencrypted WebSocket as specified in RFC6455[4](#reference-4): + - MUST abort the connection attempt if WebSocket upgrade fails. + - MUST begin the [Handshake Exchange](#handshake-exchange) as initiator + as soon as upgrade succeeds. + +The responder: +- if it supports WebSocket connections on a port: + - SHOULD advertize it using a type 5 address its node announcement. + - MUST abort the connection attempt if WebSocket upgrade fails. + +Both nodes, after upgrade: + - MUST use binary frames to send and receive messages. + - MUST NOT rely on WebSocket framing for message semantics. + + ## Lightning Message Specification At the conclusion of Act Three, both sides have derived the encryption keys, which @@ -779,6 +810,7 @@ TODO(roasbeef); fin 1.
https://tools.ietf.org/html/rfc8439 2. http://noiseprotocol.org/noise.html 3. https://tools.ietf.org/html/rfc5869 +4. https://tools.ietf.org/html/rfc6455 # Authors diff --git a/09-features.md b/09-features.md index b508bac70..29949e191 100644 --- a/09-features.md +++ b/09-features.md @@ -88,4 +88,5 @@ This work is licensed under a [Creative Commons Attribution 4.0 International Li [bolt07-sync]: 07-routing-gossip.md#initial-sync [bolt07-query]: 07-routing-gossip.md#query-messages [bolt04-mpp]: 04-onion-routing.md#basic-multi-part-payments +[bolt08-websocket]: 08-transport.md#websocket [ml-sighash-single-harmful]: https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-September/002796.html