Skip to content

WebRTC datachannels #3250

@johnny-smitherson

Description

@johnny-smitherson

After #2799 there is no remaining ticket on webrtc. After n0-computer/iroh-examples#113 I would like to publish our findings

Motivation

WebRTC seems to be the only protocol to handle direct browser-to-browser networking, with wide adoption and support. Implementing it would remove the restriction that all browser traffic flow through iroh relays.

We have experimented with some real-world network configurations (went to people's offices and houses) and have found WebRTC works in the following circumstances:

  • one peer is on open internet, no NAT, no firewall, no LAN (e.g. a VPS) -- success 100%
  • peers are on same LAN, intranet, VPN, hotspot, host, browser: success 100%
  • peers are on different residential/office ISP line: success rate 20%
  • peers are on mobile network / cgnat / corporate firewall / "guest" type wifi: success 0%

So its actual use-cases would be closest to the use-cases of the of the "local network discovery with mDNS" feature - in that:

  • it successfully detects and connects with all hosts that would have shown up on mDNS
  • it works on browsers as well as native binaries
  • it always works between all browser tabs on same pc/phone, including from different browsers
  • it doesn't really work outside of the LAN space

We think it's interesting for Iroh to have this feature for the following use-cases:

  • airdrop-style LAN file transfers, using only browsers instead of mDNS
  • apps that combine a native client (e.g. video game client / files server) with a browser client (e.g. chatroom / files search webUI) on the same host
  • real-time web app where user can open 10+ tabs in their browser
    • e.g. google-docs style app where each tab has a document, or chat app where each tab has a chat room
    • with WebRTC all tabs can automatically cross-connect without relay traffic
    • when using iroh-gossip, the local peers should naturally cluster together, greatly reducing relay traffic overall

Disadvantages

  • speed
    • ICE takes a few seconds for every peer
  • complexity
    • each peer connection would be capable of "upgrading" to webrtc datachannel
    • WebRTC Offer/Answer messages would go over normal iroh connection, until a working datachannel is found
    • handle connection failures/restarts, datachannel backpressure, etc.
    • different native (webrtc.rs) & wasm (wasm-bindgen) implementations required
    • different reliable & unreliable datachannel configurations
  • size Browser-to-Browser WebRTC connection demo using matchbox-socket iroh-examples#113 (comment)

    by shipping a whole WebRTC implementation in native nodes, we'll blow up code size for all users of iroh a little too much

    • yes, bringing in webrtc.rs on hosts grows binary size by at least some 20MB, which is not a lot considering the advantages
    • to avoid this, webrtc support would need to be optional behind iroh crate feature
  • low success rate over WAN
    • as found above, if none of the clients are on the same LAN, then attempting WebRTC ICE is usually a waste of time

Advantages

  • keep all local traffic local
  • make some classes browser-to-native traffic direct (e.g. backends hosted on public VPS)
  • greatly reduce relay bandwidth when each user has multiple nodes (e.g. browser tabs)
  • does not require any change to relay code or existing discovery mechanisms
  • only requires STUN server, which all Iroh Relays already have (we have tested it and it works fine)
  • implementation could be gated behind "webrtc" feature, avoiding any breaking changes to iroh api, or the 20MB tax on native binaries

Implementation details

We are interested in forking iroh and prototyping a webrtc implementation from scratch. After n0-computer/iroh-examples#113 we have understood how the "matchbox" library works. The library has various limitations (e.g. panics on network failure, uses unbounded channels, has no backpressure) that make it not as resilient to network conditions as we'd like. So it should be used better as a reference implementation of how the WebRTC API looks like and works, but not as dependency of this crate.

The broad idea is as follows. We are not familiar with the code base, so I marked places where I would appreciate some pointers into the code with comments and suggestions.

  • add "webrtc" iroh library feature, that brings in webrtc-based dependencies
  • add in endpoint info a boolean that says if our node is webrtc-enabled or not
    • where should this live?
  • after endpoint is successfully connected to another endpoint, if both endpoints are webrtc-enabled, begin "upgrade" attempt
    • is this similar to other transports / code paths ?
  • implement WebRTC Offer/Handshake back-and-forth over the existing endpoint using some iroh-private ALPN and direct messages
  • if datachannel is working, close original iroh connection, and start routing all messages through datachannel
  • if datachannel is not working, store that fact in memory to avoid trying again for the same peer over the same network for a few minutes

There is also the question of the ICE slow-down - the "WebRTC upgrade" logic should never block the client connection. Also, on node network change (e.g. when phone goes from wifi to GSM and back), all previously established WebRTC datachannels need to be checked if they still work, closed if they don't, and all downgraded peers need to be re-evaluated for possibility of WebRTC datachannel connection upgrade.

This is all a lot of moving parts; how would this fit into the existing connection handling implementation (e.g. from switching between relays and direct quinn connection on native)? I'm sure there are a lot of places where "webrtc" channel can be regarded as an alternative of the direct "quinn" channel, but also working for browsers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions