mirror of
https://github.com/vacp2p/specs.git
synced 2026-01-06 19:53:50 -05:00
refactor: use rfc6890 special-purpose addresses (#505)
This commit is contained in:
@@ -126,10 +126,10 @@ epoch time as the `seq` value, however they MUST NOT attempt to interpret a
|
||||
seq: 1570215229,
|
||||
addresses: [
|
||||
{
|
||||
multiaddr: "/ip4/1.2.3.4/tcp/42/p2p/QmAlice",
|
||||
multiaddr: "/ip4/192.0.2.0/tcp/42/p2p/QmAlice",
|
||||
},
|
||||
{
|
||||
multiaddr: "/ip4/10.0.1.2/tcp/42/p2p/QmAlice",
|
||||
multiaddr: "/ip4/198.51.100.0/tcp/42/p2p/QmAlice",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -208,7 +208,6 @@ And possibly:
|
||||
- `IsCertified(peer_id, multiaddr) -> Boolean`
|
||||
- has a particular address been self-certified by the given peer?
|
||||
|
||||
|
||||
We'll also need a method that constructs a new `RoutingState` containing our
|
||||
listen addresses and wraps it in a signed envelope. This may belong on the Host
|
||||
instead of the peer store, since it needs access to the private signing key.
|
||||
@@ -273,14 +272,11 @@ filter that could be used to test whether a peer supports a given protocol
|
||||
before interacting with them directly. This could be added as a new field in the
|
||||
`RoutingState` message.
|
||||
|
||||
|
||||
|
||||
[identify-spec]: ../identify/README.md
|
||||
[peer-id-spec]: ../peer-ids/peer-ids.md
|
||||
[mdns-spec]: ../discovery/mdns.md
|
||||
[rendezvous-spec]: ../rendezvous/README.md
|
||||
[pex-proposal]: https://github.com/libp2p/notes/issues/7
|
||||
[autonat]: https://github.com/libp2p/specs/issues/180
|
||||
[envelope-rfc]: ./0002-signed-envelopes.md
|
||||
[eip-778]: https://eips.ethereum.org/EIPS/eip-778
|
||||
[dht-spec]: https://github.com/libp2p/specs/blob/master/kad-dht/README.md
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
# Addressing in libp2p <!-- omit in toc -->
|
||||
>
|
||||
> How network addresses are encoded and used in libp2p
|
||||
|
||||
| Lifecycle Stage | Maturity | Status | Latest Revision |
|
||||
|-----------------|----------------|--------|-----------------|
|
||||
| 3A | Recommendation | Active | r0, 2021-07-22 |
|
||||
|
||||
|
||||
Authors: [@yusefnapora]
|
||||
|
||||
Interest Group: [@mxinden, @Stebalien, @raulk, @marten-seemann, @vyzo]
|
||||
|
||||
[@yusefnapora]: https://github.com/yusefnapora
|
||||
[@mxinden]: https://github.com/mxinden/
|
||||
|
||||
See the [lifecycle document][lifecycle-spec] for context about the maturity level
|
||||
and spec status.
|
||||
@@ -45,7 +44,7 @@ derived from public keys as described in the [peer id spec][peer-id-spec].
|
||||
|
||||
On a particular network, at a specific point in time, a peer may have one or
|
||||
more locations, which can be represented using addresses. For example, I may be
|
||||
reachable via the global IPv4 address of 7.7.7.7 on TCP port 1234.
|
||||
reachable via the global IPv4 address of 198.51.100 on TCP port 1234.
|
||||
|
||||
In a system that only supported TCP/IP or UDP over IP, we could easily write our
|
||||
addresses with the familiar `<ip>:<port>` notation and store them as tuples of
|
||||
@@ -77,16 +76,16 @@ multiaddr](#the-p2p-multiaddr).
|
||||
A multiaddr is a sequence of instructions that can be traversed to some
|
||||
destination.
|
||||
|
||||
For example, the `/ip4/7.7.7.7/tcp/1234` multiaddr starts with `ip4`, which is
|
||||
For example, the `/ip4/198.51.100/tcp/1234` multiaddr starts with `ip4`, which is
|
||||
the lowest-level protocol that requires an address. The `tcp` protocol runs on
|
||||
top of `ip4`, so it comes next.
|
||||
|
||||
The multiaddr above consists of two components, the `/ip4/7.7.7.7` component,
|
||||
The multiaddr above consists of two components, the `/ip4/198.51.100` component,
|
||||
and the `/tcp/1234` component. It's not possible to split either one further;
|
||||
`/ip4` alone is an invalid multiaddr, because the `ip4` protocol was defined to
|
||||
require a 32 bit address. Similarly, `tcp` requires a 16 bit port number.
|
||||
|
||||
Although we referred to `/ip4/7.7.7.7` and `/tcp/1234` as "components" of a
|
||||
Although we referred to `/ip4/198.51.100` and `/tcp/1234` as "components" of a
|
||||
larger TCP/IP address, each is actually a valid multiaddr according to the
|
||||
multiaddr spec. However, not every **syntactically valid multiaddr is a
|
||||
functional description of a process in the network**. As we've seen, even a
|
||||
@@ -121,28 +120,28 @@ TCP/IP streams, or TCP segments themselves encapsulated within IP datagrams.
|
||||
The multiaddr format was designed so that addresses encapsulate each other in
|
||||
the same manner as the protocols that they describe. The result is an address
|
||||
that begins with the "outermost" layer of the network stack and works
|
||||
progressively "inward". For example, in the address `/ip4/7.7.7.7/tcp/80/ws`,
|
||||
progressively "inward". For example, in the address `/ip4/198.51.100/tcp/80/ws`,
|
||||
the outermost protocol is IPv4, which encapsulates TCP streams, which in turn
|
||||
encapsulate WebSockets.
|
||||
|
||||
All multiaddr implementations provide a way to _encapsulate_ two multiaddrs into
|
||||
a composite. For example, `/ip4/7.7.7.7` can encapsulate `/tcp/42` to become
|
||||
`/ip4/7.7.7.7/tcp/42`.
|
||||
a composite. For example, `/ip4/198.51.100` can encapsulate `/tcp/42` to become
|
||||
`/ip4/198.51.100/tcp/42`.
|
||||
|
||||
#### Decapsulation
|
||||
|
||||
Decapsulation takes a composite multiaddr and removes an "inner" multiaddr from
|
||||
it, returning the result.
|
||||
|
||||
For example, if we start with `/ip4/7.7.7.7/tcp/1234/ws` and decapsulate `/ws`,
|
||||
the result is `/ip4/7.7.7.7/tcp/1234`.
|
||||
For example, if we start with `/ip4/198.51.100/tcp/1234/ws` and decapsulate `/ws`,
|
||||
the result is `/ip4/198.51.100/tcp/1234`.
|
||||
|
||||
It's important to note that decapsulation returns the original multiaddr up to
|
||||
the last occurrence of the decapsulated multiaddr. This may remove more than
|
||||
just the decapsulated component itself if there are more protocols encapsulated
|
||||
within it. Using our example above, decapsulating either `/tcp/1234/ws` _or_
|
||||
`/tcp/1234` from `/ip4/7.7.7.7/tcp/1234/ws` will result in `/ip4/7.7.7.7`. This is
|
||||
unsurprising if you consider the utility of the `/ip4/7.7.7.7/ws` address that
|
||||
`/tcp/1234` from `/ip4/198.51.100/tcp/1234/ws` will result in `/ip4/198.51.100`. This is
|
||||
unsurprising if you consider the utility of the `/ip4/198.51.100/ws` address that
|
||||
would result from simply removing the `tcp` component.
|
||||
|
||||
### The p2p multiaddr
|
||||
@@ -167,7 +166,7 @@ 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
|
||||
/ip4/198.51.100/tcp/1234/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N
|
||||
```
|
||||
|
||||
This combination of transport address plus `p2p` address is the format in which
|
||||
@@ -182,7 +181,6 @@ printed as `/ipfs/<peer-id>` instead of `/p2p/<peer-id>` in its string represent
|
||||
depending on the implementation in use. Both names resolve to the same protocol code,
|
||||
and they are equivalent in the binary form.
|
||||
|
||||
|
||||
## Transport multiaddrs
|
||||
|
||||
Because multiaddr is an open and extensible format, it's not possible to
|
||||
@@ -201,7 +199,7 @@ 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.
|
||||
|
||||
This may be an actual address, such as `/ip4/7.7.7.7` or
|
||||
This may be an actual address, such as `/ip4/198.51.100` or
|
||||
`/ip6/fe80::883:a581:fff1:833`, or it could be something that resolves to an IP
|
||||
address, like a domain name.
|
||||
|
||||
@@ -216,7 +214,6 @@ resolvable or "name-based" protocols:
|
||||
| `dns6` | Resolves DNS AAAA records into IPv6 addresses. |
|
||||
| `dnsaddr` | Resolves multiaddrs from a special TXT record. |
|
||||
|
||||
|
||||
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.
|
||||
@@ -227,8 +224,8 @@ runtime will determine what IP version is used.
|
||||
|
||||
When a name-based multiaddr encapsulates another multiaddr, only the name-based
|
||||
component is affected by the lookup process. For example, if `example.com`
|
||||
resolves to `1.2.3.4`, libp2p will resolve the address
|
||||
`/dns4/example.com/tcp/42` to `/ip4/1.2.3.4/tcp/42`.
|
||||
resolves to `192.0.2.0`, libp2p will resolve the address
|
||||
`/dns4/example.com/tcp/42` to `/ip4/192.0.2.0/tcp/42`.
|
||||
|
||||
#### dnsaddr Links
|
||||
|
||||
@@ -244,6 +241,7 @@ For example, resolving `/dnsaddr/libp2p.io` will perform a `TXT` lookup for
|
||||
|
||||
For example, asking the DNS server for the TXT records of one of the bootstrap
|
||||
nodes, `ams-2.bootstrap.libp2p.io`, returns the following records:
|
||||
|
||||
```
|
||||
> dig +short _dnsaddr.ams-2.bootstrap.libp2p.io txt
|
||||
"dnsaddr=/dns4/ams-2.bootstrap.libp2p.io/tcp/443/wss/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb"
|
||||
@@ -291,7 +289,6 @@ where `<ip-multiaddr>` is a multiaddr that resolves to an IP address, as
|
||||
described in the [IP and Name Resolution section](#ip-and-name-resolution).
|
||||
The `<udp-port>` argument must be a 16-bit unsigned integer in network byte order.
|
||||
|
||||
|
||||
### `p2p-circuit` Relay Addresses
|
||||
|
||||
The libp2p [circuit relay protocol][relay-spec] allows a libp2p peer A to
|
||||
@@ -319,7 +316,7 @@ destination peer.
|
||||
A full example would be:
|
||||
|
||||
```
|
||||
/ip4/127.0.0.1/tcp/5002/p2p/QmdPU7PfRyKehdrP5A3WqmjyD6bhVpU1mLGKppa2FjGDjZ/p2p-circuit/p2p/QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt
|
||||
/ip4/192.0.2.0/tcp/5002/p2p/QmdPU7PfRyKehdrP5A3WqmjyD6bhVpU1mLGKppa2FjGDjZ/p2p-circuit/p2p/QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt
|
||||
```
|
||||
|
||||
Here, the destination peer has the peer id
|
||||
@@ -327,7 +324,6 @@ Here, the destination peer has the peer id
|
||||
relay node with peer id `QmdPU7PfRyKehdrP5A3WqmjyD6bhVpU1mLGKppa2FjGDjZ` running
|
||||
on TCP port 5002 of the IPv4 loopback interface.
|
||||
|
||||
|
||||
[peer-id-spec]: ../peer-ids/peer-ids.md
|
||||
[identify-spec]: ../identify/README.md
|
||||
[multiaddr-repo]: https://github.com/multiformats/multiaddr
|
||||
|
||||
@@ -24,26 +24,25 @@ and spec status.
|
||||
## Table of Contents
|
||||
|
||||
- [Multicast DNS (mDNS)](#multicast-dns-mdns)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Overview](#overview)
|
||||
- [Definitions](#definitions)
|
||||
- [Peer Discovery](#peer-discovery)
|
||||
- [Request](#request)
|
||||
- [Response](#response)
|
||||
- [DNS Service Discovery](#dns-service-discovery)
|
||||
- [Meta Query](#meta-query)
|
||||
- [Find All Response](#find-all-response)
|
||||
- [Gotchas](#gotchas)
|
||||
- [Issues](#issues)
|
||||
- [References](#references)
|
||||
- [Worked Examples](#worked-examples)
|
||||
- [Meta Query](#meta-query-1)
|
||||
- [Question](#question)
|
||||
- [Answer](#answer)
|
||||
- [Find All Peers](#find-all-peers)
|
||||
- [Question](#question-1)
|
||||
- [Answer](#answer-1)
|
||||
- [Additional Records](#additional-records)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Overview](#overview)
|
||||
- [Definitions](#definitions)
|
||||
- [Peer Discovery](#peer-discovery)
|
||||
- [Request](#request)
|
||||
- [Response](#response)
|
||||
- [DNS Service Discovery](#dns-service-discovery)
|
||||
- [Meta Query](#meta-query)
|
||||
- [Find All Response](#find-all-response)
|
||||
- [Gotchas](#gotchas)
|
||||
- [Issues](#issues)
|
||||
- [References](#references)
|
||||
- [Meta Query](#meta-query-1)
|
||||
- [Question](#question)
|
||||
- [Answer](#answer)
|
||||
- [Find All Peers](#find-all-peers)
|
||||
- [Question](#question-1)
|
||||
- [Answer](#answer-1)
|
||||
- [Additional Records](#additional-records)
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -165,5 +164,5 @@ _p2p._udp.local IN PTR `<peer-name>`._p2p._udp.local
|
||||
|
||||
#### Additional Records
|
||||
|
||||
- `<peer-name>`._p2p._udp.local IN TXT dnsaddr=/ip6/fe80::7573:b0a8:46b0:bfea/tcp/4001/p2p/`id`
|
||||
- `<peer-name>`._p2p._udp.local IN TXT dnsaddr=/ip4/192.168.178.21/tcp/4001/p2p/`id`
|
||||
- `<peer-name>`._p2p._udp.local IN TXT dnsaddr=/ip6/2001:DB8::7573:b0a8:46b0:bfea/tcp/4001/p2p/`id`
|
||||
- `<peer-name>`._p2p._udp.local IN TXT dnsaddr=/ip4/192.0.2.0/tcp/4001/p2p/`id`
|
||||
|
||||
@@ -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 to relay to `QmVT6GYwjeeAF5TR485Yc58S3xRF5EFsZ5YAF4VcP3URHt` (target)
|
||||
- `/ip4/192.0.2.0/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 that one relay relays to the next relay, in a daisy-chain fashion. Example:
|
||||
|
||||
|
||||
@@ -23,29 +23,32 @@ and spec status.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Use Cases](#use-cases)
|
||||
- [Replacing ws-star-rendezvous](#replacing-ws-star-rendezvous)
|
||||
- [Rendezvous and pubsub](#rendezvous-and-pubsub)
|
||||
- [The Protocol](#the-protocol)
|
||||
- [Registration Lifetime](#registration-lifetime)
|
||||
- [Interaction](#interaction)
|
||||
- [Spam mitigation](#spam-mitigation)
|
||||
- [Protobuf](#protobuf)
|
||||
- [Recommendations for Rendezvous Points configurations](#recommendations-for-rendezvous-points-configurations)
|
||||
- [Rendezvous Protocol](#rendezvous-protocol)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Overview](#overview)
|
||||
- [Use Cases](#use-cases)
|
||||
- [Replacing ws-star-rendezvous](#replacing-ws-star-rendezvous)
|
||||
- [Rendezvous and pubsub](#rendezvous-and-pubsub)
|
||||
- [The Protocol](#the-protocol)
|
||||
- [Registration Lifetime](#registration-lifetime)
|
||||
- [Interaction](#interaction)
|
||||
- [Spam mitigation](#spam-mitigation)
|
||||
- [Protobuf](#protobuf)
|
||||
- [Recommendations for Rendezvous Points configurations](#recommendations-for-rendezvous-points-configurations)
|
||||
|
||||
## Overview
|
||||
|
||||
The protocol described in this specification is intended to provide a
|
||||
lightweight mechanism for generalized peer discovery. It can be used for
|
||||
purposes like bootstrapping, real-time peer discovery, and application-specific
|
||||
routing. Any node implementing the rendezvous protocol can act as a rendezvous
|
||||
lightweight mechanism for generalized peer discovery. It can be used for
|
||||
purposes like bootstrapping, real-time peer discovery, and application-specific
|
||||
routing. Any node implementing the rendezvous protocol can act as a rendezvous
|
||||
point, allowing the discovery of relevant peers in a decentralized manner.
|
||||
|
||||
## Use Cases
|
||||
|
||||
Depending on the application, the protocol could be used in the
|
||||
following context:
|
||||
|
||||
- During bootstrap, a node can use known rendezvous points to discover
|
||||
peers that provide critical services. For instance, rendezvous can
|
||||
be used to discover circuit relays for connectivity-restricted
|
||||
@@ -66,7 +69,7 @@ and a fleet of p2p-circuit relays. Real-time applications will
|
||||
utilize rendezvous both for bootstrap and in a real-time setting.
|
||||
During bootstrap, rendezvous will be used to discover circuit relays
|
||||
that provide connectivity for browser nodes. Subsequently, rendezvous
|
||||
will be utilized throughout the application's lifetime for real-time peer
|
||||
will be utilized throughout the application's lifetime for real-time peer
|
||||
discovery by registering and polling rendezvous points.
|
||||
This allows us to replace a fragile centralized component with a
|
||||
horizontally scalable ensemble of daemons.
|
||||
@@ -74,11 +77,11 @@ horizontally scalable ensemble of daemons.
|
||||
### Rendezvous and pubsub
|
||||
|
||||
Rendezvous can be naturally combined with pubsub for effective
|
||||
real-time discovery. At a basic level, rendezvous can
|
||||
real-time discovery. At a basic level, rendezvous can
|
||||
bootstrap pubsub: nodes can utilize rendezvous to discover
|
||||
their peers within a topic. Alternatively, pubsub can also be used to build
|
||||
rendezvous services. In this scenario, several rendezvous points can federate
|
||||
using pubsub for internal real-time distribution while still providing a simple
|
||||
their peers within a topic. Alternatively, pubsub can also be used to build
|
||||
rendezvous services. In this scenario, several rendezvous points can federate
|
||||
using pubsub for internal real-time distribution while still providing a simple
|
||||
interface to clients.
|
||||
|
||||
## The Protocol
|
||||
@@ -88,11 +91,11 @@ discovery within application-specific namespaces. Peers connect to the
|
||||
rendezvous point and register their presence in one or more
|
||||
namespaces. It is not allowed to register arbitrary peers in a
|
||||
namespace; only the peer initiating the registration can register
|
||||
itself. The register message contains a serialized
|
||||
itself. The register message contains a serialized
|
||||
[signed peer record](https://github.com/libp2p/specs/blob/377f05a/RFC/0002-signed-envelopes.md)
|
||||
created by the peer, which others can validate.
|
||||
|
||||
Other nodes can discover peers registered with the rendezvous point by
|
||||
Other nodes can discover peers registered with the rendezvous point by
|
||||
querying the rendezvous point. The query specifies the
|
||||
namespace for limiting application scope and, optionally, a maximum
|
||||
number of peers to return. The namespace can be omitted in the query,
|
||||
@@ -101,7 +104,7 @@ which asks for all peers registered to the rendezvous point.
|
||||
The query can also include a cookie obtained from the response to a
|
||||
previous query, such that only registrations that weren't included in
|
||||
the previous response will be returned. This lets peers
|
||||
progressively refresh their network view without overhead, simplifying
|
||||
progressively refresh their network view without overhead, simplifying
|
||||
real-time discovery. It also allows for the pagination
|
||||
of query responses so peers can manage large numbers of peer registrations.
|
||||
|
||||
@@ -110,11 +113,11 @@ The rendezvous protocol runs over libp2p streams using the protocol id `/rendezv
|
||||
### Registration Lifetime
|
||||
|
||||
An optional TTL parameter in
|
||||
the `REGISTER` message controls the registration lifetime. If a TTL is
|
||||
specified, then the registration persists until the TTL expires. If no
|
||||
TTL was set, then a default of 2hrs is implied. There may be a rendezvous
|
||||
point-specific upper bound on TTL, with a maximum value of 72hrs. If the
|
||||
TTL of a registration is inadmissible, the rendezvous point may reject
|
||||
the `REGISTER` message controls the registration lifetime. If a TTL is
|
||||
specified, then the registration persists until the TTL expires. If no
|
||||
TTL was set, then a default of 2hrs is implied. There may be a rendezvous
|
||||
point-specific upper bound on TTL, with a maximum value of 72hrs. If the
|
||||
TTL of a registration is inadmissible, the rendezvous point may reject
|
||||
the registration with an `E_INVALID_TTL` status.
|
||||
|
||||
Peers can refresh their registrations at any time with a new
|
||||
@@ -140,13 +143,15 @@ R -> B: {OK}
|
||||
```
|
||||
|
||||
Client `C` connects and registers for namespace `another-app`:
|
||||
|
||||
```
|
||||
C -> R: REGISTER{another-app, {QmC, AddrC}}
|
||||
R -> C: {OK}
|
||||
```
|
||||
|
||||
Another client, `D` can discover peers in `my-app` by sending a `DISCOVER` message; the
|
||||
rendezvous point responds with the list of current peer registrations and a cookie.
|
||||
Another client `D` can discover peers in `my-app` by sending a `DISCOVER` message; the
|
||||
rendezvous point responds with the list of current peer reigstrations and a cookie.
|
||||
|
||||
```
|
||||
D -> R: DISCOVER{ns: my-app}
|
||||
R -> D: {[REGISTER{my-app, {QmA, Addr}}
|
||||
@@ -156,6 +161,7 @@ R -> D: {[REGISTER{my-app, {QmA, Addr}}
|
||||
|
||||
If `D` wants to discover all peers registered with `R`, then it can omit the namespace
|
||||
in the query:
|
||||
|
||||
```
|
||||
D -> R: DISCOVER{}
|
||||
R -> D: {[REGISTER{my-app, {QmA, Addr}}
|
||||
@@ -170,6 +176,7 @@ new registrations.
|
||||
|
||||
So here we consider a new client `E` registering after the first query,
|
||||
and a subsequent query that discovers just that peer by including the cookie:
|
||||
|
||||
```
|
||||
E -> R: REGISTER{my-app, {QmE, AddrE}}
|
||||
R -> E: {OK}
|
||||
@@ -185,7 +192,7 @@ adversarial actors who generate a large number of peer identities and
|
||||
register under a namespace of interest (e.g., the relay namespace).
|
||||
|
||||
It is TBD how exactly the protocol will mitigate such attacks.
|
||||
See https://github.com/libp2p/specs/issues/341 for a discussion on this
|
||||
See <https://github.com/libp2p/specs/issues/341> for a discussion on this
|
||||
topic.
|
||||
|
||||
### Protobuf
|
||||
|
||||
@@ -49,7 +49,8 @@ WebRTC multiaddresses are composed of an IP and UDP address component, followed
|
||||
by `/webrtc` and a multihash of the certificate that the node uses.
|
||||
|
||||
Examples:
|
||||
- `/ip4/1.2.3.4/udp/1234/webrtc/certhash/<hash>/p2p/<peer-id>`
|
||||
|
||||
- `/ip4/192.0.2.0/udp/1234/webrtc/certhash/<hash>/p2p/<peer-id>`
|
||||
- `/ip6/fe80::1ff:fe23:4567:890a/udp/1234/webrtc/certhash/<hash>/p2p/<peer-id>`
|
||||
|
||||
The TLS certificate fingerprint in `/certhash` is a
|
||||
@@ -118,7 +119,7 @@ reachable but _B_ does not have a TLS certificate trusted by _A_.
|
||||
Note that this process, oftentimes referred to as "SDP munging" is disallowed
|
||||
by the specification, but not enforced across the major browsers (Safari,
|
||||
Firefox, Chrome) due to use-cases in the wild. See also
|
||||
https://bugs.chromium.org/p/chromium/issues/detail?id=823036
|
||||
<https://bugs.chromium.org/p/chromium/issues/detail?id=823036>
|
||||
|
||||
6. Once _A_ sets the SDP offer and answer, it will start sending STUN requests
|
||||
to _B_. _B_ reads the _ufrag_ from the incoming STUN request's _username_
|
||||
@@ -149,7 +150,7 @@ reachable but _B_ does not have a TLS certificate trusted by _A_.
|
||||
sending many STUN messages with different ufrags using different UDP source
|
||||
ports, forcing _B_ to allocate a new peer connection for each. _B_ SHOULD
|
||||
have a rate limiting mechanism in place as a defense measure. See also
|
||||
https://datatracker.ietf.org/doc/html/rfc5389#section-16.1.2.
|
||||
<https://datatracker.ietf.org/doc/html/rfc5389#section-16.1.2>.
|
||||
|
||||
7. _A_ and _B_ execute the DTLS handshake as part of the standard WebRTC
|
||||
connection establishment.
|
||||
@@ -340,7 +341,7 @@ After [Connection Establishment](#connection-establishment):
|
||||
capabilities via datachannels. See [Multiplexing](#multiplexing).
|
||||
|
||||
Note: WebRTC supports different hash functions to hash the TLS certificate (see
|
||||
https://datatracker.ietf.org/doc/html/rfc8122#section-5). The hash function used
|
||||
<https://datatracker.ietf.org/doc/html/rfc8122#section-5>). The hash function used
|
||||
in WebRTC and the hash function used in the multiaddr `/certhash` component MUST
|
||||
be the same. On mismatch the final Noise handshake MUST fail.
|
||||
|
||||
@@ -365,14 +366,14 @@ accept streams before completion of the handshake.
|
||||
## Previous, ongoing and related work
|
||||
|
||||
- Completed implementations of this specification:
|
||||
- https://github.com/libp2p/rust-libp2p/pull/2622
|
||||
- <https://github.com/libp2p/rust-libp2p/pull/2622>
|
||||
- Work in progress implementations of this specification:
|
||||
- https://github.com/little-bear-labs/js-libp2p-webrtc/pull/4
|
||||
- https://github.com/libp2p/go-libp2p/pull/1655
|
||||
- <https://github.com/little-bear-labs/js-libp2p-webrtc/pull/4>
|
||||
- <https://github.com/libp2p/go-libp2p/pull/1655>
|
||||
- Past related work:
|
||||
- Proof of concept for the server side (native) and the client side (Rust in
|
||||
WASM): https://github.com/wngr/libp2p-webrtc
|
||||
- WebRTC using STUN and TURN: https://github.com/libp2p/js-libp2p-webrtc-star
|
||||
WASM): <https://github.com/wngr/libp2p-webrtc>
|
||||
- WebRTC using STUN and TURN: <https://github.com/libp2p/js-libp2p-webrtc-star>
|
||||
|
||||
## Test vectors
|
||||
|
||||
@@ -479,11 +480,11 @@ prologue = "6c69627032702d7765627274632d6e6f6973653a12203e79af40d6059617a0d83b83
|
||||
> an endpoint MUST limit the amount of data it sends to the unvalidated
|
||||
> address to three times the amount of data received from that address.
|
||||
|
||||
https://datatracker.ietf.org/doc/html/rfc9000#section-8
|
||||
<https://datatracker.ietf.org/doc/html/rfc9000#section-8>
|
||||
|
||||
This is the case for STUN response messages which are only slight larger than
|
||||
the request messages. See also
|
||||
https://datatracker.ietf.org/doc/html/rfc5389#section-16.1.2.
|
||||
<https://datatracker.ietf.org/doc/html/rfc5389#section-16.1.2>.
|
||||
|
||||
- _Why does B start the Noise handshake and not A?_
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ Interest Group: [@MarcoPolo], [@mxinden], [@elenaf9]
|
||||
[@mxinden]: https://github.com/mxinden
|
||||
[@elenaf9]: https://github.com/elenaf9
|
||||
|
||||
|
||||
See the [lifecycle document](../00-framework-01-spec-lifecycle.md) for context about maturity level
|
||||
and spec status.
|
||||
|
||||
@@ -29,7 +28,8 @@ The most exciting feature for libp2p (other than the numerous performance benefi
|
||||
|
||||
## Certificates
|
||||
|
||||
According to the [w3c WebTransport specification](https://www.w3.org/TR/webtransport/), there are two ways for a browser to validate the certificate used on a WebTransport connection.
|
||||
According to the [w3c WebTransport specification](https://www.w3.org/TR/webtransport/), there are two ways for a browser to validate the certificate used on a WebTransport connection.
|
||||
|
||||
1. by verifying the chain of trust of the certificate. This means that the certificate has to be signed by a CA (Certificate Authority) that the browser trusts. This is how browsers verify certificates when establishing a regular HTTPS connection.
|
||||
2. by verifying that the cryptographic hash of the certificate matches a specific value, using the [`serverCertificateHashes`](https://www.w3.org/TR/webtransport/#dom-webtransportoptions-servercertificatehashes) option.
|
||||
|
||||
@@ -46,8 +46,9 @@ Once the first certificate has expired, the node starts using the already genera
|
||||
|
||||
WebTransport multiaddresses are composed of a QUIC multiaddress, followed by `/webtransport` and a list of multihashes of the certificates that the server uses (if not using a CA-signed certificate).
|
||||
Examples:
|
||||
* `/ip4/1.2.3.4/udp/443/quic/webtransport` (when using a CA-signed certificates)
|
||||
* `/ip4/1.2.3.4/udp/1234/quic/webtransport/certhash/<hash1>` (when using single self-signed certificates)
|
||||
|
||||
* `/ip4/192.0.2.0/udp/443/quic/webtransport` (when using a CA-signed certificates)
|
||||
* `/ip4/192.0.2.0/udp/1234/quic/webtransport/certhash/<hash1>` (when using single self-signed certificates)
|
||||
* `/ip6/fe80::1ff:fe23:4567:890a/udp/1234/quic/webtransport/certhash/<hash1>/certhash/<hash2>/certhash/<hash3>` (when using single self-signed certificates)
|
||||
|
||||
## WebTransport HTTP endpoint
|
||||
@@ -56,12 +57,12 @@ WebTransport needs a HTTPS URL to establish a WebTransport session, e.g. `https:
|
||||
|
||||
To allow future evolution of the way we run the libp2p handshake over WebTransport, we use a URL parameter. The handshake described in this document MUST be signaled by setting the `type` URL parameter to `noise`.
|
||||
|
||||
Example: The WebTransport URL of a WebTransport server advertising `/ip4/1.2.3.4/udp/1443/quic/webtransport/` would be `https://1.2.3.4:1443/.well-known/libp2p-webtransport?type=noise`.
|
||||
Example: The WebTransport URL of a WebTransport server advertising `/ip4/192.0.2.0/udp/1443/quic/webtransport/` would be `https://192.0.2.0:1443/.well-known/libp2p-webtransport?type=noise`.
|
||||
|
||||
## Security Handshake
|
||||
|
||||
Unfortunately, the self-signed certificate doesn't allow the nodes to authenticate each others' peer IDs. It is therefore necessary to run an additional libp2p handshake on a newly established WebTransport connection.
|
||||
The first stream that the client opens on a new WebTransport session is used to perform a libp2p handshake using Noise (https://github.com/libp2p/specs/tree/master/noise). The client SHOULD start the handshake right after sending the CONNECT request, without waiting for the server's response.
|
||||
The first stream that the client opens on a new WebTransport session is used to perform a libp2p handshake using Noise (<https://github.com/libp2p/specs/tree/master/noise>). The client SHOULD start the handshake right after sending the CONNECT request, without waiting for the server's response.
|
||||
|
||||
In order to verify end-to-end encryption of the connection, the peers need to establish that no MITM intercepted the connection. To do so, the server MUST include the certificate hash of the currently used certificate as well as the certificate hashes of all future certificates it has already advertised to the network in the `webtransport_certhashes` Noise extension (see Noise Extension section of the [Noise spec](/noise/README.md)). The hash of recently used, but expired certificates SHOULD also be included.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user