refactor: use rfc6890 special-purpose addresses (#505)

This commit is contained in:
Danny Salman
2023-01-23 09:02:20 -05:00
committed by GitHub
parent 76ccc4fabb
commit 1ec40b3f9c
7 changed files with 97 additions and 97 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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`

View File

@@ -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:

View File

@@ -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

View File

@@ -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?_

View File

@@ -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.