TCP is a reliable, ordered, full-duplex, congestion-controlled network protocol that powers much of the Internet as we know it today. HTTP/1.1 and HTTP/2 run atop TCP.
RLPx connections
An RLPx connection is established by creating a TCP connection and agreeing on ephemeral key material for further encrypted and authenticated communication. The process of creating those session keys is the ‘handshake’ and is carried out between the ‘initiator’ (the node which opened the TCP connection) and the ‘recipient’ (the node which accepted it).
Consensus TCP fallback
For the TCP fallback transport, the
Libp2p-noise secure channel
handshake with secp256k1 identities will be used for encryption. As specified
in the libp2p specification, clients MUST support the XX handshake pattern.
Stream multiplexing
During connection bootstrapping, libp2p dynamically negotiates a mutually supported multiplexing method to conduct parallel conversations. This applies to transports that are natively incapable of multiplexing (e.g. TCP, WebSockets, WebRTC), and is omitted for capable transports (e.g. QUIC).
Two multiplexers are commonplace in libp2p implementations:
mplex and
yamux. Their
protocol IDs are, respectively: /mplex/6.7.0 and /yamux/1.0.0.
Because the primary QUIC transport multiplexes natively, a stream multiplexer is only required for the TCP fallback transport. Clients that support the TCP transport MUST support mplex and MAY support yamux. If both are supported by the client, yamux MUST take precedence during negotiation. See the Rationale section below for tradeoffs.
Rationale
Yamux is a multiplexer invented by Hashicorp that supports stream-level congestion control. Implementations exist in a limited set of languages, and it’s not a trivial piece to develop.
Conscious of that, the libp2p community conceptualized mplex as a simple, minimal multiplexer for usage with libp2p. It does not support stream-level congestion control and is subject to head-of-line blocking.
Overlay multiplexers are not necessary with QUIC since the protocol provides native multiplexing, but they need to be layered atop TCP, WebSockets, and other transports that lack such support.