Skip to content

Commit b5fe6ec

Browse files
p-shahimarten-seemannmxinden
authored
feat: add private-to-private docs (#319)
Co-authored-by: Marten Seemann <[email protected]> Co-authored-by: Max Inden <[email protected]>
1 parent 8114afa commit b5fe6ec

File tree

1 file changed

+69
-6
lines changed

1 file changed

+69
-6
lines changed

content/concepts/transports/webrtc.md

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,80 @@ Authenticity is achieved by succeeding the
101101

102102
<!-- TO ADD DIAGRAM -->
103103

104-
### Coming soon: Browser-to-Browser
104+
### WebRTC private-to-private
105105

106-
Eventually, libp2p will have support for communication between two
107-
browsers.
106+
Thanks to js-libp2p and rust-libp2p (compiled to Wasm), libp2p can run in the browser environment.
107+
However, browsers impose certain restrictions on application code (such as libp2p browser nodes).
108+
Applications are sandboxed and face constraints on networking.
109+
For instance, browsers do not permit direct access to raw network sockets.
110+
Additionally, it's a sure bet that libp2p browser nodes will be behind a NAT/firewall.
111+
Due to these restrictions, browser nodes cannot listen for incoming connections (nor dial TCP and QUIC connections)
112+
and as a result, they cannot communicate with other browser nodes.
108113

109-
The technical specification and initial implementations of WebRTC
110-
Browser-to-Browser connectivity is planned for release in early 2023.
111-
Track the progress [here](https://github.com/libp2p/specs/issues/475).
114+
Thankfully, libp2p solves this problem and enables browser node to browser node connectivity by supporting a transport called WebRTC private-to-private.
115+
116+
{{< alert icon="" context="info">}}
117+
This WebRTC solution enables connectivity between two privates nodes i.e. nodes behind a NAT / firewall.
118+
People usually run their browsers in home or corporate networks.
119+
These networks are almost always behind a NAT and thus private.
120+
As a result, libp2p browser nodes in such networks are private nodes (meaning they cannot be dialed from outside of their local network).
121+
Thus, this WebRTC private node to private node connectivity enables the vast majority of private browser nodes to connect with one another.
122+
{{< /alert >}}
123+
124+
#### Transport Internals
125+
126+
The libp2p WebRTC private-to-private transport is enabled by supporting the [W3C defined](https://w3c.github.io/webrtc-pc/#introduction) `RTCPeerConnection` API.
127+
This core API enables p2p connectivity and provides methods for establishing connections and transferring streams of data between peers.
128+
Running instances of libp2p that support this transport will have `/webrtc` in their multiaddr.
129+
130+
However, there's more to p2p connections than what `RTCPeerConnection` provides. Crucially, signaling isn't built into the WebRTC API.
131+
{{< alert icon="" context="info">}}
132+
Signaling is the process of coordinating communication and exchanging metadata about the communication (i.e. initializing, closing, or reporting errors about connections).
133+
{{< /alert >}}
134+
135+
For this transport, libp2p supports its own signaling protocol which has the protocol id: `webrtc-signaling`.
136+
137+
#### How private-to-private connectivity works
112138

113139
<!-- TO ADD DIAGRAM -->
114140

141+
Suppose we have three network entities:
142+
143+
- _Node A_ - a libp2p node running in the browser
144+
- _Node B_ - another browser libp2p node running on a different browser instance
145+
- _Relay R_ - a libp2p relay node
146+
147+
In this connectivity scenario, _A_ wants to connect to _B_.
148+
This works as follows:
149+
150+
- _B_ connects to _R_ and makes a relay reservation. It appends `/webrtc` to its relayed multiaddress and advertises it to the network.
151+
- _A_ discovers _B_'s relayed multiaddr, sees it supports private-to-private, and establishes a relayed connection to _B_ via _R_.
152+
- _A_ and _B_ create outbound and inbound [`RTCPeerConnection` objects](https://webrtc.org/getting-started/peer-connections) respectively
153+
- Per their namesake, these objects handle peer connections, define how they're set up, and contain other useful information about the network.
154+
- _A_ initiates the `webrtc-signaling` protocol to _B_ via a stream over the relayed connection
155+
- This signaling stream is used to:
156+
- Exchange SDPs between nodes (an offer from _A_ and an answer from _B_)
157+
- This include exchangning information about the network connection (in WebRTC parlance this is called [exchanging ICE candidates](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Connectivity#ice_candidates))
158+
- The SDP messages are passed to the browsers WebRTC stack, which then tries to establish a direct connection.
159+
- A successful direct connection is established between _A_ and _B_
160+
- In this case, both browser nodes will close the signaling protocol stream
161+
- The relayed connection is closed
162+
- A failed direction connection
163+
- In this case, the signaling stream is reset
164+
165+
{{< alert icon="" context="info">}}
166+
As mentioned, a browser node is private and behind a NAT/firewall.
167+
It needs to discover it's public IP address and port to send to the remote peer.
168+
To do this, libp2p's `webrtc-private-to-private` solution depends on STUN servers.
169+
STUN servers are the only way to discover ones own public IP address and port in the browser.
170+
Public STUN servers can be used or you may choose to operate a dedicate STUN server(s) for your libp2p network.
171+
In the above connectivity example, the browser nodes need not use the same STUN server.
172+
{{< /alert >}}
173+
174+
In summary, `webrtc-private-to-private` establishes a direct connection between two private nodes using the WebRTC API and a signaling protocol.
175+
To do this, this transport relies on relay nodes and STUN servers to create relay connections to discover a browser node's public IP address and port.
176+
In this use case, the signaling protocol is used to hole punch across NATs/firewalls and establish direct connectivity between two private browser nodes.
177+
115178
{{< alert icon="💡" context="note" text="See the WebRTC <a class=\"text-muted\" href=\"https://github.com/libp2p/specs/blob/master/webrtc/README.md\">technical specification</a> for more details." />}}
116179

117180
## Comparing WebRTC and WebTransport

0 commit comments

Comments
 (0)