You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
At the moment, we have three big issues communicating between go-libp2p and a browser:
We can't dial them.
We have to do our crypto in javascript.
If the dApp is running in a secure origin, the go-libp2p node needs a valid TLS certificate for a valid domain.
However, it turns out that WebRTC already has built-in support for both encryption and multiplexing. Even better, the browser APIs allow the user to get the local and remote certificates of a connection (and their fingerprints).
In order to (a) write a libp2p-webrtc specification and ultimately (b) support WebRTC across libp2p implementations, we need to investigate the following open questions:
Where Browser is replaced with the major browsers of today (Chrome, Safari, Edge, Firefox).
Direct connections
Can Browser establish a direct connection to a known public WebRTC node without previously exchanging SDP packets? In other words can one craft the SDP packet on the browser side based on the remote's Multiaddr and then pass it down to the Browser WebRTC stack?
Can Browser establish a direct connection to some other browser without previously exchanging SDP packets?
Securing the connection
While WebRTC offers confidentiality and integrity via TLS, one still needs to authenticate the remote peer. Ideally we would not need to run an additional nested security protocol within an already secured WebRTC connection.
Does Browser allow injecting properties into the certificate before the security handshake and thus carry the libp2p PeerId within the handshake data?
If not, does Browser allow accessing the full certificate or a fingerprint of the certificate for libp2p to then do an authentication handshake on top of the established WebRTC connection exchanging signatures of the fingerprints signed with the libp2p private key?
Lifecycle of a WebRTC connection
How many concurrent WebRTC connection does Browser allow to establish concurrently?
The limitation is in resources given to each browser tab. Previous empirical results demonstrate it is roughly below 10 connections until the main thread (because WebRTC can't be run on Web or Service worker) becomes dragging
This post also has some good benchmarking for video https://bloggeek.me/how-many-users-webrtc-call, which has the complexity of video encoding/decoding, so you should be able to go a bit above using data-channel mode, that said not by much.
How aggressively does Browser close those connections (e.g. when switching tabs)?
What performance can one expect for a single and across many WebRTC connections? What is the impact of the WebRTC stack on the overall performance of the browser / page?
Multiplexing
Can we use WebRTC’s data channels in Browser to multiplex a single connection, or do we need to run an additional multiplexer (e.g. yamux) on top of a WebRTC connection and WebRTC datachannel? In other words, does WebRTC provide all functionality of a libp2p muxer like Yamux (e.g. flow control)?
Reacted by Pierre Krieger, Belma Bruner, Anton Kaliaev and Etch
To respond to the 'Direct Connections' section, I believe it is possible:
The SDP ICE candidate message itself does not contain any connection-specific information, and if you know the public ip:port of the other side you can craft it with just that information.
As a JS in-browser library, to initiate you would create a peer connection, and then pretend like you got a candidate from the other side by passing in such a hand-crafted SDP message. This will cause the browser to generate an answer SDP of it's own address, but also to attempt initiation of a direct webrtc connection to the remote host/port. If the listening peer is waiting for a connection (e.g. has opened a peer connection and made ice candidates), they will accept this connection. as it may come before the relayed ice answer would have even in a normal setup flow.
Reacted by Max Inden, Marcin Rataj, Marten Seemann and Anton Kaliaev
Chrome 97 adds support for WebTransport based on HTTP3 maybe worth considering as well?
From the link, I think we'll be out of luck here.
It has lower latency than WebSockets, and unlike the RTC Data Channel API, which is designed for peer-to-peer messaging, the Web Transport API is specifically designed for client-server messaging.
I think it would still be useful since it will be common for browser nodes connect to server nodes 🤔
Fair enough if the transport is better than websockets than it seems useful. However, the major benefit that WebRTC gives us is the ability to connect to a peer that does not have a domain name and TLS cert, which WebTransport does not help us with.
Reacted by Pierre Krieger, Marcin Rataj, Marten Seemann, Doug A and inverted-capital
To respond to the 'Direct Connections' section, I believe it is possible:
The SDP ICE candidate message itself does not contain any connection-specific information, and if you know the public ip:port of the other side you can craft it with just that information.
Basically, each endpoint must include a hash of its self-signed certificate in the SDP message.
I haven't tried but I presume that browsers don't allow connections that don't use DTLS.
I did try however to give a (DTLS) answer to the browser that does not include a fingerprint attribute, and the browser refuses the answer.
One solution could be to generate the certificate deterministically by using the PeerId as a seed.
Unfortunately, this means that we would need to negotiate another encryption protocol (such as Noise) after establishing the WebRTC connection.
Does Browser allow injecting properties into the certificate before the security handshake and thus carry the libp2p PeerId within the handshake data?
While it is possible to configure the certificates (in the RTCPeerConnection constructor), it's not possible to load them from file. There's a long discussion about that in w3c/webrtc-pc#1853. In short, the reason people opposed an API that would allow importing of a cert / priv key is that would also allow the site to exfiltrate that key and then impersonate the user.
As far as I can tell, certificates have to be generated using the generateCertificate method, which only allows configuration of the key generation algorithm and expiration time.
IdP looks like it might have offered a solution if we had managed to play a few cryptographic tricks and run our identity proxies, but I find it quite hard to find concrete information about this. This is probably due to the fact that this only supported by Firefox (see for example here). There's an unresolved Chrome issue from 2015, so we shouldn't put our hopes on this getting implemented any time soon.
Fair enough if the transport is better than websockets than it seems useful. However, the major benefit that WebRTC gives us is the ability to connect to a peer that does not have a domain name and TLS cert, which WebTransport does not help us with.
https://www.w3.org/TR/webtransport/#certificate-hashes
Bootstrap nodes could hand out self generated certs to peers for communication with browsers. It doesn't fix peers that don't have regular communication with the nodes that can make valid certificates however. There could be an added spec to generate a cert on the fly and hand out to nodes a browser wishes to connect to, but that is more in the scope of adding WebTransport than WebRTC.
I want to highlight the many ongoing efforts around WebRTC in libp2p (that I am aware of). In the ideal case this enables some level of collaboration between the teams. Even if not, I think a general overview is in itself worth it.
@melekes and @tomaka enabling Smoldot running in the browser to communicate to rust-libp2p based nodes without the need for signed TLS certificates.
Activity
[-]WebRTC Transport Proposal[/-][+]Add WebRTC Transport Spec[/+]mxinden commentedon Jan 19, 2022
Moving a closed discussion into the open.
In order to (a) write a libp2p-webrtc specification and ultimately (b) support WebRTC across libp2p implementations, we need to investigate the following open questions:
Where Browser is replaced with the major browsers of today (Chrome, Safari, Edge, Firefox).
Direct connections
Multiaddrand then pass it down to the Browser WebRTC stack?Securing the connection
PeerIdwithin the handshake data?Lifecycle of a WebRTC connection
Multiplexing
willscott commentedon Jan 20, 2022
To respond to the 'Direct Connections' section, I believe it is possible:
The SDP ICE candidate message itself does not contain any connection-specific information, and if you know the public
ip:portof the other side you can craft it with just that information.As a JS in-browser library, to initiate you would create a peer connection, and then pretend like you got a candidate from the other side by passing in such a hand-crafted SDP message. This will cause the browser to generate an answer SDP of it's own address, but also to attempt initiation of a direct webrtc connection to the remote host/port. If the listening peer is waiting for a connection (e.g. has opened a peer connection and made ice candidates), they will accept this connection. as it may come before the relayed ice answer would have even in a normal setup flow.
olanod commentedon Jan 20, 2022
Chrome 97 adds support for
WebTransportbased on HTTP3 maybe worth considering as well?aschmahmann commentedon Jan 20, 2022
From the link, I think we'll be out of luck here.
olanod commentedon Jan 20, 2022
You say it because of the client-server model? I think it would still be useful since it will be common for browser nodes connect to server nodes 🤔
aschmahmann commentedon Jan 20, 2022
Fair enough if the transport is better than websockets than it seems useful. However, the major benefit that WebRTC gives us is the ability to connect to a peer that does not have a domain name and TLS cert, which WebTransport does not help us with.
tomaka commentedon Jan 21, 2022
One tricky point is going to be the
fingerprintattribute.See https://datatracker.ietf.org/doc/html/rfc8122#section-5
Basically, each endpoint must include a hash of its self-signed certificate in the SDP message.
I haven't tried but I presume that browsers don't allow connections that don't use DTLS.
I did try however to give a (DTLS) answer to the browser that does not include a
fingerprintattribute, and the browser refuses the answer.One solution could be to generate the certificate deterministically by using the
PeerIdas a seed.Unfortunately, this means that we would need to negotiate another encryption protocol (such as Noise) after establishing the WebRTC connection.
marten-seemann commentedon Jan 29, 2022
While it is possible to configure the certificates (in the
RTCPeerConnectionconstructor), it's not possible to load them from file. There's a long discussion about that in w3c/webrtc-pc#1853. In short, the reason people opposed an API that would allow importing of a cert / priv key is that would also allow the site to exfiltrate that key and then impersonate the user.As far as I can tell, certificates have to be generated using the generateCertificate method, which only allows configuration of the key generation algorithm and expiration time.
IdP looks like it might have offered a solution if we had managed to play a few cryptographic tricks and run our identity proxies, but I find it quite hard to find concrete information about this. This is probably due to the fact that this only supported by Firefox (see for example here). There's an unresolved Chrome issue from 2015, so we shouldn't put our hopes on this getting implemented any time soon.
mriise commentedon Mar 19, 2022
https://www.w3.org/TR/webtransport/#certificate-hashes
Bootstrap nodes could hand out self generated certs to peers for communication with browsers. It doesn't fix peers that don't have regular communication with the nodes that can make valid certificates however. There could be an added spec to generate a cert on the fly and hand out to nodes a browser wishes to connect to, but that is more in the scope of adding WebTransport than WebRTC.
mxinden commentedon May 10, 2022
WebRTC in libp2p - Ongoing Efforts
I want to highlight the many ongoing efforts around WebRTC in libp2p (that I am aware of). In the ideal case this enables some level of collaboration between the teams. Even if not, I think a general overview is in itself worth it.
mxinden commentedon May 11, 2022
Note that I opened #412, consolidating all our findings thus far as well as listing open questions.
mxinden commentedon Nov 9, 2022
Status Update
mxinden commentedon Apr 26, 2023
Status Update
With both
/webrtc(browser-to-browser) and/webrtc-direct(browser-to-server) specified and implemented, I am closing here as completed 🎉Merge pull request libp2p#220 from libp2p/master-upgrade