From 119e237191d633657ff41781f77c8baea96c6359 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 5 May 2021 13:18:56 +0300 Subject: [PATCH 01/45] move README to circuit-v1.md --- relay/{README.md => circuit-v1.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename relay/{README.md => circuit-v1.md} (100%) diff --git a/relay/README.md b/relay/circuit-v1.md similarity index 100% rename from relay/README.md rename to relay/circuit-v1.md From 22e2721746d0d100a4218c58d65f0f2f86f8c024 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 5 May 2021 14:18:12 +0300 Subject: [PATCH 02/45] circuit v2 spec preliminaries --- relay/README.md | 7 ++ relay/circuit-v2.md | 193 +++++++++++++++++++++++++++++++++++++++++++ relay/circuit-v2.png | Bin 0 -> 79776 bytes 3 files changed, 200 insertions(+) create mode 100644 relay/README.md create mode 100644 relay/circuit-v2.md create mode 100644 relay/circuit-v2.png diff --git a/relay/README.md b/relay/README.md new file mode 100644 index 000000000..3afadbcb8 --- /dev/null +++ b/relay/README.md @@ -0,0 +1,7 @@ +# p2p-circuit relay + +Circuit Switching for libp2p, also known as TURN or Relay in Networking literature. + +Specifications: +- [p2p-circuit v1](circuit-v1.md) +- [p2p-cricuit v2](circuit-v2.md) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md new file mode 100644 index 000000000..881e5e320 --- /dev/null +++ b/relay/circuit-v2.md @@ -0,0 +1,193 @@ +# Circuit Relay v2 + +This is the version 2 of the libp2p Circuit Relay protocol. + +| Lifecycle Stage | Maturity | Status | Latest Revision | +|-----------------|----------------|--------|-----------------| +| 1A | DRAFT | Active | r1, 2021-05-05 | + +Authors: [@vyzo] + +Interest Group: [@mxinden], [@stebalien], [@raulk] + +[@vyzo]: https://github.com/vyzo +[@mxinden]: https://github.com/mxinden +[@stebalien]: https://github.com/stebalien +[@raulk]: https://github.com/raulk + +See the [lifecycle document][lifecycle-spec] for context about maturity level +and spec status. + +[lifecycle-spec]: https://github.com/libp2p/specs/blob/master/00-framework-01-spec-lifecycle.md + +## Table of Contents + +- [Introduction](#introduction) + - [Rationale](#rationale) +- [The Protocol](#the-protocol) + - [Interaction](#interaction) + - [Hop Protocol](#hop-protocol) + - [Stop Protocol](#stop-protocol) + - [Reservation Vouchers](#reservation-vouchers) +- [Protobuf](#protobuf) + +## Introduction + +This is the specification of v2 of the p2p-circuit relay protocol. + +Compared to the first version of the protocol, there are some significant departures: +- The protocol has been split into two subprotocols, `hop` and `stop` + - The `hop` protocol governs the behaviour of relays; it is used for + reserving resources in the relay and opening a switched connection + to a peer through the relay. + - The `stop` protocol governs the termination of circuit switched + connections. +- The concept of resource reservation has been introduced, whereby + peers wishing to use a relay explicitly reserve resources and obtain + _reservation vouchers_ which can be distributed to their peers for + routing purposes. +- The concept of limited relaying has been introduced, whereby relays + provide switched connectivity with a limited duration and data cap. + +### Rationale + +The evolution of the protocol towards v2 has been influenced by our +experience in operating open relays in the wild. The original +protocol, while very flexible, has some limitations when it comes to +the practicalities of relaying connections. + +The main problem is that is no mechanism to reserve resources in the +relay, which leads to continuoues oversubscription of relays and the +necessity of (often inefective) heuristics for balancing resources. +In practice, running a relay proved to be an expensive proposition +requiring dedicated hosts with significant hardware and bandwidth +costs. In addition, there is ongoing work in Hole Punching +coordination for direction connection upgrade through relays, which +doesn't require an unlimited relay connection. + +In order to address the situation and seamlessly support pervasive +hole punching, we have introduced limited relays and slot +reservations. This allows relays to effectively manage their +resources and provide service at a small scale, thus enabling the +deployment of an army of relays for extreme horizontal scaling without +excessive bandwidth costs and dedicated hosts. + +Furthermore, the original decision to conflate circuit initiation and +termination in the same protocol has made it very hard to on provide +relay service on demand, decoupled with whether _client_ functionality +is supported by the host. + +In order to address this problem, we have splt the protocol into the +`hop` and `stop` subprotocols. This allows us to always enable the +client-side functionality in a host, while providing the option to +later mount the relay service in public hosts, _after_ the +reachability of the host has been determined through AutoNAT. + +## The Protocol + +### Interaction + +The following diagram illustrates the interaction between three peers, +_A_, _B_, and _R_, in the course of establishing a relayed connection. +Peer _A_ is a private peer, which is not publicly reachable; it +utilizes the services of peer _R_ as the relay. Peer _B_ is another +peer who wishes to connect to peer _A_ through _R_. + +![Circuit v2 Protocol Interaction](circuit-v2.png) + +The first part of the interaction is _A_'s reservation of a relay slot +in _R_. This is accomplished by opening a connection to _R_ and +sending a `RESERVE` message in the `hop` protocol; if the reservation +is successful, the relay responds with a `STATUS:OK` message and +provides _A_ with a reservation voucher. + +The second part of the interaction is the establishment of a circuit +switch connection from _B_ to _A_ through _R_. It is assumed that _B_ +has obtained a circuit multiaddr for _A_ of the form +`/p2p/QmR/p2p-circuit/p2p/QmA` out of band using some peer discovery +service (eg. the DHT or a rendezvous point). + +In order to connect to _A_, _B_ then conncts to _R_, opens a `hop` +protocol stream and sends a `CONNECT` message to the relay. The relay +verifies that it has a reservation and connection for _A_ and opens a +`stop` protocol stream to _A_, sending a `CONNECT` message. + +Peer _A_ then responds to the relaywith a `STATUS:OK` message, which +responds to _B_ with a `STATUS:OK` message in the open `hop` stream +and then proceeds to bridge the two streams into a relayed connection. +The relayed connection flows in the `hop` stream between the +connection initiator and the relay and in the `stop` stream between +the relay and the connection termination point. + +### Hop Protocol + +TBD + +### Stop Protocol + +TBD + +### Reservation Vouchers + +TBD + +## Protobuf + +``` +message HopMessage { + enum Type { + RESERVE = 0; + CONNECT = 1; + STATUS = 2; + } + + required Type type = 1; + + optional Peer peer = 2; + optional Reservation reservation = 3; + optional Limit limit = 4; + + optional Status status = 5; +} + +message StopMessage { + enum Type { + CONNECT = 0; + STATUS = 1; + } + + required Type type = 1; + + optional Peer peer = 2; + optional Limit limit = 3; + + optional Status status = 4; +} + +message Peer { + required bytes id = 1; + repeated bytes addrs = 2; +} + +message Reservation { + optional int64 expire = 1; // Unix expiration time (UTC) + repeated bytes addrs = 2; // relay addrs for reserving peer + optional bytes voucher = 3; // reservation voucher +} + +message Limit { + optional int32 duration = 1; // seconds + optional int64 data = 2; // bytes +} + +enum Status { + OK = 100; + RESERVATION_REFUSED = 200; + RESOURCE_LIMIT_EXCEEDED = 201; + PERMISSION_DENIED = 202; + CONNECTION_FAILED = 203; + NO_RESERVATION = 204; + MALFORMED_MESSAGE = 400; + UNEXPECTED_MESSAGE = 401; +} +``` diff --git a/relay/circuit-v2.png b/relay/circuit-v2.png new file mode 100644 index 0000000000000000000000000000000000000000..ec4c2c04612113c3411904062b3dd1eb99d5c27d GIT binary patch literal 79776 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 Oz>l}5FH^EHB<^3lwx4|f literal 0 HcmV?d00001 From 91f2ab6162b95099c49b619c21f8e54f5bcdf81a Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 5 May 2021 21:04:21 +0300 Subject: [PATCH 03/45] copy edit Co-authored-by: Max Inden --- 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 881e5e320..1c6a2bd62 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -56,7 +56,7 @@ experience in operating open relays in the wild. The original protocol, while very flexible, has some limitations when it comes to the practicalities of relaying connections. -The main problem is that is no mechanism to reserve resources in the +The main problem is that v1 has no mechanism to reserve resources in the relay, which leads to continuoues oversubscription of relays and the necessity of (often inefective) heuristics for balancing resources. In practice, running a relay proved to be an expensive proposition From 6b791ab89c53ae6c8795711a681ec385d82689e9 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 5 May 2021 21:04:33 +0300 Subject: [PATCH 04/45] copy edit Co-authored-by: Max Inden --- 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 1c6a2bd62..cc6439478 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -62,7 +62,7 @@ necessity of (often inefective) heuristics for balancing resources. In practice, running a relay proved to be an expensive proposition requiring dedicated hosts with significant hardware and bandwidth costs. In addition, there is ongoing work in Hole Punching -coordination for direction connection upgrade through relays, which +coordination for direct connection upgrade through relays, which doesn't require an unlimited relay connection. In order to address the situation and seamlessly support pervasive From e36fe4859d765bddc61350518f7badde43178a69 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 5 May 2021 21:04:49 +0300 Subject: [PATCH 05/45] copy edit Co-authored-by: Max Inden --- 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 cc6439478..16b0bac02 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -73,7 +73,7 @@ deployment of an army of relays for extreme horizontal scaling without excessive bandwidth costs and dedicated hosts. Furthermore, the original decision to conflate circuit initiation and -termination in the same protocol has made it very hard to on provide +termination in the same protocol has made it very hard to provide relay service on demand, decoupled with whether _client_ functionality is supported by the host. From f8ca5d2b3c6e642aa97f5723848d0dc9f66def93 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 5 May 2021 21:05:04 +0300 Subject: [PATCH 06/45] copy edit Co-authored-by: Max Inden --- relay/circuit-v2.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 16b0bac02..23d43d473 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -81,7 +81,9 @@ In order to address this problem, we have splt the protocol into the `hop` and `stop` subprotocols. This allows us to always enable the client-side functionality in a host, while providing the option to later mount the relay service in public hosts, _after_ the -reachability of the host has been determined through AutoNAT. +reachability of the host has been determined through [AutoNAT]. + +[AutoNAT]: https://github.com/libp2p/specs/issues/180 ## The Protocol From 16027bc049314cc835b9978f93063acb791d66ec Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 5 May 2021 21:08:01 +0300 Subject: [PATCH 07/45] copy edit Co-authored-by: Max Inden --- 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 23d43d473..57e7fd096 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -114,7 +114,7 @@ protocol stream and sends a `CONNECT` message to the relay. The relay verifies that it has a reservation and connection for _A_ and opens a `stop` protocol stream to _A_, sending a `CONNECT` message. -Peer _A_ then responds to the relaywith a `STATUS:OK` message, which +Peer _A_ then responds to the relay with a `STATUS:OK` message, which responds to _B_ with a `STATUS:OK` message in the open `hop` stream and then proceeds to bridge the two streams into a relayed connection. The relayed connection flows in the `hop` stream between the From bbb2337005ab39dde28affd12c6a3b40e99b22d6 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 5 May 2021 21:09:36 +0300 Subject: [PATCH 08/45] copy edit Co-authored-by: Max Inden --- relay/circuit-v1.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index cddcf4d3a..f4082cf64 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -1,7 +1,5 @@ # Circuit Relay v0.1.0 -> Circuit Switching for libp2p, also known as TURN or Relay in Networking literature. - | Lifecycle Stage | Maturity | Status | Latest Revision | |-----------------|----------------|--------|-----------------| | 3A | Recommendation | Active | r1, 2018-06-03 | From bfa691853e8f8a749313841d4e0ac4bdc871f656 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 5 May 2021 21:12:42 +0300 Subject: [PATCH 09/45] copy edit Co-authored-by: Max Inden --- 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 57e7fd096..ea8d668df 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -101,7 +101,7 @@ The first part of the interaction is _A_'s reservation of a relay slot in _R_. This is accomplished by opening a connection to _R_ and sending a `RESERVE` message in the `hop` protocol; if the reservation is successful, the relay responds with a `STATUS:OK` message and -provides _A_ with a reservation voucher. +provides _A_ with a reservation voucher. _A_ keeps the connection to _R_ alive for the duration of the reservation, refreshing the reservation as needed. The second part of the interaction is the establishment of a circuit switch connection from _B_ to _A_ through _R_. It is assumed that _B_ From 3c0e757a1712d8f5787968bc323940443695134a Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 10 May 2021 14:53:11 +0300 Subject: [PATCH 10/45] flesh out spec --- relay/circuit-v2.md | 175 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 169 insertions(+), 6 deletions(-) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index ea8d668df..85c6a829c 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -123,15 +123,178 @@ the relay and the connection termination point. ### Hop Protocol -TBD +The Hop protocol governs interaction between clients and the relay; +it uses the protocol ID `/libp2p/circuit/relay/0.2.0/hop`. + +There are two parts of the protocol: +- reservation, by peers that wish to receive relay service +- connection initiation, by peers that wish to connect to a peer through the relay. + +#### Reservation + +In order to make a reservation, a peer opens a connection to the relay and sends a `HopMessage` with +`type = RESERVE`: + +``` +HopMessage { + type = RESERVE +} +``` + +The relay responds with a `HopMessage` of `type = STATUS`, indicating whether the reservation has +been accepted. + +If the reservation is accepted, then the message has the following form: +``` +HopMessage { + type = STATUS + status = OK + reservation = Reservation {...} + limit = Limit {...} +} +``` + +The `reservation` field provides information about the reservation itself; the struct has the following fields: +``` +Reservation { + expire = ... + addrs = [...] + voucher = ... +} +``` + +- the `expire` field contains the expiration time as a UTC UNIX time. The reservation becomes invalid after this time and it's the responsibility of the client to refresh. +- the `addrs` fields contains the all public relay addrs, including the peer ID but not the + trailing `p2p-circuit` part; the client can use this list to constrct its + own `p2p-circuit` relay addrs for advertising by encapsulating + `p2p-circuit/p2p/QmPeer` where `QmPeer` is its peer ID. +- the `voucher` is the binary representation of the reservation voucher -- see [Reservation Vouchers](#reservation-vouchers) for details. + +The `limit` field, if present, provides information about the limits applied by the relay in relayed connection. When omitted, it indicates that the relay does not apply any limits. +The struct has the following fields: +``` +Limit { + duration = ... + data = ... +``` +- the `duration` field indicates the maximum duration of a relayed connection in seconds; if 0, there is no limit applied. +- the `data` field indicates the maximum number of bytes allowed to be transmitted in each direction; if 0 there is no limit applied. + +Note that the reservation remains valid until its expiration, as long +as there is an active connection from the peer to the relay. If the +peer disconnects, the reservation is no longer valid. + +If the reservation is rejected, the relay responds with a `HopMessage` of the form +``` +Reservation { + type = STATUS + status = ... +} +``` +where the `status` field has a value other than `OK`. Common rejection status codes are: +- `PERMISSION_DENIED` if the reservation is rejected because of peer filtering using ACLs. +- `RESERVATION_REFUSED` if the reservation is rejected for some other reason, eg because there are too + many reservations. + +#### Connection Initiation + +In order to initiate a connection to a peer through a relay, the initiator opens a connection and sends a `HopMessage` of `type = CONNECT`: +``` +HopMessage { + type = CONNECT + peer = Peer {...} +} +``` + +The `peer` field contains the peer `ID` of the target peer and optionally the address of that peer for the case of active relay: +``` +Peer { + id = ... + addrs = [...] +``` + +Note that active relay functionality is considered deprecated for security reasons, at least in public relays. +However, the protocol reserves the slot to support the functionality for the rare cases where it is actually desirable to use active relay functionality in a controlled environment. + +If the relay has a reservation (and thus an active connection) from the peer, then it opens the second hop of the connection using the `stop` protocol; the details are not relevant for the `hop` protocol and the only thing that matters is whether it succeeds in opening the relay connection or not. +If the relayed connection is successfully established, then the relay responds with `HopMessage` with `type = STATUS` and `status = OK`: +``` +HopMessage { + type = STATUS + sgtatus = OK + limit = Limit {...} +} +``` +at this point the original `hop` stream becomes the relayed connection. +The `limit` field, if present, communicates to the initiator the +limits applied to the relayed connection with the semantics described +[above](#reservation). + +If the relayed connection cannot be established, then the relay responds with a `HopMessage` of `type = STATUS` and the `status` field having a value other than `OK`. +Common failure status codes are: +- `PERMISSION_DENIED` if the connection is rejected because of peer filtering using ACLs. +- `NO_RESERVATION` if there is no active reservation for the target peer +- `RESOURCE_LIMIT_EXCEEDED` if there are two many relayed connections from the initiator or to the target peer. +- `CONNECTION_FAILED` if the relay failed to terminate the connection to the target peer. + ### Stop Protocol -TBD +The Stop protocol governs connection termination between the relay and the target peer; +it uses the protocol ID `/libp2p/circuit/relay/0.2.0/stop`. + +In order to terminate a relayed connection, the relay opens a stream +using an existing connection to the target peer. If there is no +existing connection, an active relay may attempt to open one using the +initiator supplied address, but as discussed in the previous section +this functionality is generally deprecated. + +The relay sends a `StopMessage` with `type = CONNECT` and the following form: +``` +StopMessage { + type = CONNECT + peer = Peer { ID = ...} + limit = Limit { ...} +} +``` +- the `peer` field contains a `Peer` struct with the peer `ID` of the connection initiator. +- 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`: +``` +StopMessage { + type = STATUS + status = OK +} +``` + +If the target fails to terminate the connection for some reason, then it responds to the relay with a `StopMessage` of `type = STATUS` and the `status` code set to something other than `OK`. +Common failure status codes are: +- `CONNECTION_FAILED` if the target internally failed to create the relayed connection for some reason. ### Reservation Vouchers -TBD +Successful relay slot reservations come with _Reservation Vouchers_. +These are cryptographic certificates signed by the relay that testify that it is willing to provide +service to the reserving peer. +The intention is to eventually require the use of reservation vouchers for dialing relay addresses, +but this is not currently enforced so the vouchers are only advisory. + +The voucher itself is a [Signed Envelope](../RFC/0002-signed-envelopes.md). +The payload of the envelope has the following form, in canonicalized protobuf format: +``` +message Voucher { + required bytes relay = 1; + required bytes peer = 2; + required uint64 expiration = 3; +} +``` +- the `relay` field is the peer ID of the relay. +- the `peer` field is the peer ID of the reserving peer. +- the `expiration` field is the UNIX UTC expiration time for the reservation. + +The wire representation is cononicalized, where elements of the message are written in field id order. + ## Protobuf @@ -172,14 +335,14 @@ message Peer { } message Reservation { - optional int64 expire = 1; // Unix expiration time (UTC) + optional uint64 expire = 1; // Unix expiration time (UTC) repeated bytes addrs = 2; // relay addrs for reserving peer optional bytes voucher = 3; // reservation voucher } message Limit { - optional int32 duration = 1; // seconds - optional int64 data = 2; // bytes + optional uint32 duration = 1; // seconds + optional uint64 data = 2; // bytes } enum Status { From 5efd8e8520a9497ccece59453196c7d09117a0d5 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 10 May 2021 16:02:59 +0200 Subject: [PATCH 11/45] relay/circuit-v2: Replace excalidraw with plantuml For the sake of consistency across the specifications use plantuml to picture circuit relay v2 protocol interaction. --- relay/circuit-v2.md | 42 +++++++++++++++++++++++++++++++++++++++++- relay/circuit-v2.png | Bin 79776 -> 0 bytes relay/circuit-v2.svg | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) delete mode 100644 relay/circuit-v2.png create mode 100644 relay/circuit-v2.svg diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 85c6a829c..8a21c325e 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -95,7 +95,47 @@ Peer _A_ is a private peer, which is not publicly reachable; it utilizes the services of peer _R_ as the relay. Peer _B_ is another peer who wishes to connect to peer _A_ through _R_. -![Circuit v2 Protocol Interaction](circuit-v2.png) +![Circuit v2 Protocol Interaction](circuit-v2.svg) + +
+ Instructions to reproduce diagram + +Use https://plantuml.com/ and the specification below to reproduce the diagram. + +``` +@startuml +participant A +participant R +participant B + +skinparam sequenceMessageAlign center + +== Reservation == + +A -> R: [hop] RESERVE +R -> A: [hop] STATUS:OK + +hnote over A: Reservation timeout approaching. +hnote over A: Refresh. + +A -> R: [hop] RESERVE +R -> A: [hop] STATUS:OK + +hnote over A: ... + +== Circuit Establishment == + +B -> R: [hop] CONNECT to A +R -> A: [stop] CONNECT from B +A -> R: [stop] STATUS:OK +R -> B: [hop] STATUS:OK + +B <-> A: Connection +@enduml +``` + +
+ The first part of the interaction is _A_'s reservation of a relay slot in _R_. This is accomplished by opening a connection to _R_ and diff --git a/relay/circuit-v2.png b/relay/circuit-v2.png deleted file mode 100644 index ec4c2c04612113c3411904062b3dd1eb99d5c27d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79776 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 Oz>l}5FH^EHB<^3lwx4|f diff --git a/relay/circuit-v2.svg b/relay/circuit-v2.svg new file mode 100644 index 000000000..476539781 --- /dev/null +++ b/relay/circuit-v2.svg @@ -0,0 +1,39 @@ +AARRBBReservation[hop] RESERVE[hop] STATUS:OKReservation timeout approaching.Refresh.[hop] RESERVE[hop] STATUS:OK...Circuit Establishment[hop] CONNECT to A[stop] CONNECT from B[stop] STATUS:OK[hop] STATUS:OKConnection From e2cbf5f7795b82cc4af94e35d232cdefa1c4387a Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 11 May 2021 10:51:41 +0300 Subject: [PATCH 12/45] copy edit Co-authored-by: Max Inden --- 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 85c6a829c..d9c220755 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 | r1, 2021-05-05 | +| 1A | DRAFT | Active | r0, 2021-05-05 | Authors: [@vyzo] From e2424141bbf318cfe8bdb40fc3d1dbe0c42f5ec3 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 11 May 2021 10:51:55 +0300 Subject: [PATCH 13/45] copy edit Co-authored-by: Max Inden --- 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 d9c220755..1aaf6f9a3 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -58,7 +58,7 @@ the practicalities of relaying connections. The main problem is that v1 has no mechanism to reserve resources in the relay, which leads to continuoues oversubscription of relays and the -necessity of (often inefective) heuristics for balancing resources. +necessity of (often ineffective) heuristics for balancing resources. In practice, running a relay proved to be an expensive proposition requiring dedicated hosts with significant hardware and bandwidth costs. In addition, there is ongoing work in Hole Punching From 186bf1c3a29c6d7e4b8ea77ef6c96375b097fb90 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 11 May 2021 10:52:13 +0300 Subject: [PATCH 14/45] copy edit Co-authored-by: Max Inden --- 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 1aaf6f9a3..539e816f4 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -77,7 +77,7 @@ termination in the same protocol has made it very hard to provide relay service on demand, decoupled with whether _client_ functionality is supported by the host. -In order to address this problem, we have splt the protocol into the +In order to address this problem, we have split the protocol into the `hop` and `stop` subprotocols. This allows us to always enable the client-side functionality in a host, while providing the option to later mount the relay service in public hosts, _after_ the From 803682e82bc25e88b6c133defd94ce04072bedf3 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 11 May 2021 10:52:29 +0300 Subject: [PATCH 15/45] copy edit Co-authored-by: Max Inden --- 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 539e816f4..682ac3d42 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -164,7 +164,7 @@ Reservation { ``` - the `expire` field contains the expiration time as a UTC UNIX time. The reservation becomes invalid after this time and it's the responsibility of the client to refresh. -- the `addrs` fields contains the all public relay addrs, including the peer ID but not the +- the `addrs` field contains all the public relay addrs, including the peer ID but not the trailing `p2p-circuit` part; the client can use this list to constrct its own `p2p-circuit` relay addrs for advertising by encapsulating `p2p-circuit/p2p/QmPeer` where `QmPeer` is its peer ID. From 8bea5d02b1b9f5ced6d46dcefdacf38d75ce80e1 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 11 May 2021 10:52:42 +0300 Subject: [PATCH 16/45] copy edit Co-authored-by: Max Inden --- 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 682ac3d42..e0d193734 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -165,7 +165,7 @@ Reservation { - the `expire` field contains the expiration time as a UTC UNIX time. The reservation becomes invalid after this time and it's the responsibility of the client to refresh. - the `addrs` field contains all the public relay addrs, including the peer ID but not the - trailing `p2p-circuit` part; the client can use this list to constrct its + trailing `p2p-circuit` part; the client can use this list to construct its own `p2p-circuit` relay addrs for advertising by encapsulating `p2p-circuit/p2p/QmPeer` where `QmPeer` is its peer ID. - the `voucher` is the binary representation of the reservation voucher -- see [Reservation Vouchers](#reservation-vouchers) for details. From 5af61260e58a62db55f699f32885cedc78d9963a Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 11 May 2021 16:37:48 +0300 Subject: [PATCH 17/45] copy edit Co-authored-by: Max Inden --- 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 d204f55b3..b8ac59b75 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -204,7 +204,7 @@ Reservation { ``` - the `expire` field contains the expiration time as a UTC UNIX time. The reservation becomes invalid after this time and it's the responsibility of the client to refresh. -- the `addrs` field contains all the public relay addrs, including the peer ID but not the +- the `addrs` field contains all the public relay addrs, including the peer ID of the relay node but not the trailing `p2p-circuit` part; the client can use this list to construct its own `p2p-circuit` relay addrs for advertising by encapsulating `p2p-circuit/p2p/QmPeer` where `QmPeer` is its peer ID. From 01ea1eac039f66e8cd78a2323c039039ac54bb7e Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 11 May 2021 16:38:11 +0300 Subject: [PATCH 18/45] copy edit Co-authored-by: Max Inden --- 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 b8ac59b75..1dc2d6c15 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -314,7 +314,7 @@ Common failure status codes are: ### Reservation Vouchers -Successful relay slot reservations come with _Reservation Vouchers_. +Successful relay slot reservations should come with _Reservation Vouchers_. These are cryptographic certificates signed by the relay that testify that it is willing to provide service to the reserving peer. The intention is to eventually require the use of reservation vouchers for dialing relay addresses, From af6819b56afd78e2e386a9a3d1be5ef54ae2838c Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:00:41 +0300 Subject: [PATCH 19/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index f4082cf64..2f4ca13a2 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -42,7 +42,7 @@ The circuit relay is a means to establish connectivity between libp2p nodes (e.g Relay is needed in situations where nodes are behind NAT, reverse proxies, firewalls and/or simply don't support the same transports (e.g. go-ipfs vs. browser-ipfs). Even though libp2p has modules for NAT traversal ([go-libp2p-nat](https://github.com/libp2p/go-libp2p-nat)), piercing through NATs isn't always an option. The circuit relay protocol exists to overcome those scenarios. -Unlike a transparent **tunnel**, where a libp2p peer would just proxy a communication stream to a destination (the destination being unaware of the original source), a circuit relay makes the destination aware of the original source and the circuit followed to establish communication between the two. This provides the destination side with full knowledge of the circuit which, if needed, could be rebuilt in the opposite direction. +Unlike a transparent **tunnel**, where a libp2p peer would just proxy a communication stream to a destination (the destination being unaware of the original source), a circuit relay makes the destination aware of the original source and the circuit followed to establish communication between the two. This provides the destination side with full knowledge of the circuit which, if needed, could be rebuilt in the opposite direction. As a word of caution, dialing a peer back on its source addr:port usually won't work. However, most libp2p implementations (e.g. go-libp2p) enable `SO_REUSEPORT` and `SO_REUSEADDR`, and use the listening address as the local address when dialing, to facilitate this connection reversability. Apart from that, this relayed connection behaves just like a regular connection would, but over an existing swarm stream with another peer (instead of e.g. TCP). A node asks a relay node to connect to another node on its behalf. The relay node short-circuits streams between the two nodes, enabling them to reach each other. From f9dda94149228369f7d8362707f6e37d146f19f4 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:01:05 +0300 Subject: [PATCH 20/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index 2f4ca13a2..2a8159606 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -44,7 +44,7 @@ Relay is needed in situations where nodes are behind NAT, reverse proxies, firew Unlike a transparent **tunnel**, where a libp2p peer would just proxy a communication stream to a destination (the destination being unaware of the original source), a circuit relay makes the destination aware of the original source and the circuit followed to establish communication between the two. This provides the destination side with full knowledge of the circuit which, if needed, could be rebuilt in the opposite direction. As a word of caution, dialing a peer back on its source addr:port usually won't work. However, most libp2p implementations (e.g. go-libp2p) enable `SO_REUSEPORT` and `SO_REUSEADDR`, and use the listening address as the local address when dialing, to facilitate this connection reversability. -Apart from that, this relayed connection behaves just like a regular connection would, but over an existing swarm stream with another peer (instead of e.g. TCP). A node asks a relay node to connect to another node on its behalf. The relay node short-circuits streams between the two nodes, enabling them to reach each other. +Apart from that, this relayed connection behaves just like a regular connection would, but over an existing fully formed libp2p stream with another peer (instead of e.g. a raw TCP connection). Think of this as a "virtualized connection". This enables further resource efficiency and maximizes the utility of the underlying connection, as once a NAT'ted peer A has established a connection to a relay R, many peers (B1...Bn) can establish relayed connections to A over that single physical connection. The relay node acts like a circuit switcher over streams between the two nodes, enabling them to reach each other. Relayed connections are end-to-end encrypted just like regular connections. From 53e4fdd03a91f6e60042aefbdae113b7ab202c89 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:01:25 +0300 Subject: [PATCH 21/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index 2a8159606..a594d55cf 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -48,7 +48,7 @@ Apart from that, this relayed connection behaves just like a regular connection Relayed connections are end-to-end encrypted just like regular connections. -The circuit relay is both a tunneled transport and a mounted swarm protocol. The transport is the means of ***establishing*** and ***accepting*** connections, and the swarm protocol is the means to ***relaying*** connections. +The circuit relay consists of both a (tunneled) libp2p transport and a libp2p protocol, mounted on the host. The libp2p transport is the means of ***establishing*** and ***accepting*** connections, and the libp2p protocol is the means to ***relaying*** connections. ``` +-----+ /ip4/.../tcp/.../ws/p2p/QmRelay +-------+ /ip4/.../tcp/.../p2p/QmTwo +-----+ From d5bc92e079622412b3acf43f83c9a047d4cc2cf9 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:01:47 +0300 Subject: [PATCH 22/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index a594d55cf..5f2a17cd9 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -61,7 +61,7 @@ The circuit relay consists of both a (tunneled) libp2p transport and a libp2p pr **Notes for the reader:** -- In this document, we use `/p2p/Qm...` multiaddrs. Libp2p previously used `/ipfs/Qm...` for multiaddrs you'll likely see uses of this notation in the wild. `/ipfs` and `/p2p` multiaddrs are equivalent but `/ipfs` is deprecated `/p2p` should be preferred. +- In this document, we use `/p2p/Qm...` multiaddrs. libp2p previously used `/ipfs/Qm...` for multiaddrs, and you'll likely see uses of this notation in the wild. `/ipfs` and `/p2p` multiaddrs are equivalent but `/ipfs` is deprecated `/p2p` should be preferred. - You may also see `/ipfs/Qm...` used for _file paths_ in IPFS. These are _not_ multiaddrs and this confusion is one of the many motivations for switching to `/p2p/Qm...` multiaddrs. ## Dramatization From 4538e2a83eb0e3696c434f96c2229cdf25065399 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:02:26 +0300 Subject: [PATCH 23/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index 5f2a17cd9..299502346 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -62,7 +62,7 @@ The circuit relay consists of both a (tunneled) libp2p transport and a libp2p pr **Notes for the reader:** - In this document, we use `/p2p/Qm...` multiaddrs. libp2p previously used `/ipfs/Qm...` for multiaddrs, and you'll likely see uses of this notation in the wild. `/ipfs` and `/p2p` multiaddrs are equivalent but `/ipfs` is deprecated `/p2p` should be preferred. -- You may also see `/ipfs/Qm...` used for _file paths_ in IPFS. These are _not_ multiaddrs and this confusion is one of the many motivations for switching to `/p2p/Qm...` multiaddrs. +- You may also see `/ipfs/Qm...` used for _content-addressed pathing_ in IPFS. These are _not_ multiaddrs and this confusion is one of the many motivations for switching to `/p2p/Qm...` multiaddrs. ## Dramatization From b47a1db4925ecc734f6fd3c1432ea5f4a95e8f89 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:07:09 +0300 Subject: [PATCH 24/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index 299502346..33b2d6e4a 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -246,7 +246,7 @@ This is a table of status codes and sample messages that may occur during a rela As explained above, the relay is both a transport (`tpt.Transport`) and a mounted stream protocol (`p2pnet.StreamHandler`). In addition it provides a means of specifying relay nodes to listen/dial through. -Note: the usage of p2pnet.StreamHandler is a little bit off, but it gets the point across. +Note: the usage of `p2pnet.StreamHandler` is a little bit off herein, but it gets the point across. ```go import ( From 50bbeadb3be5af810d76a9ba36bcbdb982e26bbd Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:07:30 +0300 Subject: [PATCH 25/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index 33b2d6e4a..57f7097ec 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -270,7 +270,7 @@ fund NewCircuitRelay(h p2phost.Host) ### Removing existing relay protocol in Go -Note that there is an existing swarm protocol colloqiually called relay. It lives in the go-libp2p package and is named `/ipfs/relay/line/0.1.0`. +Note that there is an existing swarm protocol colloquially called relay. It lives in the go-libp2p package and is named `/ipfs/relay/line/0.1.0`. - Introduced in ipfs/go-ipfs#478 (28-Dec-2014). - No changes except for ipfs/go-ipfs@de50b2156299829c000b8d2df493b4c46e3f24e9. From d74f42c3a745975692582c8dbbcd5f1c5e430ea0 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:08:25 +0300 Subject: [PATCH 26/45] copy edit Co-authored-by: raulk --- relay/circuit-v2.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 1dc2d6c15..e8811264d 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -141,7 +141,9 @@ The first part of the interaction is _A_'s reservation of a relay slot in _R_. This is accomplished by opening a connection to _R_ and sending a `RESERVE` message in the `hop` protocol; if the reservation is successful, the relay responds with a `STATUS:OK` message and -provides _A_ with a reservation voucher. _A_ keeps the connection to _R_ alive for the duration of the reservation, refreshing the reservation as needed. +provides _A_ with a reservation voucher. _A_ keeps the connection to +_R_ alive for the duration of the reservation, refreshing the +reservation as needed. The second part of the interaction is the establishment of a circuit switch connection from _B_ to _A_ through _R_. It is assumed that _B_ From d47247b401b7ccd36893f7f9171d0d2e132aebd4 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:09:05 +0300 Subject: [PATCH 27/45] copy edit Co-authored-by: raulk --- 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 e8811264d..506f603b3 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -151,7 +151,7 @@ has obtained a circuit multiaddr for _A_ of the form `/p2p/QmR/p2p-circuit/p2p/QmA` out of band using some peer discovery service (eg. the DHT or a rendezvous point). -In order to connect to _A_, _B_ then conncts to _R_, opens a `hop` +In order to connect to _A_, _B_ then connects to _R_, opens a `hop` protocol stream and sends a `CONNECT` message to the relay. The relay verifies that it has a reservation and connection for _A_ and opens a `stop` protocol stream to _A_, sending a `CONNECT` message. From 8591edede0b0adf42be9503754d7fa584772c246 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:09:32 +0300 Subject: [PATCH 28/45] copy edit Co-authored-by: raulk --- relay/circuit-v2.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 506f603b3..0e9d2cfdb 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -37,7 +37,8 @@ This is the specification of v2 of the p2p-circuit relay protocol. Compared to the first version of the protocol, there are some significant departures: - The protocol has been split into two subprotocols, `hop` and `stop` - - The `hop` protocol governs the behaviour of relays; it is used for + - The `hop` protocol is client-initiated, and is used when clients send commands + to relays; it is used for reserving resources in the relay and opening a switched connection to a peer through the relay. - The `stop` protocol governs the termination of circuit switched From 90deee6cbc32fd49140d71ce1e002f1dbb5a4227 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:11:19 +0300 Subject: [PATCH 29/45] copy edit Co-authored-by: raulk --- relay/circuit-v2.md | 1 + 1 file changed, 1 insertion(+) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 0e9d2cfdb..7cdaafeb1 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -214,6 +214,7 @@ Reservation { - the `voucher` is the binary representation of the reservation voucher -- see [Reservation Vouchers](#reservation-vouchers) for details. The `limit` field, if present, provides information about the limits applied by the relay in relayed connection. When omitted, it indicates that the relay does not apply any limits. + The struct has the following fields: ``` Limit { From 2b7c32da89442e7f3980976955cd892e9045c612 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:11:40 +0300 Subject: [PATCH 30/45] copy edit Co-authored-by: raulk --- 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 7cdaafeb1..5dbdfdc5e 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -269,7 +269,7 @@ HopMessage { limit = Limit {...} } ``` -at this point the original `hop` stream becomes the relayed connection. +At this point the original `hop` stream becomes the relayed connection. The `limit` field, if present, communicates to the initiator the limits applied to the relayed connection with the semantics described [above](#reservation). From 15788cef8dc76b0a5ca056f238982ae8e17e8643 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:12:47 +0300 Subject: [PATCH 31/45] copy edit Co-authored-by: raulk --- 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 5dbdfdc5e..b69c7d9a7 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -237,7 +237,7 @@ Reservation { ``` where the `status` field has a value other than `OK`. Common rejection status codes are: - `PERMISSION_DENIED` if the reservation is rejected because of peer filtering using ACLs. -- `RESERVATION_REFUSED` if the reservation is rejected for some other reason, eg because there are too +- `RESERVATION_REFUSED` if the reservation is rejected for some other reason, e.g. because there are too many reservations. #### Connection Initiation From ad64f2f87599fa7693611ce6e251b887a4d8e559 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:13:08 +0300 Subject: [PATCH 32/45] copy edit Co-authored-by: raulk --- 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 b69c7d9a7..c6b5d7f6e 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -337,7 +337,7 @@ message Voucher { - the `peer` field is the peer ID of the reserving peer. - the `expiration` field is the UNIX UTC expiration time for the reservation. -The wire representation is cononicalized, where elements of the message are written in field id order. +The wire representation is canonicalized, where elements of the message are written in field id order, with no unknown fields. ## Protobuf From 0bebcc1b1548bbdd837801bd040a61db649af8ad Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:14:26 +0300 Subject: [PATCH 33/45] copy edit Co-authored-by: raulk --- 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 c6b5d7f6e..b9275bc92 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -258,7 +258,7 @@ Peer { ``` Note that active relay functionality is considered deprecated for security reasons, at least in public relays. -However, the protocol reserves the slot to support the functionality for the rare cases where it is actually desirable to use active relay functionality in a controlled environment. +However, the protocol reserves the field to support the functionality for the rare cases where it is actually desirable to use active relay functionality in a controlled environment. If the relay has a reservation (and thus an active connection) from the peer, then it opens the second hop of the connection using the `stop` protocol; the details are not relevant for the `hop` protocol and the only thing that matters is whether it succeeds in opening the relay connection or not. If the relayed connection is successfully established, then the relay responds with `HopMessage` with `type = STATUS` and `status = OK`: From fb477c717cd7512309020b41b9799959e90d096e Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:15:24 +0300 Subject: [PATCH 34/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index 57f7097ec..101b6c6d6 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -40,7 +40,7 @@ and spec status. The circuit relay is a means to establish connectivity between libp2p nodes (e.g. IPFS nodes) that wouldn't otherwise be able to establish a direct connection to each other. -Relay is needed in situations where nodes are behind NAT, reverse proxies, firewalls and/or simply don't support the same transports (e.g. go-ipfs vs. browser-ipfs). Even though libp2p has modules for NAT traversal ([go-libp2p-nat](https://github.com/libp2p/go-libp2p-nat)), piercing through NATs isn't always an option. The circuit relay protocol exists to overcome those scenarios. +Relay is needed in situations where nodes are behind NAT, reverse proxies, firewalls and/or simply don't support the same transports (e.g. go-ipfs vs. browser-ipfs). Even though libp2p has modules for NAT port mapping ([go-libp2p-nat](https://github.com/libp2p/go-libp2p-nat)), this isn't always an option, nor does it always work (e.g. non-residential routers, hotspots, etc.). The circuit relay protocol exists to overcome those scenarios. Unlike a transparent **tunnel**, where a libp2p peer would just proxy a communication stream to a destination (the destination being unaware of the original source), a circuit relay makes the destination aware of the original source and the circuit followed to establish communication between the two. This provides the destination side with full knowledge of the circuit which, if needed, could be rebuilt in the opposite direction. As a word of caution, dialing a peer back on its source addr:port usually won't work. However, most libp2p implementations (e.g. go-libp2p) enable `SO_REUSEPORT` and `SO_REUSEADDR`, and use the listening address as the local address when dialing, to facilitate this connection reversability. From 9cb054f370696d9740c364bb49eb800b44456269 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:16:04 +0300 Subject: [PATCH 35/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index 101b6c6d6..5b99b3297 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -90,7 +90,7 @@ Scene 2: As with all other multiaddrs, encapsulation of different protocols determines which metaphorical tubes to connect to each other. -A `/p2p-circuit` circuit address, is formated following: +A `/p2p-circuit` circuit address, is formatted as following: `[]/p2p-circuit/` From f5c1d62c351e28c9cdd84a483703a55260a42fa2 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:18:00 +0300 Subject: [PATCH 36/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index 5b99b3297..1f4b2540a 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -96,7 +96,7 @@ A `/p2p-circuit` circuit address, is formatted as following: Examples: -- `/p2p-circuit/p2p/QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` - Arbitrary relay node +- `/p2p-circuit/p2p/QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` - Arbitrary relay node that can relay to `QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` (target) - `/ip4/127.0.0.1/tcp/5002/p2p/QmdPU7PfRyKehdrP5A3WqmjyD6bhVpU1mLGKppa2FjGDjZ/p2p-circuit/p2p/QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` - Specific relay node This opens the room for multiple hop relay, where the second relay is encapsulated in the first relay multiaddr, such as: From 962a80d529738c202bb4ed04451dc8e26cc366e9 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:18:27 +0300 Subject: [PATCH 37/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index 1f4b2540a..e686cc8a2 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -97,7 +97,7 @@ A `/p2p-circuit` circuit address, is formatted as following: Examples: - `/p2p-circuit/p2p/QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` - Arbitrary relay node that can relay to `QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` (target) -- `/ip4/127.0.0.1/tcp/5002/p2p/QmdPU7PfRyKehdrP5A3WqmjyD6bhVpU1mLGKppa2FjGDjZ/p2p-circuit/p2p/QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` - Specific relay node +- `/ip4/127.0.0.1/tcp/5002/p2p/QmdPU7PfRyKehdrP5A3WqmjyD6bhVpU1mLGKppa2FjGDjZ/p2p-circuit/p2p/QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` - Specific relay node to relay to `QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` (target) This opens the room for multiple hop relay, where the second relay is encapsulated in the first relay multiaddr, such as: From b1ac56d07994128d4f7ad278fd5ee13e21e8b407 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:19:18 +0300 Subject: [PATCH 38/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index e686cc8a2..ae1e95366 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -99,7 +99,7 @@ Examples: - `/p2p-circuit/p2p/QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` - Arbitrary relay node that can relay to `QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` (target) - `/ip4/127.0.0.1/tcp/5002/p2p/QmdPU7PfRyKehdrP5A3WqmjyD6bhVpU1mLGKppa2FjGDjZ/p2p-circuit/p2p/QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` - Specific relay node to relay to `QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` (target) -This opens the room for multiple hop relay, where the second relay is encapsulated in the first relay multiaddr, such as: +This opens the room for multiple hop relay, where the second relay is encapsulated in the first relay multiaddr, such that one relay relays to the next relay, in a daisy-chain fashion. Example: `<1st relay>/p2p-circuit/<2nd relay>/p2p-circuit/` From d00f2c7e2b8463ba3d312dc349fbff3ede0410b7 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:20:18 +0300 Subject: [PATCH 39/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index ae1e95366..fdbd48742 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -122,7 +122,7 @@ Specify a relay: - `/ip4/../tcp/../p2p/QmRelay/p2p-circuit/p2p/QmTwo` - Dial QmTwo, through QmRelay. - Includes info for connecting to QmRelay. - - The relay node will use peer routing to find an address for QmTwo. + - The relay node will use peer routing to find an address for QmTwo, if not already connected. Double relay: From 1b636646599fbd65ae30e6c94dc9a3bfae65ccdf Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:20:54 +0300 Subject: [PATCH 40/45] copy edit Co-authored-by: raulk --- relay/circuit-v1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/circuit-v1.md b/relay/circuit-v1.md index fdbd48742..9d65a7a16 100644 --- a/relay/circuit-v1.md +++ b/relay/circuit-v1.md @@ -129,7 +129,7 @@ Double relay: - `/p2p-circuit/p2p/QmTwo/p2p-circuit/p2p/QmThree` - Dial QmThree, through a relayed connection to QmTwo. - The relay nodes will use peer routing to find an address for QmTwo and QmThree. - - We'll **not support nested relayed connections for now**, see [Future Work](#future-work) section. + - go-libp2p (reference implementation) **does not support nested relayed connections for now**, see [Future Work](#future-work) section. ## Wire format From 4d520428539f175054da08b5638aa457b6edef9e Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 18 May 2021 17:22:23 +0300 Subject: [PATCH 41/45] copy edit Co-authored-by: raulk --- 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 b9275bc92..4ebaf3d84 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -257,7 +257,7 @@ Peer { addrs = [...] ``` -Note that active relay functionality is considered deprecated for security reasons, at least in public relays. +***Note that active relay functionality is considered deprecated for security reasons, at least in public relays.*** However, the protocol reserves the field to support the functionality for the rare cases where it is actually desirable to use active relay functionality in a controlled environment. If the relay has a reservation (and thus an active connection) from the peer, then it opens the second hop of the connection using the `stop` protocol; the details are not relevant for the `hop` protocol and the only thing that matters is whether it succeeds in opening the relay connection or not. From 62c641bf89e3e2ae90d5fbaa1549d940f61b11c4 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 2 Jun 2021 20:17:14 +0300 Subject: [PATCH 42/45] add wording about relay over relay --- relay/circuit-v2.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 4ebaf3d84..ee3b58604 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -134,7 +134,7 @@ R -> B: [hop] STATUS:OK B <-> A: Connection @enduml ``` - + @@ -142,7 +142,7 @@ The first part of the interaction is _A_'s reservation of a relay slot in _R_. This is accomplished by opening a connection to _R_ and sending a `RESERVE` message in the `hop` protocol; if the reservation is successful, the relay responds with a `STATUS:OK` message and -provides _A_ with a reservation voucher. _A_ keeps the connection to +provides _A_ with a reservation voucher. _A_ keeps the connection to _R_ alive for the duration of the reservation, refreshing the reservation as needed. @@ -240,6 +240,8 @@ where the `status` field has a value other than `OK`. Common rejection status co - `RESERVATION_REFUSED` if the reservation is rejected for some other reason, e.g. because there are too many reservations. +***Note: implementations _should not_ accept reservations over already relayed connections*** + #### Connection Initiation In order to initiate a connection to a peer through a relay, the initiator opens a connection and sends a `HopMessage` of `type = CONNECT`: @@ -281,6 +283,7 @@ Common failure status codes are: - `RESOURCE_LIMIT_EXCEEDED` if there are two many relayed connections from the initiator or to the target peer. - `CONNECTION_FAILED` if the relay failed to terminate the connection to the target peer. +***Note: implementations _should not_ accept connection initiations over already relayed connections*** ### Stop Protocol From e943af6e7d4faeca72e30d34de27b8f4c34e1815 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 8 Jun 2021 15:13:54 +0300 Subject: [PATCH 43/45] copy edit Co-authored-by: raulk --- 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 ee3b58604..170e1b263 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -41,7 +41,7 @@ Compared to the first version of the protocol, there are some significant depart to relays; it is used for reserving resources in the relay and opening a switched connection to a peer through the relay. - - The `stop` protocol governs the termination of circuit switched + - The `stop` protocol governs the endpoints of circuit switched connections. - The concept of resource reservation has been introduced, whereby peers wishing to use a relay explicitly reserve resources and obtain From c3b40e4a89b6719b9c6aeafcbda0702fc3b12f60 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 8 Jun 2021 15:20:12 +0300 Subject: [PATCH 44/45] editorial changes --- relay/circuit-v2.md | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 170e1b263..994e50dbb 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -197,6 +197,19 @@ HopMessage { } ``` +If the reservation is rejected, the relay responds with a `HopMessage` of the form +``` +Reservation { + type = STATUS + status = ... +} +``` +where the `status` field has a value other than `OK`. Common rejection status codes are: +- `PERMISSION_DENIED` if the reservation is rejected because of peer filtering using ACLs. +- `RESERVATION_REFUSED` if the reservation is rejected for some other reason, e.g. because there are too + many reservations. + + The `reservation` field provides information about the reservation itself; the struct has the following fields: ``` Reservation { @@ -228,17 +241,13 @@ Note that the reservation remains valid until its expiration, as long as there is an active connection from the peer to the relay. If the peer disconnects, the reservation is no longer valid. -If the reservation is rejected, the relay responds with a `HopMessage` of the form -``` -Reservation { - type = STATUS - status = ... -} -``` -where the `status` field has a value other than `OK`. Common rejection status codes are: -- `PERMISSION_DENIED` if the reservation is rejected because of peer filtering using ACLs. -- `RESERVATION_REFUSED` if the reservation is rejected for some other reason, e.g. because there are too - many reservations. +The server may drop a connection according to its connection +management policy after all reservations expired. The expectation is +that the server will make a best effort attempt to maintain the +connection for the duration of any reservations and tag it to prevent +accidental termination according to its connection management policy. +If a relay server becomes oerloaded however, it may still drop a +connection with reservations in order to maintain its resource quotas. ***Note: implementations _should not_ accept reservations over already relayed connections*** @@ -315,6 +324,8 @@ StopMessage { } ``` +At this point the original `stop` stream becomes the relayed connection. + If the target fails to terminate the connection for some reason, then it responds to the relay with a `StopMessage` of `type = STATUS` and the `status` code set to something other than `OK`. Common failure status codes are: - `CONNECTION_FAILED` if the target internally failed to create the relayed connection for some reason. From c541d2cd92e2243bfbaca308e56f75d1d4a64552 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 8 Jun 2021 15:21:18 +0300 Subject: [PATCH 45/45] add multicoded and envelope domain for vouchers --- relay/circuit-v2.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/relay/circuit-v2.md b/relay/circuit-v2.md index 994e50dbb..90c7f8510 100644 --- a/relay/circuit-v2.md +++ b/relay/circuit-v2.md @@ -339,6 +339,8 @@ The intention is to eventually require the use of reservation vouchers for diali but this is not currently enforced so the vouchers are only advisory. The voucher itself is a [Signed Envelope](../RFC/0002-signed-envelopes.md). +The envelope domain is `libp2p-relay-rsvp` and uses the multicodec code `0x0302`. + The payload of the envelope has the following form, in canonicalized protobuf format: ``` message Voucher {