Skip to content
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

feat: add private-to-private docs #319

Merged
merged 7 commits into from
Apr 11, 2023
Merged
Changes from 2 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
80 changes: 74 additions & 6 deletions content/concepts/transports/webrtc.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,85 @@ Authenticity is achieved by succeeding the

<!-- TO ADD DIAGRAM -->

### Coming soon: Browser-to-Browser
### WebRTC W3C (Hole punching to achieve Browser-to-Browser connectivity)

Eventually, libp2p will have support for communication between two
browsers.
Thanks to js-libp2p and rust-libp2p (complied to Wasm), libp2p can run in the browser environment.
p-shahi marked this conversation as resolved.
Show resolved Hide resolved
However, browsers impose certain restrictions on application code (such as libp2p browser nodes).
Applications are sandboxed and face constraints on security and networking.
p-shahi marked this conversation as resolved.
Show resolved Hide resolved
For instance, browsers do not permit direct access to raw network sockets.
Additionally, it's a sure bet that libp2p browser nodes will be behind a NAT/firewall.
Due to these restrictions, browser nodes cannot listen for incoming connections,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They also can't dial TCP and QUIC connections.

and as a result, they cannot communicate with other browser nodes.

The technical specification and initial implementations of WebRTC
Browser-to-Browser connectivity is planned for release in early 2023.
Track the progress [here](https://github.com/libp2p/specs/issues/475).
Thankfully, libp2p solves this problem and enables browser node to browser node connectivity by supporting a transport called WebRTC W3C.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why W3C? All the W3C is does is specify the browser API. We don't call WebTransport "WebTransport W3C".

Suggested change
Thankfully, libp2p solves this problem and enables browser node to browser node connectivity by supporting a transport called WebRTC W3C.
Thankfully, libp2p solves this problem and enables browser node to browser node connectivity by supporting WebRTC.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving this until the convo in specs is resolved.


{{< alert icon="" context="info">}}
Due to the restrictions mentioned above, libp2p browser nodes are private nodes (meaning they cannot be dialed from outside of their local network).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. They're private nodes because people run their browsers in their home / corporate networks, and those networks almost always use NATs. In principle, you could run your browser on a machine that has a public address.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll make this clearer

However, in principle, this use case can be thought of not just as browser-to-browser but private node to private node.
This WebRTC solution enables connectivity between two non browser nodes behind a NAT/firewall as well
p-shahi marked this conversation as resolved.
Show resolved Hide resolved
{{< /alert >}}

#### Transport Internals

The libp2p WebRTC W3C transport is enabled by supporting the [W3C defined](https://w3c.github.io/webrtc-pc/#introduction) `RTCPeerConnection` API.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think mentioning W3C makes a lot of sense here. I will engage on the specs PR. Browser-to-server also uses the W3C-defined API, simply because that's the API that's available in browsers.

This core API enables p2p connectivity and provides methods for establishing connections and transferring streams of data between peers.
Running instances of libp2p that support this transport will have `/webrtc-w3c` in their multiaddr.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, I don't think we should go with this multiaddr, but I'll comment on the PR in the multiaddr repo.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


However, there's more to p2p connections that what `RTCPeerConnection` provides. Crucially, signaling isn't built into the WebRTC API.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It kind of is. The W3C gives you the signaling messages, you just need to figure out how to ship them to the peer yourself.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, might have misrepresented what was described here: "Signaling methods and protocols are not specified by WebRTC. Signaling is not part of the RTCPeerConnection API."

I'll take a note out of this: https://webrtc.org/getting-started/peer-connections#signaling and reword as:
"Crucially, the WebRTC specification doesn't prescribe any single solution for signaling. The peer connection API has a notion of signaling state but not mechanism to share this data with remote peers."

lmk what you think

p-shahi marked this conversation as resolved.
Show resolved Hide resolved
{{< alert icon="" context="info">}}
Signaling is the process of coordinating communication and exchanging metadata about the communication (i.e. initializing, closing, or reporting errors about connections).
{{< /alert >}}

For this transport, libp2p supports its own signaling protocol which has the protocol id: `webrtc-w3c-signaling`.

#### How browser-to-browser connectivity works

<!-- TO ADD DIAGRAM -->

Suppose we have three network entities:

- _Node A_ - a libp2p node running in the browser
- _Node B_ - another browser libp2p node running on a different browser instance
- _Relay R_ - a libp2p relay node

In this connectivity scenario, _A_ wants to connect to _B_.
This roughly works as follows:
p-shahi marked this conversation as resolved.
Show resolved Hide resolved

- _A_ and _B_ are both connected to _R_
- _B_ appends `webrtc-w3c` to its multiaddress and that multiaddress is relayed by _R_.
- _A_ will discover _B_'s multiaddress via _R_
- _A_ sees that _B_ supports `webrtc-w3c` and establishes a relayed connection to _B_
p-shahi marked this conversation as resolved.
Show resolved Hide resolved
- Over the relayed connection, _A_ will:
- Create an _outbound_ `RTCPeerConnection`
p-shahi marked this conversation as resolved.
Show resolved Hide resolved
- Send a SDP offer via the WebRTC API
p-shahi marked this conversation as resolved.
Show resolved Hide resolved
- Initiate the `webrtc-w3c-signaling` signaling protocol via a stream
- On _B_'s end (over the same relayed connection), _B_ will
- Receive _A_'s SDP offer sent via the signaling protocol stream
- Create an _inbound_ `RTCPeerConnection` and provide the offer to its peer connection via the WebRTC API
- Send an answer back to _A_ over the signaling protocol stream
- Once _A_ gets the answer from _B_, _A_ sets the session description with answer
- Via the signaling protocol stream, _A_ and _B_ now both exchange 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))
- After this whole process is done, there can be one of two results:
p-shahi marked this conversation as resolved.
Show resolved Hide resolved
- A successful direct connection is established between _A_ and _B_
- In this case, both browser nodes will close the signaling protocol stream
- The relayed connection is closed
- A failed direction connection
- In this case, the signaling stream is reset
- It's important to note that libp2p does not specify transferring data over the relayed connection if the direct connection fails
p-shahi marked this conversation as resolved.
Show resolved Hide resolved
p-shahi marked this conversation as resolved.
Show resolved Hide resolved

{{< alert icon="" context="info">}}
As mentioned, a browser node is private and behind a NAT/firewall.
It needs to discover it's public IP address and port to send to the remote peer.
To do this, libp2p's `webrtc-w3c` solution depends on STUN servers.
STUN servers are the only way to discover ones own public IP address and port in the browser.
Public STUN servers can be used or you may choose to operate a dedicate STUN server(s) for your libp2p network.
In the above connectivity example, the browser nodes need not use the same STUN server.
{{< /alert >}}

In summary, `webrtc-w3c` makes us of the WebRTC API to establish connectivity.
It also relies on relay nodes and STUN servers to create relay connections to discover a browser node's public IP address and port.
Lastly, it uses the signaling protocol to hole punch across NATs/firewalls and establish a direct connection between two browser nodes.

{{< 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." />}}

## Comparing WebRTC and WebTransport
Expand Down