Skip to content

Commit d4db76b

Browse files
authored
Merge branch 'master' into chore/107-peerid
2 parents 4a625f3 + d2e5e37 commit d4db76b

File tree

4 files changed

+230
-8
lines changed

4 files changed

+230
-8
lines changed

Cargo.toml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ authors = ["dignifiedquire <[email protected]>", "Parity Technologies <ad
33
description = "Implementation of the multiaddr format"
44
edition = "2021"
55
rust-version = "1.59.0"
6-
homepage = "https://github.com/multiformats/rust-multiaddr"
6+
repository = "https://github.com/multiformats/rust-multiaddr"
77
keywords = ["multiaddr", "ipfs"]
88
license = "MIT"
99
name = "multiaddr"
@@ -31,3 +31,11 @@ bincode = "1"
3131
quickcheck = { version = "1.0.3", default-features = false }
3232
rand = "0.8.4"
3333
serde_json = "1.0"
34+
35+
# Passing arguments to the docsrs builder in order to properly document cfg's.
36+
# More information: https://docs.rs/about/builds#cross-compiling
37+
[package.metadata.docs.rs]
38+
all-features = true
39+
40+
[lints.rust]
41+
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(nightly)'] }

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//! Implementation of [multiaddr](https://github.com/multiformats/multiaddr) in Rust.
2+
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
23

34
pub use multihash;
45

src/protocol.rs

Lines changed: 142 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ const DNS4: u32 = 54;
2222
const DNS6: u32 = 55;
2323
const DNSADDR: u32 = 56;
2424
const HTTP: u32 = 480;
25-
const HTTPS: u32 = 443;
25+
const HTTPS: u32 = 443; // Deprecated - alias for /tls/http
2626
const IP4: u32 = 4;
2727
const IP6: u32 = 41;
28-
const P2P_WEBRTC_DIRECT: u32 = 276;
29-
const P2P_WEBRTC_STAR: u32 = 275;
28+
const P2P_WEBRTC_DIRECT: u32 = 276; // Deprecated
29+
const P2P_WEBRTC_STAR: u32 = 275; // Deprecated
3030
const WEBRTC_DIRECT: u32 = 280;
3131
const CERTHASH: u32 = 466;
32-
const P2P_WEBSOCKET_STAR: u32 = 479;
32+
const P2P_WEBSOCKET_STAR: u32 = 479; // Deprecated
3333
const MEMORY: u32 = 777;
3434
const ONION: u32 = 444;
3535
const ONION3: u32 = 445;
@@ -48,8 +48,16 @@ const UTP: u32 = 302;
4848
const WEBTRANSPORT: u32 = 465;
4949
const WS: u32 = 477;
5050
const WS_WITH_PATH: u32 = 4770; // Note: not standard
51-
const WSS: u32 = 478;
51+
const WSS: u32 = 478; // Deprecated - alias for /tls/ws
5252
const WSS_WITH_PATH: u32 = 4780; // Note: not standard
53+
const IP6ZONE: u32 = 42;
54+
const IPCIDR: u32 = 43;
55+
// const IPFS: u32 = 421; // Deprecated
56+
const GARLIC64: u32 = 446;
57+
const GARLIC32: u32 = 447;
58+
const SNI: u32 = 449;
59+
const P2P_STARDUST: u32 = 277; // Deprecated
60+
const WEBRTC: u32 = 281;
5361

5462
/// Type-alias for how multi-addresses use `Multihash`.
5563
///
@@ -113,6 +121,13 @@ pub enum Protocol<'a> {
113121
WebTransport,
114122
Ws(Cow<'a, str>),
115123
Wss(Cow<'a, str>),
124+
Ip6zone(Cow<'a, str>),
125+
Ipcidr(u8),
126+
Garlic64(Cow<'a, [u8]>),
127+
Garlic32(Cow<'a, [u8]>),
128+
Sni(Cow<'a, str>),
129+
P2pStardust,
130+
WebRTC,
116131
}
117132

118133
impl<'a> Protocol<'a> {
@@ -175,7 +190,7 @@ impl<'a> Protocol<'a> {
175190
let s = iter.next().ok_or(Error::InvalidProtocolString)?;
176191
Ok(Protocol::Unix(Cow::Borrowed(s)))
177192
}
178-
"p2p" => {
193+
"p2p" | "ipfs" => {
179194
let s = iter.next().ok_or(Error::InvalidProtocolString)?;
180195
let decoded = multibase::Base::Base58Btc.decode(s)?;
181196
let peer_id =
@@ -223,6 +238,44 @@ impl<'a> Protocol<'a> {
223238
let s = iter.next().ok_or(Error::InvalidProtocolString)?;
224239
Ok(Protocol::Memory(s.parse()?))
225240
}
241+
"ip6zone" => {
242+
let s = iter.next().ok_or(Error::InvalidProtocolString)?;
243+
Ok(Protocol::Ip6zone(Cow::Borrowed(s)))
244+
}
245+
"ipcidr" => {
246+
let s = iter.next().ok_or(Error::InvalidProtocolString)?;
247+
Ok(Protocol::Ipcidr(s.parse()?))
248+
}
249+
"garlic64" => {
250+
let s = iter
251+
.next()
252+
.ok_or(Error::InvalidProtocolString)?
253+
.replace('-', "+")
254+
.replace('~', "/");
255+
256+
if s.len() < 516 || s.len() > 616 {
257+
return Err(Error::InvalidProtocolString);
258+
}
259+
260+
let decoded = multibase::Base::Base64.decode(s)?;
261+
Ok(Protocol::Garlic64(Cow::from(decoded)))
262+
}
263+
"garlic32" => {
264+
let s = iter.next().ok_or(Error::InvalidProtocolString)?;
265+
266+
if s.len() < 55 && s.len() != 52 {
267+
return Err(Error::InvalidProtocolString);
268+
}
269+
270+
let decoded = multibase::Base::Base32Lower.decode(s)?;
271+
Ok(Protocol::Garlic32(Cow::from(decoded)))
272+
}
273+
"sni" => {
274+
let s = iter.next().ok_or(Error::InvalidProtocolString)?;
275+
Ok(Protocol::Sni(Cow::Borrowed(s)))
276+
}
277+
"p2p-stardust" => Ok(Protocol::P2pStardust),
278+
"webrtc" => Ok(Protocol::WebRTC),
226279
unknown => Err(Error::UnknownProtocolString(unknown.to_string())),
227280
}
228281
}
@@ -375,6 +428,35 @@ impl<'a> Protocol<'a> {
375428
let (data, rest) = split_at(n, input)?;
376429
Ok((Protocol::Wss(Cow::Borrowed(str::from_utf8(data)?)), rest))
377430
}
431+
IP6ZONE => {
432+
let (n, input) = decode::usize(input)?;
433+
let (data, rest) = split_at(n, input)?;
434+
Ok((
435+
Protocol::Ip6zone(Cow::Borrowed(str::from_utf8(data)?)),
436+
rest,
437+
))
438+
}
439+
IPCIDR => {
440+
let (data, rest) = split_at(1, input)?;
441+
Ok((Protocol::Ipcidr(data[0]), rest))
442+
}
443+
GARLIC64 => {
444+
let (n, input) = decode::usize(input)?;
445+
let (data, rest) = split_at(n, input)?;
446+
Ok((Protocol::Garlic64(Cow::Borrowed(data)), rest))
447+
}
448+
GARLIC32 => {
449+
let (n, input) = decode::usize(input)?;
450+
let (data, rest) = split_at(n, input)?;
451+
Ok((Protocol::Garlic32(Cow::Borrowed(data)), rest))
452+
}
453+
SNI => {
454+
let (n, input) = decode::usize(input)?;
455+
let (data, rest) = split_at(n, input)?;
456+
Ok((Protocol::Sni(Cow::Borrowed(str::from_utf8(data)?)), rest))
457+
}
458+
P2P_STARDUST => Ok((Protocol::P2pStardust, input)),
459+
WEBRTC => Ok((Protocol::WebRTC, input)),
378460
_ => Err(Error::UnknownProtocolId(id)),
379461
}
380462
}
@@ -494,6 +576,34 @@ impl<'a> Protocol<'a> {
494576
w.write_all(encode::u32(MEMORY, &mut buf))?;
495577
w.write_u64::<BigEndian>(*port)?
496578
}
579+
Protocol::Ip6zone(zone_id) => {
580+
w.write_all(encode::u32(IP6ZONE, &mut buf))?;
581+
let bytes = zone_id.as_bytes();
582+
w.write_all(encode::usize(bytes.len(), &mut encode::usize_buffer()))?;
583+
w.write_all(bytes)?
584+
}
585+
Protocol::Ipcidr(mask) => {
586+
w.write_all(encode::u32(IPCIDR, &mut buf))?;
587+
w.write_u8(*mask)?
588+
}
589+
Protocol::Garlic64(addr) => {
590+
w.write_all(encode::u32(GARLIC64, &mut buf))?;
591+
w.write_all(encode::usize(addr.len(), &mut encode::usize_buffer()))?;
592+
w.write_all(addr)?
593+
}
594+
Protocol::Garlic32(addr) => {
595+
w.write_all(encode::u32(GARLIC32, &mut buf))?;
596+
w.write_all(encode::usize(addr.len(), &mut encode::usize_buffer()))?;
597+
w.write_all(addr)?
598+
}
599+
Protocol::Sni(s) => {
600+
w.write_all(encode::u32(SNI, &mut buf))?;
601+
let bytes = s.as_bytes();
602+
w.write_all(encode::usize(bytes.len(), &mut encode::usize_buffer()))?;
603+
w.write_all(bytes)?
604+
}
605+
Protocol::P2pStardust => w.write_all(encode::u32(P2P_STARDUST, &mut buf))?,
606+
Protocol::WebRTC => w.write_all(encode::u32(WEBRTC, &mut buf))?,
497607
}
498608
Ok(())
499609
}
@@ -534,6 +644,13 @@ impl<'a> Protocol<'a> {
534644
WebTransport => WebTransport,
535645
Ws(cow) => Ws(Cow::Owned(cow.into_owned())),
536646
Wss(cow) => Wss(Cow::Owned(cow.into_owned())),
647+
Ip6zone(cow) => Ip6zone(Cow::Owned(cow.into_owned())),
648+
Ipcidr(mask) => Ipcidr(mask),
649+
Garlic64(addr) => Garlic64(Cow::Owned(addr.into_owned())),
650+
Garlic32(addr) => Garlic32(Cow::Owned(addr.into_owned())),
651+
Sni(cow) => Sni(Cow::Owned(cow.into_owned())),
652+
P2pStardust => P2pStardust,
653+
WebRTC => WebRTC,
537654
}
538655
}
539656

@@ -574,6 +691,13 @@ impl<'a> Protocol<'a> {
574691
Ws(_) => "x-parity-ws",
575692
Wss(ref s) if s == "/" => "wss",
576693
Wss(_) => "x-parity-wss",
694+
Ip6zone(_) => "ip6zone",
695+
Ipcidr(_) => "ipcidr",
696+
Garlic64(_) => "garlic64",
697+
Garlic32(_) => "garlic32",
698+
Sni(_) => "sni",
699+
P2pStardust => "p2p-stardust",
700+
WebRTC => "webrtc",
577701
}
578702
}
579703
}
@@ -619,6 +743,18 @@ impl<'a> fmt::Display for Protocol<'a> {
619743
percent_encoding::percent_encode(s.as_bytes(), PATH_SEGMENT_ENCODE_SET);
620744
write!(f, "/{encoded}")
621745
}
746+
Ip6zone(zone) => write!(f, "/{zone}"),
747+
Ipcidr(mask) => write!(f, "/{mask}"),
748+
Garlic64(addr) => write!(
749+
f,
750+
"/{}",
751+
multibase::Base::Base64
752+
.encode(addr)
753+
.replace('+', "-")
754+
.replace('/', "~")
755+
),
756+
Garlic32(addr) => write!(f, "/{}", multibase::Base::Base32Lower.encode(addr)),
757+
Sni(s) => write!(f, "/{s}"),
622758
_ => Ok(()),
623759
}
624760
}

