From b6d4ff4f1a4344e615034a220164729b8e180fc1 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 25 Jul 2021 16:34:48 +0200 Subject: [PATCH 01/13] addressing: describe multiaddrs containing the security protocol --- addressing/README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/addressing/README.md b/addressing/README.md index 94be9c863..454927f6d 100644 --- a/addressing/README.md +++ b/addressing/README.md @@ -147,6 +147,33 @@ within it. Using our example above, decapsulating either `/tcp/1234/ws` _or_ unsurprising if you consider the utility of the `/ip4/7.7.7.7/ws` address that would result from simply removing the `tcp` component. +### The security multiaddr + +Peers MAY advertise their addresses without the security protocol, e.g. +`/ip4/6.6.6.6/tcp/1234/` or `/ip4/6.6.6.6/udp/1234/quic`. The security handshake +protocol is then negotiated using the [multistream](../multistream.md). This is +the way the libp2p handshake worked until mid 2021. +This poses a security problem, as the negotiation was not authenticated and +therefore susceptible to man-in-the-middle attacks. A MITM could modify the list +of supported handshake protocols, thereby forcing a downgrade to a (potentially) +less secure handshake protocol. Note that since QUIC is standardized to use +TLS 1.3, no handshake protocol needs to be negotiated when using QUIC. + +Peers SHOULD encapsulate the security protocol in the addresses they advertise, +for example `/ip4/6.6.6.6/tcp/1234/tls` for a TLS 1.3 server listening on TCP +port 1234 and `/ip4/6.6.6.6/tcp/1235/noise` for a Noise server listening on TCP +port 1235. QUIC multiaddrs remain unchanged. +The nodes jump straight into a cryptographic handshake, thus curtailing the +possibility of packet-inspection-based censorship and dynamic downgrade attacks. +This also applies to circuit addresses: the security protocol is encoded in the +`` as defined in [`p2p-circuit` Relay Addresses](#p2p-circuit-relay-addresses). + +Implementations using [Protocol Select](https://github.com/libp2p/specs/pull/349/) +(**TODO**: update link) MUST encapsulate the security protocol in the multiaddr. +Note that it’s valid to assume that any node that encapsulated the security +protocol in their multiaddr also supports Protocol Select. + + ### The p2p multiaddr libp2p defines the `p2p` multiaddr protocol, whose address component is the From 13fa14747cbef4cf19aaead45906869d04e6c05a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 26 Jul 2021 11:01:25 +0200 Subject: [PATCH 02/13] apply @mxinden's suggestions from code review Co-authored-by: Max Inden --- addressing/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addressing/README.md b/addressing/README.md index 454927f6d..f8c7fb8f4 100644 --- a/addressing/README.md +++ b/addressing/README.md @@ -147,11 +147,11 @@ within it. Using our example above, decapsulating either `/tcp/1234/ws` _or_ unsurprising if you consider the utility of the `/ip4/7.7.7.7/ws` address that would result from simply removing the `tcp` component. -### The security multiaddr +### The multiaddr security component -Peers MAY advertise their addresses without the security protocol, e.g. +Peers MAY advertise their addresses without a security protocol, e.g. `/ip4/6.6.6.6/tcp/1234/` or `/ip4/6.6.6.6/udp/1234/quic`. The security handshake -protocol is then negotiated using the [multistream](../multistream.md). This is +protocol is then negotiated using [multistream-select](../connections/README.md#multistream-select). This is the way the libp2p handshake worked until mid 2021. This poses a security problem, as the negotiation was not authenticated and therefore susceptible to man-in-the-middle attacks. A MITM could modify the list From 35ccd7c60f28a070b00cf7bf38e4c1d3404debc1 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 26 Jul 2021 11:18:20 +0200 Subject: [PATCH 03/13] add missing 'not' --- addressing/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addressing/README.md b/addressing/README.md index f8c7fb8f4..793174c1d 100644 --- a/addressing/README.md +++ b/addressing/README.md @@ -170,7 +170,7 @@ This also applies to circuit addresses: the security protocol is encoded in the Implementations using [Protocol Select](https://github.com/libp2p/specs/pull/349/) (**TODO**: update link) MUST encapsulate the security protocol in the multiaddr. -Note that it’s valid to assume that any node that encapsulated the security +Note that it’s not valid to assume that any node that encapsulated the security protocol in their multiaddr also supports Protocol Select. From c8b3b09fbcf9acb68b31e741ee77baa72622a374 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 26 Jul 2021 21:09:13 +0200 Subject: [PATCH 04/13] add paragraph about hard-coded multiaddrs Co-authored-by: Max Inden --- addressing/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/addressing/README.md b/addressing/README.md index 793174c1d..abc6bc51a 100644 --- a/addressing/README.md +++ b/addressing/README.md @@ -168,6 +168,13 @@ possibility of packet-inspection-based censorship and dynamic downgrade attacks. This also applies to circuit addresses: the security protocol is encoded in the `` as defined in [`p2p-circuit` Relay Addresses](#p2p-circuit-relay-addresses). +Advertising the secure channel protocol through the peer's Multiaddr instead of +negotiating the protocol in-band forces users to advertise an updated Multiaddr +when changing the secure channel protocol in use. This is especially cumbersome +when using hardcoded Multiaddresses. Users may leverage the [dnsaddr] Multiaddr +protocol as well as using a new UDP or TCP port for the new protocol to ease the +transition. + Implementations using [Protocol Select](https://github.com/libp2p/specs/pull/349/) (**TODO**: update link) MUST encapsulate the security protocol in the multiaddr. Note that it’s not valid to assume that any node that encapsulated the security From 85f80ca34a412cc83ece06add8215c794db90b30 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 27 Jul 2021 16:08:32 +0200 Subject: [PATCH 05/13] connections/: Adjust to multiaddr change --- connections/README.md | 49 +++++++++++------------- connections/conn-upgrade.plantuml | 26 +++---------- connections/conn-upgrade.svg | 63 +++++++++++++------------------ 3 files changed, 55 insertions(+), 83 deletions(-) diff --git a/connections/README.md b/connections/README.md index 820bc6209..24e9137ca 100644 --- a/connections/README.md +++ b/connections/README.md @@ -99,10 +99,11 @@ connections, and **listen** to refer to accepting inbound connections. One of libp2p's core design goals is to be adaptable to many network environments, including those that don't yet exist. To provide this flexibility, the connection upgrade process supports multiple protocols for connection -security and stream multiplexing and allows peers to select which to use for -each connection. +security and stream multiplexing. While security protocols are specified +out-of-band through a peer's multiaddr (see [addressing specification]), stream +multiplexing protocols are selected in-band. -The process of selecting protocols is called **protocol negotiation**. In +The process of selecting protocols in-band is called **protocol negotiation**. In addition to its role in the connection upgrade process, protocol negotiation is also used whenever [a new stream is opened over an existing connection](#opening-new-streams-over-a-connection). This allows libp2p @@ -133,10 +134,10 @@ details, see [the multistream-select repository][mss]. Before engaging in the multistream-select negotiation process, it is assumed that the peers have already established a bidirectional communication channel, -which may or may not have the security and multiplexing capabilities of a libp2p -connection. If those capabilities are missing, multistream-select is used in the -[connection upgrade process](#upgrading-connections) to determine how to provide -them. +which may or may not have the multiplexing capability of a libp2p connection. If +that capability is missing, multistream-select is used in the [connection +upgrade process](#upgrading-connections) to determine which multiplexing +protocol to use on a given connection. Messages are sent encoded as UTF-8 byte strings, and they are always followed by a `\n` newline character. Each message is also prefixed with its length in bytes @@ -190,11 +191,10 @@ that do not natively support the core libp2p capabilities of security and stream multiplexing. The process of layering capabilities onto "raw" transport connections is called "upgrading" the connection. -Because there are many valid ways to provide the libp2p capabilities, the -connection upgrade process uses protocol negotiation to decide which specific -protocols to use for each capability. The protocol negotiation process uses -multistream-select as described in the [Protocol -Negotiation](#protocol-negotiation) section. +The security protocol to be used on a connection is determined through the +listeners multiaddr. The multiplexing protocol is determined using protocol +negotiation. The protocol negotiation process uses multistream-select as +described in the [Protocol Negotiation](#protocol-negotiation) section. When raw connections need both security and multiplexing, security is always established first, and the negotiation for stream multiplexing takes place over @@ -204,23 +204,19 @@ Here's an example of the connection upgrade process: ![see conn-upgrade.plantuml for diagram source](conn-upgrade.svg) -First, the peers both send the multistream protocol id to establish that they'll -use multistream-select to negotiate protocols for the connection upgrade. -Next, the Initiator proposes the [TLS protocol][tls-libp2p] for encryption, but -the Responder rejects the proposal as they don't support TLS. +The security protocol to be used on a connection is determined by the listener's +multiaddr, see [addressing specification], in this case the Noise protocol. The +peers exchange the Noise handshake to establish a secure channel. If the Noise +handshake fails, the connection establishment process aborts. If successful, the +peers will use the secured channel for all future communications, including the +remainder of the connection upgrade process. -The Initiator then proposes the [Noise protocol][noise-spec], which is supported -by the Responder. The Listener echoes back the protocol id for Noise to indicate -agreement. +Once security has been established, the peers both send the multistream protocol +id to establish that they'll use multistream-select to negotiate protocols for +the connection upgrade. -At this point the Noise protocol takes over, and the peers exchange the Noise -handshake to establish a secure channel. If the Noise handshake fails, the -connection establishment process aborts. If successful, the peers will use the -secured channel for all future communications, including the remainder of the -connection upgrade process. - -Once security has been established, the peers negotiate which stream multiplexer +Then the peers negotiate which stream multiplexer to use. The negotiation process works in the same manner as before, with the dialing peer proposing a multiplexer by sending its protocol id, and the listening peer responding by either echoing back the supported id or sending @@ -409,3 +405,4 @@ updated to incorporate the changes. [simopen]: ./simopen.md [resource-manager-issue]: https://github.com/libp2p/go-libp2p/issues/635 [hole-punching]: ./hole-punching.md +[addressing specification]: ../addressing/README.md diff --git a/connections/conn-upgrade.plantuml b/connections/conn-upgrade.plantuml index b2d497630..911f5fa4f 100644 --- a/connections/conn-upgrade.plantuml +++ b/connections/conn-upgrade.plantuml @@ -1,28 +1,16 @@ @startuml - entity Initiator entity Responder -== Initial multistream handshake == - -Responder -> Initiator: /multistream/1.0.0 -Initiator -> Responder: /multistream/1.0.0 - -== Negotiate security protocol == -Initiator -> Responder: /tls/1.0.0 -note left: Initiator proposes TLS for security +== Upgrade with security protocol from listener's multiaddr == -Responder -> Initiator: na -note right: Responder does not support TLS yet +... Security handshake ... -Initiator -> Responder: /noise -note left: Initiator falls back to Noise - -Responder -> Initiator: /noise -note right: Responder supports Noise, echoes back protocol id +== Initial multistream handshake == -... Noise handshake ... +Responder -> Initiator: /multistream/1.0.0 +Initiator -> Responder: /multistream/1.0.0 == Negotiate stream multiplexer == @@ -31,6 +19,4 @@ note left: Initiator proposes mplex for stream multiplexing Responder -> Initiator: /mplex/1.0.0 note right: Responder supports mplex, echoes back protocol id - - -@enduml +@enduml \ No newline at end of file diff --git a/connections/conn-upgrade.svg b/connections/conn-upgrade.svg index 443b6d8ac..846fe4f98 100644 --- a/connections/conn-upgrade.svg +++ b/connections/conn-upgrade.svg @@ -1,43 +1,32 @@ -InitiatorInitiatorResponderResponderInitial multistream handshake/multistream/1.0.0/multistream/1.0.0Negotiate security protocol/tls/1.0.0Initiator proposes TLS for securitynaResponder does not support TLS yet/noiseInitiator falls back to Noise/noiseResponder supports Noise, echoes back protocol idNoise handshakeNegotiate stream multiplexer/mplex/1.0.0Initiator proposes mplex for stream multiplexing/mplex/1.0.0Responder supports mplex, echoes back protocol id \ No newline at end of file +--> From c01af99ee32881a675df766aa55f8cc24d7eb42c Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 12 Aug 2021 11:06:05 +0200 Subject: [PATCH 06/13] *: Address security-protocol-in-multiaddr and relay conflict (#359) --- addressing/README.md | 56 ++++++++++++++++++++++++++++++++++++----- relay/circuit-v2.md | 60 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 107 insertions(+), 9 deletions(-) diff --git a/addressing/README.md b/addressing/README.md index abc6bc51a..68aa91df0 100644 --- a/addressing/README.md +++ b/addressing/README.md @@ -202,7 +202,7 @@ within](#encapsulation) another multiaddr. For example, the above `p2p` address can be combined with the transport address on which the node is listening: -``` +``` /ip4/7.7.7.7/tcp/1234/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N ``` @@ -235,7 +235,7 @@ appreciated. Most libp2p transports use the IP protocol as a foundational layer, and as a result, most transport multiaddrs will begin with a component that represents an -IPv4 or IPv6 address. +IPv4 or IPv6 address. This may be an actual address, such as `/ip4/7.7.7.7` or `/ip6/fe80::883:a581:fff1:833`, or it could be something that resolves to an IP @@ -255,7 +255,7 @@ resolvable or "name-based" protocols: When the `/dns` protocol is used, the lookup may result in both IPv4 and IPv6 addresses, in which case IPv6 will be preferred. To explicitly resolve to IPv4 -or IPv6 addresses, use the `/dns4` or `/dns6` protocols, respectively. +or IPv6 addresses, use the `/dns4` or `/dns6` protocols, respectively. Note that in some restricted environments, such as inside a web browser, libp2p may not have access to the resolved IP addresses at all, in which case the @@ -305,7 +305,7 @@ wherever TCP/IP sockets are accessible. Addresses for the TCP transport are of the form `/tcp/`, where `` is a multiaddr that resolves to an IP address, as -described in the [IP and Name Resolution section](#ip-and-name-resolution). +described in the [IP and Name Resolution section](#ip-and-name-resolution). The `` argument must be a 16-bit unsigned integer. ### WebSockets @@ -324,7 +324,7 @@ multiaddr format mirrors this arrangement. A libp2p QUIC multiaddr is of the form `/udp//quic`, where `` is a multiaddr that resolves to an IP address, as -described in the [IP and Name Resolution section](#ip-and-name-resolution). +described in the [IP and Name Resolution section](#ip-and-name-resolution). The `` argument must be a 16-bit unsigned integer in network byte order. @@ -354,7 +354,7 @@ destination peer. A full example would be: -``` +``` /ip4/127.0.0.1/tcp/5002/p2p/QmdPU7PfRyKehdrP5A3WqmjyD6bhVpU1mLGKppa2FjGDjZ/p2p-circuit/p2p/QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt ``` @@ -363,6 +363,50 @@ Here, the destination peer has the peer id relay node with peer id `QmdPU7PfRyKehdrP5A3WqmjyD6bhVpU1mLGKppa2FjGDjZ` running on TCP port 5002 of the IPv4 loopback interface. +#### Relay addresses and multiaddr security component + +Instead of negotiating the security protocol in-band, security protocols should +be encapsulated in the multiaddr (see [The multiaddr security component +section](#the-multiaddr-security-component)). Establishing a single relayed +connection involves 3 security protocol upgrades: + +1. Upgrading the connection from the source to the relay. + + The security protocol is specified in the relay multiaddr (before + `p2p-circuit`). + + Example: `/ip4/6.6.6.6/tcp/1234/tls/p2p/QmRelay/p2p-circuit/` + +2. Upgrading the connection from the relay to the destination. + + The security protocol is specified in the destination multiaddr (after + `p2p-circuit`). + + Note: Specifying this security protocol is only necessary for active + relaying. In the case of passive relaying the connection established by the + destination to the relay will be used to relay the connection. + + Example: + - Passive relaying: `/p2p-circuit/p2p/QmDestination` + - Active relaying: `/p2p-circuit/ip4/6.6.6.6/tcp/1234/tls/p2p/QmDestination` + +3. Upgrading the relayed connection from the source to the destination. + + The security protocol is specified by appending + `/p2p-circuit-inner/` to the full + address. + + + + Example: `/p2p-circuit//p2p-circuit-inner/tls` + + Note: One might be tempted to not specify (3) and simply use the security + protocol in (2). This would break if the security protocol used for (2) can + not be used for (3), e.g. in the case where the relay establishes a QUIC + connection to the destination secured via TLS and the source only supports + Noise. + [peer-id-spec]: ../peer-ids/peer-ids.md [identify-spec]: ../identify/README.md diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 90c7f8510..cd173dbb7 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -294,6 +294,42 @@ Common failure status codes are: ***Note: implementations _should not_ accept connection initiations over already relayed connections*** +##### Security protocol selection for the relayed connection + +Instead of negotiating the security protocol in-band, security protocols should +be encapsulated in the multiaddr (see [The multiaddr security component +section](../addressing/README.md#the-multiaddr-security-component)). A relayed +connection is not an exception. A target advertises the support for a security +protocol for relayed connections by appending +`/p2p-circuit-inner/` to its relayed multiaddresses. An +initiator may include any set of relayed multiaddr in the `peer` field of +`HopMessage` on type `CONNECT` in which all addresses end with the same +`/p2p-circuit-inner/`. The initiator is thus signaling to the +target which security protocol, out of all advertised security protocols +by the target, the initiator chose to use on the relayed connection. + +As an example, let's say the target listens for incoming relayed connections via +relay `R1` and relay `R2`. In addition it supports both TLS Noise as security +protocols. It would then advertise the following relayed multiaddresses: + +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/tls` +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/noise` +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/tls` +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/noise` + +Once the initiator received the above multiaddresses and decides to initiate a +relayed connection to the target, it needs to decide whether it wants to secure +the relayed connection via TLS or Noise. Say it decides for Noise it would then +include the multiaddresses below in it `HopMessage` with type `Connect` in the +`peer` field: + +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/noise` +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/noise` + +Note that all addresses sent by the initiator in the `peer` field MUST share the +same security protocol for the relayed connection +(`/p2p-circuit-inner/`). + ### Stop Protocol The Stop protocol governs connection termination between the relay and the target peer; @@ -309,11 +345,13 @@ The relay sends a `StopMessage` with `type = CONNECT` and the following form: ``` StopMessage { type = CONNECT - peer = Peer { ID = ...} + initiator = Peer { ID = ...} + target = Peer { addrs = ...} limit = Limit { ...} } ``` -- the `peer` field contains a `Peer` struct with the peer `ID` of the connection initiator. +- the `initiator` field contains a `Peer` struct with the peer `ID` of the connection initiator. +- the `target` field contains a `Peer` struct with the peer `addrs` of the target that the initiator included in its `HopMessage`. - the `limit` field, if present, conveys the limits applied to the relayed connection with the semantics described [above](#reservation). If the target peer accepts the connection it responds to the relay with a `StopMessage` of `type = STATUS` and `status = OK`: @@ -330,6 +368,21 @@ If the target fails to terminate the connection for some reason, then it respond Common failure status codes are: - `CONNECTION_FAILED` if the target internally failed to create the relayed connection for some reason. +#### Security protocol selection for the relayed connection + +A target may advertise support for different security protocols by advertising +multiple multiaddresses with different `/p2p-circuit-inner/` +suffixes. A target needs some mechanism to determine which of the advertised +security protocols the initiator intends to use to secure an incoming relayed +connection. The target can use the addresses included in the `target` field of +the `StopMessage` to determine which security protocol the initiator chose to +secure the relayed connection. + +Note that all addresses sent by the initiator MUST share the same security +protocol for the relayed connection (`/p2p-circuit-inner/`). +Thus a target MUST abort the connection attempt (i.e. reset the stream) if it +receives a `CONNECT` with varying security protocols for the relay connection. + ### Reservation Vouchers Successful relay slot reservations should come with _Reservation Vouchers_. @@ -383,7 +436,8 @@ message StopMessage { required Type type = 1; - optional Peer peer = 2; + optional Peer initiator = 2; + optional Peer target = 5; optional Limit limit = 3; optional Status status = 4; From 6d8004e9cd5ec58f8b564443554838a553c02f0e Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 30 Aug 2021 14:17:55 +0200 Subject: [PATCH 07/13] addressing/: Link to circuit relay v2 addressing section --- addressing/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addressing/README.md b/addressing/README.md index 68aa91df0..23ddfb090 100644 --- a/addressing/README.md +++ b/addressing/README.md @@ -407,9 +407,13 @@ connection involves 3 security protocol upgrades: connection to the destination secured via TLS and the source only supports Noise. + See [Security protocol selection for the relayed connection] for details on + how the above integrates with the circuit relayv 2 _Hop_ and _Stop_ protocol. + [peer-id-spec]: ../peer-ids/peer-ids.md [identify-spec]: ../identify/README.md [multiaddr-repo]: https://github.com/multiformats/multiaddr [multiaddr-proto-table]: https://github.com/multiformats/multiaddr/blob/master/protocols.csv [relay-spec]: ../relay/README.md +[Security protocol selection for the relayed connection]: ../relay/circuit-v2.md#security-protocol-selection-for-the-relayed-connection From 3c1487a106943ade936c5185def680c67c9496c8 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 4 Oct 2021 16:55:41 +0200 Subject: [PATCH 08/13] *: Rename p2p-circuit-inner to p2p-circuit-security --- addressing/README.md | 7 ++----- relay/circuit-v2.md | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/addressing/README.md b/addressing/README.md index 23ddfb090..77c5007ee 100644 --- a/addressing/README.md +++ b/addressing/README.md @@ -393,13 +393,10 @@ connection involves 3 security protocol upgrades: 3. Upgrading the relayed connection from the source to the destination. The security protocol is specified by appending - `/p2p-circuit-inner/` to the full + `/p2p-circuit-security/` to the full address. - - - Example: `/p2p-circuit//p2p-circuit-inner/tls` + Example: `/p2p-circuit//p2p-circuit-security/tls` Note: One might be tempted to not specify (3) and simply use the security protocol in (2). This would break if the security protocol used for (2) can diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index cd173dbb7..40c956f62 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -301,10 +301,10 @@ be encapsulated in the multiaddr (see [The multiaddr security component section](../addressing/README.md#the-multiaddr-security-component)). A relayed connection is not an exception. A target advertises the support for a security protocol for relayed connections by appending -`/p2p-circuit-inner/` to its relayed multiaddresses. An +`/p2p-circuit-security/` to its relayed multiaddresses. An initiator may include any set of relayed multiaddr in the `peer` field of `HopMessage` on type `CONNECT` in which all addresses end with the same -`/p2p-circuit-inner/`. The initiator is thus signaling to the +`/p2p-circuit-security/`. The initiator is thus signaling to the target which security protocol, out of all advertised security protocols by the target, the initiator chose to use on the relayed connection. @@ -312,10 +312,10 @@ As an example, let's say the target listens for incoming relayed connections via relay `R1` and relay `R2`. In addition it supports both TLS Noise as security protocols. It would then advertise the following relayed multiaddresses: -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/tls` -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/noise` -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/tls` -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/noise` +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/tls` +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/noise` +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/tls` +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/noise` Once the initiator received the above multiaddresses and decides to initiate a relayed connection to the target, it needs to decide whether it wants to secure @@ -323,12 +323,12 @@ the relayed connection via TLS or Noise. Say it decides for Noise it would then include the multiaddresses below in it `HopMessage` with type `Connect` in the `peer` field: -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/noise` -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-inner/noise` +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/noise` +- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/noise` Note that all addresses sent by the initiator in the `peer` field MUST share the same security protocol for the relayed connection -(`/p2p-circuit-inner/`). +(`/p2p-circuit-security/`). ### Stop Protocol @@ -371,7 +371,7 @@ Common failure status codes are: #### Security protocol selection for the relayed connection A target may advertise support for different security protocols by advertising -multiple multiaddresses with different `/p2p-circuit-inner/` +multiple multiaddresses with different `/p2p-circuit-security/` suffixes. A target needs some mechanism to determine which of the advertised security protocols the initiator intends to use to secure an incoming relayed connection. The target can use the addresses included in the `target` field of @@ -379,7 +379,7 @@ the `StopMessage` to determine which security protocol the initiator chose to secure the relayed connection. Note that all addresses sent by the initiator MUST share the same security -protocol for the relayed connection (`/p2p-circuit-inner/`). +protocol for the relayed connection (`/p2p-circuit-security/`). Thus a target MUST abort the connection attempt (i.e. reset the stream) if it receives a `CONNECT` with varying security protocols for the relay connection. From 90bef6fa4752add96bff7ebf016d247cc120c34d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 4 Oct 2021 17:35:51 +0200 Subject: [PATCH 09/13] relay/circuit-v2: Move /p2p/QmTarget to the end of Multiaddr --- relay/circuit-v2.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 40c956f62..3660dd673 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -300,8 +300,8 @@ Instead of negotiating the security protocol in-band, security protocols should be encapsulated in the multiaddr (see [The multiaddr security component section](../addressing/README.md#the-multiaddr-security-component)). A relayed connection is not an exception. A target advertises the support for a security -protocol for relayed connections by appending -`/p2p-circuit-security/` to its relayed multiaddresses. An +protocol for relayed connections by including +`/p2p-circuit-security/` in its relayed multiaddresses. An initiator may include any set of relayed multiaddr in the `peer` field of `HopMessage` on type `CONNECT` in which all addresses end with the same `/p2p-circuit-security/`. The initiator is thus signaling to the @@ -312,10 +312,10 @@ As an example, let's say the target listens for incoming relayed connections via relay `R1` and relay `R2`. In addition it supports both TLS Noise as security protocols. It would then advertise the following relayed multiaddresses: -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/tls` -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/noise` -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/tls` -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/noise` +- `/p2p-circuit/p2p-circuit-security/tls/p2p/QmTarget` +- `/p2p-circuit/p2p-circuit-security/noise/p2p/QmTarget` +- `/p2p-circuit/p2p-circuit-security/tls/p2p/QmTarget` +- `/p2p-circuit/p2p-circuit-security/noise/p2p/QmTarget` Once the initiator received the above multiaddresses and decides to initiate a relayed connection to the target, it needs to decide whether it wants to secure @@ -323,8 +323,8 @@ the relayed connection via TLS or Noise. Say it decides for Noise it would then include the multiaddresses below in it `HopMessage` with type `Connect` in the `peer` field: -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/noise` -- `/p2p-circuit/p2p/QmTarget/p2p-circuit-security/noise` +- `/p2p-circuit/p2p-circuit-security/noise/p2p/QmTarget` +- `/p2p-circuit/p2p-circuit-security/noise/p2p/QmTarget` Note that all addresses sent by the initiator in the `peer` field MUST share the same security protocol for the relayed connection From 4de35ef268969a36b74e329b5249b2de10d3ee6d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 4 Oct 2021 18:13:12 +0200 Subject: [PATCH 10/13] relay/circuit-v2: Fix misconception on passive relaying When using passive relaying, there is no need for the initiator to include multiple addresses in the `peer` field of the `HopMessage`. --- relay/circuit-v2.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 3660dd673..747aabe6c 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -303,13 +303,13 @@ connection is not an exception. A target advertises the support for a security protocol for relayed connections by including `/p2p-circuit-security/` in its relayed multiaddresses. An initiator may include any set of relayed multiaddr in the `peer` field of -`HopMessage` on type `CONNECT` in which all addresses end with the same +`HopMessage` on type `CONNECT` in which all addresses include the same `/p2p-circuit-security/`. The initiator is thus signaling to the target which security protocol, out of all advertised security protocols by the target, the initiator chose to use on the relayed connection. As an example, let's say the target listens for incoming relayed connections via -relay `R1` and relay `R2`. In addition it supports both TLS Noise as security +relay `R1` and relay `R2`. In addition it supports both TLS and Noise as security protocols. It would then advertise the following relayed multiaddresses: - `/p2p-circuit/p2p-circuit-security/tls/p2p/QmTarget` @@ -318,16 +318,16 @@ protocols. It would then advertise the following relayed multiaddresses: - `/p2p-circuit/p2p-circuit-security/noise/p2p/QmTarget` Once the initiator received the above multiaddresses and decides to initiate a -relayed connection to the target, it needs to decide whether it wants to secure -the relayed connection via TLS or Noise. Say it decides for Noise it would then -include the multiaddresses below in it `HopMessage` with type `Connect` in the -`peer` field: +relayed connection to the target, it needs to decide whether it wants to use +`R1` or `R2` and whether it wants to secure the relayed connection via TLS or +Noise. Say it decides for `R1` and Noise it would then include the multiaddress +below in it `HopMessage` with type `Connect` in the `peer` field: - `/p2p-circuit/p2p-circuit-security/noise/p2p/QmTarget` -- `/p2p-circuit/p2p-circuit-security/noise/p2p/QmTarget` -Note that all addresses sent by the initiator in the `peer` field MUST share the -same security protocol for the relayed connection +Note when activly relaying and thus potentially including multiple addresses in +the `peer` field that all addresses sent by the initiator MUST share the same +security protocol for the relayed connection (`/p2p-circuit-security/`). ### Stop Protocol From 8807a126f52dac4c3c07461b496d4f2107ce0d80 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 29 Oct 2021 18:50:36 +0200 Subject: [PATCH 11/13] relay/circuit-v2: Bump spec version --- relay/circuit-v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 747aabe6c..8329369cc 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -4,7 +4,7 @@ This is the version 2 of the libp2p Circuit Relay protocol. | Lifecycle Stage | Maturity | Status | Latest Revision | |-----------------|----------------|--------|-----------------| -| 1A | DRAFT | Active | r0, 2021-05-05 | +| 1A | DRAFT | Active | r1, TODO | Authors: [@vyzo] From bb3c4f96fbea49c3fcd57a26e09102cbdb442872 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 29 Oct 2021 19:13:06 +0200 Subject: [PATCH 12/13] relay/circuit-v2: Omit address of relay in HopMessage --- relay/circuit-v2.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 8329369cc..23500927b 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -318,12 +318,12 @@ protocols. It would then advertise the following relayed multiaddresses: - `/p2p-circuit/p2p-circuit-security/noise/p2p/QmTarget` Once the initiator received the above multiaddresses and decides to initiate a -relayed connection to the target, it needs to decide whether it wants to use -`R1` or `R2` and whether it wants to secure the relayed connection via TLS or -Noise. Say it decides for `R1` and Noise it would then include the multiaddress -below in it `HopMessage` with type `Connect` in the `peer` field: +relayed connection to the target, it needs to decide whether it wants to secure +the relayed connection via TLS or Noise. Say it decides for Noise it would then +include the multiaddress below in it `HopMessage` with type `Connect` in the +`peer` field: -- `/p2p-circuit/p2p-circuit-security/noise/p2p/QmTarget` +- /p2p-circuit/p2p-circuit-security/noise/p2p/QmTarget` Note when activly relaying and thus potentially including multiple addresses in the `peer` field that all addresses sent by the initiator MUST share the same From 128e76d36bb72bf6f68d5af2fe42d4f50be74f5f Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 29 Oct 2021 19:19:10 +0200 Subject: [PATCH 13/13] relay/circuit-v2: Use source and destination in StopMessage --- relay/circuit-v2.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 23500927b..1fc0bb19b 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -345,13 +345,13 @@ The relay sends a `StopMessage` with `type = CONNECT` and the following form: ``` StopMessage { type = CONNECT - initiator = Peer { ID = ...} - target = Peer { addrs = ...} + source = Peer { ID = ...} + destination = Peer { addrs = ...} limit = Limit { ...} } ``` -- the `initiator` field contains a `Peer` struct with the peer `ID` of the connection initiator. -- the `target` field contains a `Peer` struct with the peer `addrs` of the target that the initiator included in its `HopMessage`. +- the `source` field contains a `Peer` struct with the peer `ID` of the connection initiator. +- the `destination` field contains a `Peer` struct with the peer `addrs` of the destination that the initiator included in its `HopMessage`. - the `limit` field, if present, conveys the limits applied to the relayed connection with the semantics described [above](#reservation). If the target peer accepts the connection it responds to the relay with a `StopMessage` of `type = STATUS` and `status = OK`: @@ -436,8 +436,8 @@ message StopMessage { required Type type = 1; - optional Peer initiator = 2; - optional Peer target = 5; + optional Peer source = 2; + optional Peer destination = 5; optional Limit limit = 3; optional Status status = 4;