libp2p Connectivity

By supporting a wide range of transport protocols, libp2p enables universal connectivity between nodes across different network positions.

A primary goal of the libp2p project is universal connectivity. However, libp2p nodes may run on host machines or in browsers; they may be publically reachable or private. Thus, connectivity across these barriers has been historically out of reach.

Support for new protocols and our own advancements in libp2p helped us overcome these hurdles.

For developers using libp2p to build an application, we hope this site will help you learn more about how libp2p achieves universal connectivity across networks, how it will improve in the future, and how you can get involved!

Types of Connectivity

TCP

TCP was developed in the 1970s, and carried, up to the introduction of QUIC (see next section), the vast majority of traffic on the internet. It was also the first transport that was adopted in libp2p. To learn why it is not supported in browsers, see the Browser → Standalone Node section further below.

Support

Possible

  • go-libp2p
  • rust-libp2p
  • node.js-libp2p

Not Possible

  • Chrome
  • Firefox
  • Safari

Get Involved

This is a very new protocol, and we can use your help.

QUIC

QUIC is a new UDP-based transport protocol. QUIC connections are always encrypted (using TLS 1.3) and provides native stream multiplexing.

Whenever possible, QUIC should be preferred over TCP. Not only is it faster, it also increases the chances of a successful holepunch in case of firewalls (see next section).

However: UDP is blocked in ~5-10% of networks, especially in corporate networks, so running a node exclusively with QUIC is usually not an option.

Support

Possible

  • go-libp2
  • node.js-libp2p

Not Possible

  • Chrome
  • Firefox
  • Safari

Work In Progress

  • rust-libp2p

Hole Punching

TCP and QUIC by themselves are enough for establishing communication between public nodes; however, not all nodes are located in a publicly reachable position. Nodes in home or corporate networks are private and usually separated from the public internet by a NAT or a firewall. Mobile phones are also usually behind a so-called "carrier-grade NAT".

Nodes behind firewalls/NATs can dial any node on the public internet, but they cannot receive incoming connections from outside their local network.

Therefore, we introduced a novel decentralized hole punching mechanism in libp2p to enable connectivity between public and private nodes.

Support

Possible

go-libp2p

rust-libp2p

js-libp2p

Further Reading

DINPS Paper

Circuit v2 Spec

Browser → Standalone Node

Enabling users and app developers to run fully functioning nodes in the browser has been a goal of the libp2p project for some time. Yet seamless connectivity had been out of reach until significant changes in browsers as of late. Here we outline existing ways of establishing connectivity and modern advances such as WebTransport.

Browsers mostly use HTTP(S), making use of an underlying TCP connection for HTTP/1.1 and HTTP/2, or a QUIC connection for HTTP/3. To keep their users secure, they enforce strict rules, like certificate requirements and blocking of cross-origin policies. For security reasons, it's not possible for a browser to dial a raw TCP or QUIC connection from within the browser, and all connections have to meet Secure Context requirements such as messages delivered over TLS.

Traditionally, WebSocket could be used to gain access to the underlying to the underlying TCP connection, after a so-called WebSocket Upgrade. Similarly, WebTransport aims to allow access to the underlying QUIC connection for HTTP/3.

Streams vs. Request-Response

HTTP is a request-response scheme. The client (browser) sends a request, and then waits for a response.

libp2p on the other hand is built on top of a stream abstraction. A stream is more flexible than a request-response scheme: it allows continuous bidirectional communication, both parties can send and receive data at any time.

WebSocket

WebSocket allows “hijacking” of a HTTP/1.1 connection. Later on, it was later also standardized for HTTP/2.

After an HTTP-based "Upgrade request", the browser gains access to the underlying TCP connection.

Support

Possible

  • go-libp2p
  • rust-libp2p
  • Chrome
  • Firefox
  • Safari

Work In Progress

  • node.js-libp2p2

Get Involved

There are solutions to assign certificates to a fleet of nodes, see an example.

Another option would be using IP certificates. They’re quite rare, and not a lot of CAs support generating them, but this might be worth investigating.

WebTransport

While WebSocket allows the browser to “hijack” a TCP connection, WebTransport does the same thing with a QUIC connection.

The protocol is brand-new, in fact, there’s not even an RFC yet: It’s still under development by the IETF WebTransport Working Group and the W3C WebTransport Working Group.

WebTransport is interesting for libp2p, because in contrast with WebSocket, there's a way around the strict certificate requirements, allowing the use in a p2p setting.

Support

Possible

  • Chrome

Not Possible

  • node.js-libp2p

Work In Progress

  • go-libp2p
  • Firefox
  • Safari

Work Not Started

  • rust-libp2p

Get Involved

This is a very new protocol, and we can use your help.

Specification

Go implementation

Browser ⇄ Browser

WebRTC

Usually used for video conferencing, WebRTC is a suite of protocols that allows browsers to connect to servers, and to other browsers, and even punch through NATs.

In addition to enabling audio and video communication (for which packets are sent using an unreliably transport), WebRTC also establishes stream-based communication and exposes reliable streams, called WebRTC Data Channels.

Support

Work In Progress

  • go-libp2
  • rust-libp2
  • js-libp2p

Made with love by Protocol Labs