-
Notifications
You must be signed in to change notification settings - Fork 288
feat(webrtc): add WebRTC (prev. browser-to-browser) spec #497
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
Merged
Merged
Changes from 8 commits
Commits
Show all changes
58 commits
Select commit
Hold shift + click to select a range
58acd82
webrtc/: Initialize browser-to-browser specification
mxinden 35841c3
Document that Noise handshake is not required
mxinden c41007e
Discourage certificate reuse
mxinden 29d166b
Draft signaling protocol
mxinden 5615e2f
Document outstanding role assignment
mxinden cc1a8f1
Change format to one line per sentence
mxinden 78fae26
Document open question on advertising support in Multiaddr
mxinden 4fa8da4
Extend signaling protocol section and process
mxinden 7da6004
Define role distribution among A and B
mxinden badcb1f
Detail STUN section
mxinden d92e673
Document relaying on failure to be out of scope
mxinden 1b86e62
Remove trickle candidate alternative
mxinden 79ee3b0
Document non-browser behind NAT and/or firewall
mxinden e384839
Minor edits
mxinden b5d82c4
Mark proto fields as optional
mxinden 6c139b6
Move mention of existing (deprecated) protocols
mxinden 74c1bc0
Document not using DCUtR
mxinden 619e4e6
Fix STUN section link
mxinden aa62e92
Fix signaling protocol link
mxinden fa79a13
Add uvarint link
mxinden f5ea248
refactor(proto): Rename to SDP_{OFFER,ANSWER} and ICE_CANDIDATE
mxinden 39ed458
Update webrtc/browser-to-browser.md
mxinden 2408db9
Use proto3
mxinden e1e6a0c
Make explicit that A and B might as well be non-browser
mxinden 30b0d53
Document reset on failure
mxinden ebc3d5c
Remove sub heading implied by document title
mxinden 6406947
Document latency of relayed connection
mxinden 5a9e553
Rename signaling protocol to `/webrtc-signaling`
mxinden 2d6ef30
Contrast to DCUtR protocol for two non-browsers
mxinden 4255246
Reword TLS certificate validation sentence
mxinden e99d582
Have A initiate the signaling protocol
mxinden c09392b
Document advertisement via /webrtc-direct
mxinden 0a0a30a
Rename to /webrtc-w3c and /webrtc-w3c-signaling
mxinden 165bd52
Use webtransport instead of plain quic for relay
mxinden ec68ec3
Rename title to WebRTC W3C
mxinden c5b36d2
Introduce naming of w3c in motivation
mxinden e119c1d
Update webrtc/browser-to-browser.md
mxinden 5a48183
Document the origin of `RTCPeerConnection
mxinden 3744342
Rephrase browser being one example of a constrained env
mxinden 4cca1f1
Restructure documents with browser-to-server and w3c subdocuments
mxinden d63368a
Fix indentation
mxinden 25e5774
Introduce private-to-private rename
mxinden e171330
Rename webrtc to webrtc-direct and webrtc-private-to-private to webrtc
mxinden 96529cf
Merge branch 'master' of https://github.com/libp2p/specs into webrtc-…
mxinden 610a3dd
Rename to "Shared concepts"
mxinden 249ff1b
Don't expand on relayed address in example
mxinden 8c4d450
Remove mention of constrained w3c api
mxinden ad2549b
Stress that _B_ creates RTCPeerConnection after incoming stream
mxinden 2b506ab
"Cannot"
mxinden 01f78a7
Require A to support B initiating the signaling process
mxinden fca22b3
Expand on trickle ICE
mxinden 669e0c3
Port for a webrtc connection
mxinden 7a2bf0a
Reword dedicated STUN
mxinden 3425f01
Replace note with not necessary
mxinden 554e3db
Wording on STUN
mxinden 2cd2f19
Fix typo in webrtc/webrtc.md
mxinden 1160982
Update spec headers
mxinden 63b141d
Signal in root readme that there is more than one webrtc
mxinden File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# WebRTC browser-to-browser | ||
|
||
| Lifecycle Stage | Maturity | Status | Latest Revision | | ||
|-----------------|---------------|--------|-----------------| | ||
| 1A | Working Draft | Active | r0, 2022-12-15 | | ||
|
||
## Motivation | ||
|
||
1. **Hole punching in the browser**: Enable two browsers or a browser and a server node to connect even though one or both are behind a NAT / firewall. | ||
|
||
TODO: Doucment use-case where A is a browser and B is a non-browser but behind firewall and/or NAT. | ||
|
||
## Connection Establishment | ||
|
||
### Browser to Browser | ||
|
||
Scenario: Browser _A_ wants to connect to Browser node _B_ with the help of server node _R_. | ||
Both _A_ and _B_ can not listen for incoming connections due to the restriction of the browser platform and being behind a NAT and/or firewall. | ||
|
||
TODO: Define which node on a relayed connection is _A_ and which one is _B_, i.e. which one initiates (offer) and which one responds (answer). | ||
|
||
1. _A_ and _B_ establish a relayed connection through some protocol, e.g. the Circuit Relay v2 protocol. | ||
Note that further steps depend on the relayed connection to be authenticated, i.e. that data send on the relayed connection can be trusted. | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
2. _A_ creates an `RTCPeerConnection`. | ||
See [#STUN] on what STUN servers to configure at creation time. | ||
_A_ creates an SDP offer via `RTCPeerConnection.createOffer()`. | ||
_A_ initiates the signaling protocol to _B_ via the relayed connection from (1), see [#Signaling protocol] and sends the offer to _B_. | ||
|
||
3. _B_ creates an `RTCPeerConnection`. | ||
Again see [#STUN] on what STUN servers to configure at creation time. | ||
_B_ receives _A_'s offer send in (2) via the signaling protocol stream and provides the offer to its `RTCPeerConnection` via `RTCPeerConnection.setRemoteDescription`. | ||
_B_ then creates an answer via `RTCPeerConnection.createAnswer` and sends it to _A_ via the existing signaling protocol stream (see [#signaling protocol]). | ||
|
||
4. _A_ receives _B_'s answer via the signaling protocol stream and sets it locally via `RTCPeerConnection.setRemoteDescription`. | ||
|
||
5. _A_ and _B_ send their local ICE candidates via the existing signaling protocol stream. | ||
Both nodes continuously read from the stream, adding incoming remote candidates via `RTCPeerConnection.addIceCandidate()`. | ||
|
||
6. On successful establishment or failure of the direct connection, _A_ and _B_ close the signaling protocol stream. | ||
TODO: Is there value in retrying on failure? | ||
|
||
7. Messages on `RTCDataChannel`s on the established `RTCPeerConnection` are framed using the message framing mechanism described in [Multiplexing](#multiplexing). | ||
|
||
The above browser-to-browser WebRTC connection establishment replaces the existing [libp2p WebRTC star](https://github.com/libp2p/js-libp2p-webrtc-star) and [libp2p WebRTC direct](https://github.com/libp2p/js-libp2p-webrtc-direct) protocols. | ||
|
||
## STUN | ||
|
||
TODO: Specify | ||
|
||
## Signaling protocol | ||
|
||
The protocol id is `/webrtc-direct`. | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Messages are sent prefixed with the message length in bytes, encoded as an unsigned variable length integer as defined by the [multiformats unsigned-varint spec][uvarint-spec]. | ||
|
||
``` protobuf | ||
syntax = "proto2"; | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
message Message { | ||
// Specifies type in `data` field. | ||
enum Type { | ||
// String of `RTCSessionDescription.sdp` | ||
OFFER = 0; | ||
// String of `RTCSessionDescription.sdp` | ||
ANSWER = 1; | ||
// String of `RTCIceCandidate.toJSON()` | ||
CANDIDATE = 2; | ||
} | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// TODO: Consider removal of `required` for future compatibility. | ||
required Type type = 1; | ||
required string data = 2; | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
``` | ||
|
||
## Open Questions | ||
|
||
- Do we need a mechanism for browsers to advertise support for WebRTC browser-to-browser? | ||
|
||
Say that browser B supports WebRTC browser-to-browser. | ||
B listens via a relay and advertises its relayed address. | ||
A discovers B's relayed address. | ||
At this point A does not know whether B is a browser and thus supports WebRTC browser-to-browser, or whether B is e.g. a laptop potentially supporting TCP and QUIC hole punching via DCUtR but not WebRTC browser-to-browser. | ||
In the latter case, A can not establish a direct connection to B. | ||
|
||
Potential solution would be for B to advertise some protocol after the `/p2p-circuit` within its Multiaddr, e.g. `/ip6/<RELAY_IP>/udp/4001/p2p/<RELAY_PEER_ID>/p2p-circuit/webrtc-direct/p2p/<B_PEER_ID>`. | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
As an alternative, A can discover B's support via the identify protocol on the relayed connection or by optimistically opening a stream using the signaling protocol. | ||
Both of the latter options would on failure happen at the expense of a wasted relayed connection. | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- Instead of using trickle ICE, we could as well wait for the candidate gathering. | ||
See https://github.com/pion/webrtc/blob/c1467e4871c78ee3f463b50d858d13dc6f2874a4/examples/insertable-streams/main.go#L141-L142 as one example. | ||
In the browser, one can wait for the [`icegatheringstatechange` event](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icegatheringstatechange_event). | ||
|
||
## FAQ | ||
|
||
- Why is there no additional Noise handshake needed? | ||
|
||
This specification (browser-to-browser) requires _A_ and _B_ to exchange their SDP offer and answer over an authenticated channel. | ||
Offer and answer contain the TLS certificate fingerprint. | ||
The browser validates the TLS certificate fingerprint through the TLS handshake on the direct connection. | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
In contrast, the browser-to-server specification allows exchange of the server's multiaddr, containing the server's TLS certificate fingerprint, over unauthenticated channels. | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
In other words, the browser-to-server specification does not consider the TLS certificate fingerprint in the server's multiaddr to be trusted. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.