Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add content for WebTransport #198

Merged
merged 11 commits into from
Oct 12, 2022
94 changes: 92 additions & 2 deletions content/concepts/transport.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ in 2014, and was later standardized by the IETF in
firewalls, NATs, proxies, and load balancers.
{{% /notice %}}

3. Handshake inefficiency: the 3-way handshake is inefficient, as it spends 1-RTT on verifying
3. Handshake inefficiency: the 3-way handshake is inefficient, as it spends 1 RTT on verifying
the client’s address.

{{% notice "info" %}}
Expand All @@ -165,7 +165,7 @@ A web browser connection typically entails the following (TCP+TLS+HTTP/2):
- TCP provides a reliable, bidirectional connection between two end systems.
2. Secure communication layer: A TLS handshake runs on top of TCP to,
establishing an encrypted and authenticated connection.
- Standard TLS over TCP requires 3-RTT. A typical TLS 1.3 handshake takes 1-RTT.
- Standard TLS over TCP requires 3 RTT. A typical TLS 1.3 handshake takes 1 RTT.
3. Application layer: HTTP runs on a secure transport connection to transfer
information and applies a stream muxer to serve multiple requests.
- Application data starts to flow.
Expand Down Expand Up @@ -210,3 +210,93 @@ Following the multiaddress format described earlier, a standard QUIC connection
look like: `/ip4/127.0.0.1/udp/65432/quic/`.

In this section, we offered an overview of QUIC and how QUIC works in libp2p.

## WebTransport

Another transport protocol under development at the IETF is WebTransport.
salmad3 marked this conversation as resolved.
Show resolved Hide resolved
WebTransport is a new specification that uses QUIC to offer an alternative to
WebSocket. Conceptually, it can be considered WebSocket over QUIC.
It allows browsers to establish a stream-multiplexed and bidirectional connection
to servers.
salmad3 marked this conversation as resolved.
Show resolved Hide resolved

While WebSocket provides a bidirectional, full-duplex communication between a
salmad3 marked this conversation as resolved.
Show resolved Hide resolved
browser and a server over a TCP connection, WebTransport exposes the streams of a
QUIC connection to the browser.
salmad3 marked this conversation as resolved.
Show resolved Hide resolved

WebTransports allows us to connect to any libp2p browser node with any server node
because the protocol supports certificate verification via certificate hash, whereas
for WebSocket, it is necessary that the TLS certificate is signed by a trusted CA
(certificate authority).
marten-seemann marked this conversation as resolved.
Show resolved Hide resolved
salmad3 marked this conversation as resolved.
Show resolved Hide resolved

When connecting to a WebSocket server, browsers require the server to present a
TLS certificate signed by a trusted CA (certificate authority). Few nodes have such
a certificate, which is the reason that WebSocket never saw widespread adoption in the
libp2p network. libp2p WebTransport offers a browser API that includes a way to
accept the server's certificate by checking the (SHA-256) hash of the certificate
(using the [`serverCertificateHashes` option](https://www.w3.org/TR/webtransport/#dom-webtransportoptions-servercertificatehashes)), even if the certificate is "just"
a self-signed certificate. This allows us to connect any browser node to any server node,
as long as the browser knows the certificate hash in advance
(see [WebTransport in libp2p](#webtransport-in-libp2p) for how WebTransport addresses
achieve this).

Therefore, WebTransport exhibits all the advantages of QUIC over TCP, that being
faster handshakes, no HoL blocking, and being future-proof.

{{% notice "caution" %}}

There is an experimental WebTransport transport in go-libp2p that is part
of the [v0.23 release](https://github.com/libp2p/go-libp2p/releases/tag/v0.23.0).
The implementation should be used experimentally and is not recommended for production
environments.

js-libp2p also plans to release
[WebTransport support](https://github.com/libp2p/js-libp2p-webtransport) very soon.

There are currently no concrete plans to support WebTransport beyond the Go and JS
implementations.

{{% /notice %}}

For network stacks like libp2p, WebTransport is a pluggable
protocol that fits well with a modular network design.

For a standard WebSocket connection, the roundtrips required are as follows:

- 1 RTT for TCP handshake
- 1 RTT for TLS 1.3 handshake
- 1 RTT for WebSocket upgrade
- 1 RTT for multistream security negotiation (Noise or TLS 1.3)
- 1 RTT for security handshake (Noise or TLS 1.3)
- 1 RTT for multistream muxer negotiation (mplex or yamux)

In total, 6 RTTs.

WebTransport running over QUIC only requires 3 RTTs, as:

- 1 RTT for QUIC handshake
- 1 RTT for WebTransport handshake
- 1 RTT for libp2p handshake; one for multistream and one for authentication
(with a Noise handshake)

In principle, the WebTransport protocol would even allow running the WebTransport
handshake and the Noise handshake in parallel. However, this is currently not
possible in Chrome due to a bug in its WebTransport implementation.
salmad3 marked this conversation as resolved.
Show resolved Hide resolved
salmad3 marked this conversation as resolved.
Show resolved Hide resolved

### WebTransport in libp2p

WebTransport multiaddresses are composed of a QUIC multiaddr, followed
by `/webtransport` and a list of multihashes of the node certificates that the server uses.

For instance, for multiaddress `/ip4/127.0.0.1/udp/123/quic/webtransport/certhash/<hash1>`,
a standard local QUIC connection is defined up until and including `/quic.`
Then, `/webtransport/` runs over QUIC. The self-signed certificate hash that the
server will use to verify the connection.

WebTransport requires an HTTPS URL to establish a WebTransport session -
e.g., `https://docs.libp2p.com/webtransport` and the multiaddresses use an HTTP URL
salmad3 marked this conversation as resolved.
Show resolved Hide resolved
instead. The HTTP endpoint of a libp2p WebTransport servers must be located at
`/.well-known/libp2p-webtransport`.

For instance, the WebTransport URL of a WebTransport server advertising
`/ip4/1.2.3.4/udp/1234/quic/webtransport/` would be
`https://1.2.3.4:1234/.well-known/libp2p-webtransport?type=noise` (the ?type=noise refers to the authentication scheme using Noise).