Skip to content

Commit 30838ff

Browse files
authored
Merge branch 'master' into add-doc-auto-cfg
2 parents 9ec95ad + acb4df7 commit 30838ff

File tree

2 files changed

+220
-7
lines changed

2 files changed

+220
-7
lines changed

src/protocol.rs

Lines changed: 142 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ const DNS4: u32 = 54;
2323
const DNS6: u32 = 55;
2424
const DNSADDR: u32 = 56;
2525
const HTTP: u32 = 480;
26-
const HTTPS: u32 = 443;
26+
const HTTPS: u32 = 443; // Deprecated - alias for /tls/http
2727
const IP4: u32 = 4;
2828
const IP6: u32 = 41;
29-
const P2P_WEBRTC_DIRECT: u32 = 276;
30-
const P2P_WEBRTC_STAR: u32 = 275;
29+
const P2P_WEBRTC_DIRECT: u32 = 276; // Deprecated
30+
const P2P_WEBRTC_STAR: u32 = 275; // Deprecated
3131
const WEBRTC_DIRECT: u32 = 280;
3232
const CERTHASH: u32 = 466;
33-
const P2P_WEBSOCKET_STAR: u32 = 479;
33+
const P2P_WEBSOCKET_STAR: u32 = 479; // Deprecated
3434
const MEMORY: u32 = 777;
3535
const ONION: u32 = 444;
3636
const ONION3: u32 = 445;
@@ -49,8 +49,16 @@ const UTP: u32 = 302;
4949
const WEBTRANSPORT: u32 = 465;
5050
const WS: u32 = 477;
5151
const WS_WITH_PATH: u32 = 4770; // Note: not standard
52-
const WSS: u32 = 478;
52+
const WSS: u32 = 478; // Deprecated - alias for /tls/ws
5353
const WSS_WITH_PATH: u32 = 4780; // Note: not standard
54+
const IP6ZONE: u32 = 42;
55+
const IPCIDR: u32 = 43;
56+
// const IPFS: u32 = 421; // Deprecated
57+
const GARLIC64: u32 = 446;
58+
const GARLIC32: u32 = 447;
59+
const SNI: u32 = 449;
60+
const P2P_STARDUST: u32 = 277; // Deprecated
61+
const WEBRTC: u32 = 281;
5462

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

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

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

tests/lib.rs

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

8787
impl Proto {
88-
const IMPL_VARIANT_COUNT: u8 = 32;
88+
const IMPL_VARIANT_COUNT: u8 = 39;
8989
}
9090

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

0 commit comments

Comments
 (0)