tests/lib.rs

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl Arbitrary for Ma {
8484
struct Proto(Protocol<'static>);
8585

8686
impl Proto {
87-
const IMPL_VARIANT_COUNT: u8 = 32;
87+
const IMPL_VARIANT_COUNT: u8 = 39;
8888
}
8989

9090
impl Arbitrary for Proto {
@@ -137,6 +137,29 @@ impl Arbitrary for Proto {
137137
29 => Proto(WebTransport),
138138
30 => Proto(Ws("/".into())),
139139
31 => Proto(Wss("/".into())),
140+
32 => Proto(Ip6zone(Cow::Owned(SubString::arbitrary(g).0))),
141+
33 => Proto(Ipcidr(Arbitrary::arbitrary(g))),
142+
34 => {
143+
let len = usize::arbitrary(g) % (462 - 387) + 387;
144+
let a = iter::repeat_with(|| u8::arbitrary(g))
145+
.take(len)
146+
.collect::<Vec<_>>();
147+
Proto(Garlic64(Cow::Owned(a)))
148+
}
149+
35 => {
150+
let len = if bool::arbitrary(g) {
151+
32
152+
} else {
153+
usize::arbitrary(g) % 128 + 35
154+
};
155+
let a = iter::repeat_with(|| u8::arbitrary(g))
156+
.take(len)
157+
.collect::<Vec<_>>();
158+
Proto(Garlic32(Cow::Owned(a)))
159+
}
160+
36 => Proto(Sni(Cow::Owned(SubString::arbitrary(g).0))),
161+
37 => Proto(P2pStardust),
162+
38 => Proto(WebRTC),
140163
_ => panic!("outside range"),
141164
}
142165
}
@@ -231,6 +254,14 @@ fn construct_success() {
231254
"29260100094F819700803ECA6566E80C21",
232255
vec![Ip6("2601:9:4f81:9700:803e:ca65:66e8:c21".parse().unwrap())],
233256
);
257+
ma_valid(
258+
"/ip6/fe80::9700:803e:ca65:66e8:c21/ip6zone/wlan0",
259+
"29FE80000000009700803ECA6566E80C212A05776C616E30",
260+
vec![
261+
Ip6("fe80::9700:803e:ca65:66e8:c21".parse().unwrap()),
262+
Ip6zone(Cow::Borrowed("wlan0")),
263+
],
264+
);
234265
ma_valid("/udp/0", "91020000", vec![Udp(0)]);
235266
ma_valid("/tcp/0", "060000", vec![Tcp(0)]);
236267
ma_valid("/sctp/0", "84010000", vec![Sctp(0)]);
@@ -335,6 +366,44 @@ fn construct_success() {
335366
.into(),
336367
)],
337368
);
369+
ma_valid(
370+
"/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF\
371+
18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvG\
372+
onIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMS\
373+
iT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA",
374+
"BE0383038D3FC8C976A86AE4E78BA378E75EC41BC9AB1542A9CB422581987E118F5CB0C024F3639D6AD9B3AFF613672F07BFBBBFC2F920EF910534ECAA6FF9C03E\
375+
0FA4872A764D2FCE6D4CFC5A5A9800CD95944CC9EF0241F753FE71494A175F334B35682459ACADC4076428AB49B5A83A49D2EA2366B06461E4A559B0111FA750E0D\
376+
E0C138A94D1231ED5979572FF53922905636221994BDABC44BD0C17FEF11622B16432DB3F193400AF53CC61AA9BFC0C4C8D874B41A6E18732F0B60F5662EF1A89C8\
377+
0589DD8366C90BB58BB85EAD56356ABA2A244950CA170ABBD01094539014F84BDD383E4A10E00CEE63DFC3E809506E2D9B54EDBDCA1BACE6EAA119E68573D305337\
378+
91FBA830F5D80BE5C051A77C09415E3B8FE3139400848BE5244B8AE96BB0C4A24F819CBA0488F34985EAC741D3359180BD72CAFA1559E4C19F54EA8CEDBB6A5AFDE\
379+
4319396EB92AAB340C60A50CC2284580CB3AD09017E8D9ABC60269B3D8D687680BD86CE834412273D4F2E3BF68DD3D6FE87E2426AC658CD5C77FD5C0AA000000",
380+
vec![Garlic64(
381+
(
382+
&[
383+
141, 63, 200, 201, 118, 168, 106, 228, 231, 139, 163, 120, 231, 94, 196, 27, 201, 171, 21, 66,
384+
169, 203, 66, 37, 129, 152, 126, 17, 143, 92, 176, 192, 36, 243, 99, 157, 106, 217, 179, 175,
385+
246, 19, 103, 47, 7, 191, 187, 191, 194, 249, 32, 239, 145, 5, 52, 236, 170, 111, 249, 192,
386+
62, 15, 164, 135, 42, 118, 77, 47, 206, 109, 76, 252, 90, 90, 152, 0, 205, 149, 148, 76,
387+
201, 239, 2, 65, 247, 83, 254, 113, 73, 74, 23, 95, 51, 75, 53, 104, 36, 89, 172, 173,
388+
196, 7, 100, 40, 171, 73, 181, 168, 58, 73, 210, 234, 35, 102, 176, 100, 97, 228, 165, 89,
389+
176, 17, 31, 167, 80, 224, 222, 12, 19, 138, 148, 209, 35, 30, 213, 151, 149, 114, 255, 83,
390+
146, 41, 5, 99, 98, 33, 153, 75, 218, 188, 68, 189, 12, 23, 254, 241, 22, 34, 177, 100,
391+
50, 219, 63, 25, 52, 0, 175, 83, 204, 97, 170, 155, 252, 12, 76, 141, 135, 75, 65, 166,
392+
225, 135, 50, 240, 182, 15, 86, 98, 239, 26, 137, 200, 5, 137, 221, 131, 102, 201, 11, 181,
393+
139, 184, 94, 173, 86, 53, 106, 186, 42, 36, 73, 80, 202, 23, 10, 187, 208, 16, 148, 83,
394+
144, 20, 248, 75, 221, 56, 62, 74, 16, 224, 12, 238, 99, 223, 195, 232, 9, 80, 110, 45,
395+
155, 84, 237, 189, 202, 27, 172, 230, 234, 161, 25, 230, 133, 115, 211, 5, 51, 121, 31, 186,
396+
131, 15, 93, 128, 190, 92, 5, 26, 119, 192, 148, 21, 227, 184, 254, 49, 57, 64, 8, 72,
397+
190, 82, 68, 184, 174, 150, 187, 12, 74, 36, 248, 25, 203, 160, 72, 143, 52, 152, 94, 172,
398+
116, 29, 51, 89, 24, 11, 215, 44, 175, 161, 85, 158, 76, 25, 245, 78, 168, 206, 219, 182,
399+
165, 175, 222, 67, 25, 57, 110, 185, 42, 171, 52, 12, 96, 165, 12, 194, 40, 69, 128, 203,
400+
58, 208, 144, 23, 232, 217, 171, 198, 2, 105, 179, 216, 214, 135, 104, 11, 216, 108, 232, 52,
401+
65, 34, 115, 212, 242, 227, 191, 104, 221, 61, 111, 232, 126, 36, 38, 172, 101, 140, 213, 199,
402+
127, 213, 192, 170, 0, 0, 0,
403+
]
404+
).into()
405+
)],
406+
);
338407
ma_valid(
339408
"/dnsaddr/sjc-1.bootstrap.libp2p.io",
340409
"3819736A632D312E626F6F7473747261702E6C69627032702E696F",
@@ -413,6 +482,7 @@ fn construct_fail() {
413482
"/ip4/::1",
414483
"/ip4/fdpsofodsajfdoisa",
415484
"/ip6",
485+
"/ip6/fe80::9700:803e:ca65:66e8:c21/ip6zone",
416486
"/udp",
417487
"/tcp",
418488
"/sctp",
@@ -430,6 +500,12 @@ fn construct_fail() {
430500
"/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:-1",
431501
"/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd",
432502
"/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyy@:666",
503+
"/garlic64/jT~",
504+
"/garlic32/566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzu",
505+
"/garlic32/566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzu77",
506+
"/garlic32/566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzu:80",
507+
"/garlic32/566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq:-1",
508+
"/garlic32/566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzu@",
433509
"/udp/1234/sctp",
434510
"/udp/1234/udt/1234",
435511
"/udp/1234/utp/1234",
@@ -581,6 +657,7 @@ fn protocol_stack() {
581657
"/ip4/0.0.0.0",
582658
"/ip6/::1",
583659
"/ip6/2601:9:4f81:9700:803e:ca65:66e8:c21",
660+
"/ip6/fe80::9700:803e:ca65:66e8:c21/ip6zone/wlan0",
584661
"/udp/0",
585662
"/tcp/0",
586663
"/sctp/0",

0 commit comments

Comments
 (0)