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;