Skip to content

Add content for QUIC #191

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

Merged
merged 18 commits into from
Oct 7, 2022
Merged
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions content/concepts/transport.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,98 @@ and some places in the codebase still use the "swarm" terminology.
{{% /notice %}}

[definition_switch]: /reference/glossary/#switch

## QUIC

QUIC is a new transport protocol that provides an always-encrypted, stream-multiplexed
connection built on top of UDP. It started as an experiment by Google on Google Chrome
in 2014, and was later standardized by the IETF in
[RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000).

### Key challenges with TCP

1. Head-of-line blocking (HoL blocking): TCP is a single byte stream exposed by the kernel,
so streams layered on top of TCP experience HoL blocking.

{{% notice "info" %}}
HoL blocking occurs when a the head packet holds up the other packets in the transmission
queue.
{{% /notice %}}

2. Ossification: Because TCP is unencrypted, middleboxes can inspect and modify
TCP header fields and may break unexpectedly when they encounter anything they don’t like.

{{% notice "info" %}}
Middleboxes are intermediary networking devices that can perform special functions to
inspect, transform, and even manipulate network traffic. Examples of middleboxes are
firewalls, NATs, proxies, and load balancers.
{{% /notice %}}

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

{{% notice "info" %}}
TCP requires a 3-way handshake to establish a reliable, bidirectional connection as it intends to.
{{% /notice %}}

We need a transport protocol that:

- Understands streams
- Overcomes HOL blocking (Head-of-line blocking)
- Overcomes the latency of connection setup
- Overcomes the ossification risks of TCP

and, ideally, keeps the guarantees of TCP.

A web browser connection typically entails the following (TCP+TLS+HTTP/2):

1. Transport layer: TCP runs on top of the IP layer to provide a reliable
byte stream.
- 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.
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.

<!-- to add diagram -->

### What is QUIC?

QUIC combines the functionality of these layers: it sends UDP packets. Therefore,
it is responsible for loss detection and repair itself. By using encryption,
QUIC avoid middleboxes. The TLS 1.3 handshake is performed in the first flight,
removing the 1-RTT cost of verifying the client’s address. QUIC also exposes multiple
streams, so no stream multiplexer is needed at the application layer. Part of the application
layer is also built directly into QUIC; when you run HTTP on top of QUIC; only a small shim
layer exists that maps
[HTTP semantics](https://httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html)
onto QUIC streams.

QUIC supports the resumption of connections (0-RTT connections), allowing a
client to send application data right away, even before the QUIC handshake has finished.

<!-- to add diagram -->

### QUIC in libp2p

libp2p only supports bidirectional streams and uses TLS 1.3 by default.
The streams in libp2p map cleanly to QUIC streams.

When a connection starts, peers will take their host key and create a self-signed CA
certificate. They then sign an intermediate chain using their self-signed CA and put it
as a certificate chain in the TLS handshake. View the full TLS specification
[here](https://github.com/libp2p/specs/blob/master/tls/tls.md).

{{% notice "note" %}}

To be clear, there is no additional security handshake and stream muxer needed as QUIC
provides all of this by default.

{{% /notice %}}

Following the multiaddress format described earlier, a standard QUIC connection will
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.