Skip to content

Commit

Permalink
feat: Add /webrtc protocol (browser-to-browser)
Browse files Browse the repository at this point in the history
See decision making in multiformats/multiaddr#150 (comment).
  • Loading branch information
Marcel-G committed Sep 11, 2023
1 parent 0114e72 commit 05af19f
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 21 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
- Make `/p2p` typesafe, i.e. have `Protocol::P2p` contain a `PeerId` instead of a `Multihash`.
See [PR 83].

- Add `WebRTC` (browser-to-browser) instance for `Multiaddr`.

[multiformats/multiaddr discussion]: https://github.com/multiformats/multiaddr/pull/150#issuecomment-1468791586
[PR 70]: https://github.com/multiformats/rust-multiaddr/pull/70
[PR 77]: https://github.com/multiformats/rust-multiaddr/pull/77
Expand Down
7 changes: 7 additions & 0 deletions src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const IP6: u32 = 41;
const P2P_WEBRTC_DIRECT: u32 = 276;
const P2P_WEBRTC_STAR: u32 = 275;
const WEBRTC_DIRECT: u32 = 280;
const WEBRTC: u32 = 281;
const CERTHASH: u32 = 466;
const P2P_WEBSOCKET_STAR: u32 = 479;
const MEMORY: u32 = 777;
Expand Down Expand Up @@ -93,6 +94,7 @@ pub enum Protocol<'a> {
P2pWebRtcDirect,
P2pWebRtcStar,
WebRTCDirect,
WebRTC,
Certhash(Multihash),
P2pWebSocketStar,
/// Contains the "port" to contact. Similar to TCP or UDP, 0 means "assign me a port".
Expand Down Expand Up @@ -213,6 +215,7 @@ impl<'a> Protocol<'a> {
"p2p-websocket-star" => Ok(Protocol::P2pWebSocketStar),
"p2p-webrtc-star" => Ok(Protocol::P2pWebRtcStar),
"webrtc-direct" => Ok(Protocol::WebRTCDirect),
"webrtc" => Ok(Protocol::WebRTC),
"certhash" => {
let s = iter.next().ok_or(Error::InvalidProtocolString)?;
let (_base, decoded) = multibase::decode(s)?;
Expand Down Expand Up @@ -295,6 +298,7 @@ impl<'a> Protocol<'a> {
P2P_WEBRTC_DIRECT => Ok((Protocol::P2pWebRtcDirect, input)),
P2P_WEBRTC_STAR => Ok((Protocol::P2pWebRtcStar, input)),
WEBRTC_DIRECT => Ok((Protocol::WebRTCDirect, input)),
WEBRTC => Ok((Protocol::WebRTC, input)),
CERTHASH => {
let (n, input) = decode::usize(input)?;
let (data, rest) = split_at(n, input)?;
Expand Down Expand Up @@ -483,6 +487,7 @@ impl<'a> Protocol<'a> {
Protocol::P2pWebSocketStar => w.write_all(encode::u32(P2P_WEBSOCKET_STAR, &mut buf))?,
Protocol::P2pWebRtcStar => w.write_all(encode::u32(P2P_WEBRTC_STAR, &mut buf))?,
Protocol::WebRTCDirect => w.write_all(encode::u32(WEBRTC_DIRECT, &mut buf))?,
Protocol::WebRTC => w.write_all(encode::u32(WEBRTC, &mut buf))?,
Protocol::Certhash(hash) => {
w.write_all(encode::u32(CERTHASH, &mut buf))?;
let bytes = hash.to_bytes();
Expand Down Expand Up @@ -515,6 +520,7 @@ impl<'a> Protocol<'a> {
P2pWebRtcDirect => P2pWebRtcDirect,
P2pWebRtcStar => P2pWebRtcStar,
WebRTCDirect => WebRTCDirect,
WebRTC => WebRTC,
Certhash(hash) => Certhash(hash),
P2pWebSocketStar => P2pWebSocketStar,
Memory(a) => Memory(a),
Expand Down Expand Up @@ -553,6 +559,7 @@ impl<'a> Protocol<'a> {
P2pWebRtcDirect => "p2p-webrtc-direct",
P2pWebRtcStar => "p2p-webrtc-star",
WebRTCDirect => "webrtc-direct",
WebRTC => "webrtc",
Certhash(_) => "certhash",
P2pWebSocketStar => "p2p-websocket-star",
Memory(_) => "memory",
Expand Down
51 changes: 30 additions & 21 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl Arbitrary for Ma {
struct Proto(Protocol<'static>);

impl Proto {
const IMPL_VARIANT_COUNT: u8 = 32;
const IMPL_VARIANT_COUNT: u8 = 33;
}

impl Arbitrary for Proto {
Expand All @@ -104,40 +104,41 @@ impl Arbitrary for Proto {
9 => Proto(P2pWebRtcDirect),
10 => Proto(P2pWebRtcStar),
11 => Proto(WebRTCDirect),
12 => Proto(Certhash(Mh::arbitrary(g).0)),
13 => Proto(P2pWebSocketStar),
14 => Proto(Memory(Arbitrary::arbitrary(g))),
15 => {
12 => Proto(WebRTC),
13 => Proto(Certhash(Mh::arbitrary(g).0)),
14 => Proto(P2pWebSocketStar),
15 => Proto(Memory(Arbitrary::arbitrary(g))),
16 => {
let a = iter::repeat_with(|| u8::arbitrary(g))
.take(10)
.collect::<Vec<_>>()
.try_into()
.unwrap();
Proto(Onion(Cow::Owned(a), std::cmp::max(1, u16::arbitrary(g))))
}
16 => {
17 => {
let a: [u8; 35] = iter::repeat_with(|| u8::arbitrary(g))
.take(35)
.collect::<Vec<_>>()
.try_into()
.unwrap();
Proto(Onion3((a, std::cmp::max(1, u16::arbitrary(g))).into()))
}
17 => Proto(P2p(PId::arbitrary(g).0)),
18 => Proto(P2pCircuit),
19 => Proto(Quic),
20 => Proto(QuicV1),
21 => Proto(Sctp(Arbitrary::arbitrary(g))),
22 => Proto(Tcp(Arbitrary::arbitrary(g))),
23 => Proto(Tls),
24 => Proto(Noise),
25 => Proto(Udp(Arbitrary::arbitrary(g))),
26 => Proto(Udt),
27 => Proto(Unix(Cow::Owned(SubString::arbitrary(g).0))),
28 => Proto(Utp),
29 => Proto(WebTransport),
30 => Proto(Ws("/".into())),
31 => Proto(Wss("/".into())),
18 => Proto(P2p(PId::arbitrary(g).0)),
19 => Proto(P2pCircuit),
20 => Proto(Quic),
21 => Proto(QuicV1),
22 => Proto(Sctp(Arbitrary::arbitrary(g))),
23 => Proto(Tcp(Arbitrary::arbitrary(g))),
24 => Proto(Tls),
25 => Proto(Noise),
26 => Proto(Udp(Arbitrary::arbitrary(g))),
27 => Proto(Udt),
28 => Proto(Unix(Cow::Owned(SubString::arbitrary(g).0))),
29 => Proto(Utp),
30 => Proto(WebTransport),
31 => Proto(Ws("/".into())),
32 => Proto(Wss("/".into())),
_ => panic!("outside range"),
}
}
Expand Down Expand Up @@ -387,6 +388,12 @@ fn construct_success() {
],
);

ma_valid(
"/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/4001/wss/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN/p2p-circuit/webrtc/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
"29200108A07AC542013AC986FFFE317095060FA1DE03A50322122006B3608AA000274049EB28AD8E793A26FF6FAB281A7D3BD77CD18EB745DFAABBA2029902A503221220D52EBB89D85B02A284948203A62FF28389C57C9F42BEEC4EC20DB76A68911C0B",
vec![Ip6(addr6),Tcp(4001), Wss("/".into()), P2p(multihash("QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN")), P2pCircuit, WebRTC, P2p(multihash("QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC"))],

Check failure on line 394 in tests/lib.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest)

expected function, found crate `multihash`

Check failure on line 394 in tests/lib.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest)

expected function, found crate `multihash`

Check failure on line 394 in tests/lib.rs

View workflow job for this annotation

GitHub Actions / Build (macos-latest)

expected function, found crate `multihash`

Check failure on line 394 in tests/lib.rs

View workflow job for this annotation

GitHub Actions / Build (macos-latest)

expected function, found crate `multihash`

Check failure on line 394 in tests/lib.rs

View workflow job for this annotation

GitHub Actions / Build (windows-latest)

expected function, found crate `multihash`

Check failure on line 394 in tests/lib.rs

View workflow job for this annotation

GitHub Actions / Build (windows-latest)

expected function, found crate `multihash`
);

ma_valid(
"/ip4/127.0.0.1/udp/1234/quic/webtransport",
"047F000001910204D2CC03D103",
Expand Down Expand Up @@ -615,6 +622,7 @@ fn protocol_stack() {
"/ip4/127.0.0.1/tcp/127/tls/ws",
"/ip4/127.0.0.1/tcp/127/noise",
"/ip4/127.0.0.1/udp/1234/webrtc-direct",
"/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/4001/wss/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN/p2p-circuit/webrtc/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
];
let argless = std::collections::HashSet::from([
"http",
Expand All @@ -630,6 +638,7 @@ fn protocol_stack() {
"udt",
"utp",
"webrtc-direct",
"webrtc",
"ws",
"wss",
]);
Expand Down

0 comments on commit 05af19f

Please sign in to comment.