Skip to content

Commit 221595c

Browse files
authored
Merge pull request #274 from libp2p/early-mux
feat: early muxer negotiation
2 parents 0236c3d + 1aaf98e commit 221595c

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
title: "Early Multiplexer Negotiation"
3+
description: "Early stream multiplexer negotiation is an optimization in libp2p where peers can negotiate which multiplexer to use during the security protocol handshake, saving one round trip."
4+
weight: 162
5+
---
6+
7+
## Vanilla stream multiplexer selection process
8+
9+
One of libp2p's main guarantees is that no data sent over the wire is unencrypted.
10+
This means that transport protocols, like TCP or WebSocket, that don't support encryption
11+
by default must complete a cryptographic handshake. This process of adding the secure channel
12+
on top of the raw transport is called upgrading the connections and happens via the
13+
[multistream-select protocol](https://github.com/multiformats/multistream-select).
14+
15+
In the unoptimized libp2p connection upgrade process, the security or encryption is negotiated
16+
first. After that is agreed upon, the stream multiplexer is negotiated. Again this only happens
17+
for transports that don't have native stream multiplexing.
18+
19+
A standard connection upgrade process that negotiates the secure channel first and the multiplexer
20+
second
21+
[is shown in a diagram here](https://github.com/libp2p/specs/tree/master/connections#upgrading-connections).
22+
23+
First, the security protocol is negotiated, then this protocol is used to perform a cryptographic
24+
handshake. libp2p currently supports [Noise](../secure-comm/noise) and [TLS 1.3](../secure-comm/tls).
25+
Once the cryptographic handshake completes, multistream-select runs again on top of
26+
the secured connection to negotiate a steam multiplexer, like [yamux](yamux) or [mplex](mplex).
27+
28+
<!-- ADD DIAGRAM -->
29+
30+
## Early muxer negotiation
31+
32+
The libp2p project eliminates an unnecessary round trip in the standard negotiation protocol
33+
for selecting a stream multiplexer. This is achieved by combining the steps of agreeing on a
34+
secure channel and multiplexer. This is called "early" or "inlined" muxer negotiation.
35+
36+
Early muxer negotiation is a feature in libp2p that allows for the simultaneous selection of a
37+
stream multiplexer during the cryptographic handshake of the TLS and Noise security protocols.
38+
This is achieved by sharing a list of supported muxer protocols as a part of the handshake payload.
39+
40+
For example, if a libp2p node supports mplex and yamux, it will advertise both in the list.
41+
This **eliminates an extra round trip**, improving TTFB (time to first byte) in the libp2p handshake.
42+
Currently, this feature is only supported in go-libp2p and for TCP and WebSocket transports that do
43+
not have native encryption or multiplexing.
44+
45+
<!-- ADD DIAGRAM -->
46+
47+
### ALPN extension in TLS
48+
49+
The [Application-Layer Protocol Negotiation (ALPN) extension](https://datatracker.ietf.org/doc/html/rfc7301)
50+
is a feature of TLS that allows for the negotiation of application-layer protocols during the TLS handshake.
51+
This allows the client and server to agree on the application-layer protocol for the rest of the TLS session.
52+
ALPN is typically used to negotiate the application-layer protocol for applications that use TLS, such as HTTP/2
53+
or QUIC. libp2p uses ALPN to negotiate the stream muxer and saves a roundtrip when upgrading a raw connection.
54+
55+
### Extension registry in Noise
56+
57+
Since there's no commonly used extension mechanism in Noise, libp2p defines an extension registry.
58+
We then defined an extension to negotiate the stream multiplexer, that is conceptually the equivalent
59+
of the ALPN extension in TLS.
60+
61+
> The extension registry is modeled after
62+
> [RFC 6066](https://www.rfc-editor.org/rfc/rfc6066) (for TLS) and
63+
> [RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000#section-19.21)
64+
> (for QUIC).
65+
66+
More information is available in the
67+
[Noise specification](https://github.com/libp2p/specs/blob/master/noise/README.md#libp2p-data-in-handshake-messages).
68+
69+
{{< alert icon="💡" context="note" text="See the inclined muxer negotiation <a class=\"text-muted\" href=\"https://github.com/libp2p/specs/blob/master/connections/inlined-muxer-negotiation.md\">specification</a> for more details." />}}

0 commit comments

Comments
 (0)