1
2use arrayref::array_ref;
3use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
4use crate::{Result, Error};
5use data_encoding::BASE32;
6use multihash::Multihash;
7use std::{
8 borrow::Cow,
9 convert::From,
10 fmt,
11 io::{Cursor, Write},
12 net::{IpAddr, Ipv4Addr, Ipv6Addr},
13 str::{self, FromStr}
14};
15use unsigned_varint::{encode, decode};
16use crate::onion_addr::Onion3Addr;
17
18const DCCP: u32 = 33;
19const DNS: u32 = 53;
20const DNS4: u32 = 54;
21const DNS6: u32 = 55;
22const DNSADDR: u32 = 56;
23const HTTP: u32 = 480;
24const HTTPS: u32 = 443;
25const IP4: u32 = 4;
26const IP6: u32 = 41;
27const P2P_WEBRTC_DIRECT: u32 = 276;
28const P2P_WEBRTC_STAR: u32 = 275;
29const P2P_WEBSOCKET_STAR: u32 = 479;
30const MEMORY: u32 = 777;
31const ONION: u32 = 444;
32const ONION3: u32 = 445;
33const P2P: u32 = 421;
34const P2P_CIRCUIT: u32 = 290;
35const QUIC: u32 = 460;
36const SCTP: u32 = 132;
37const TCP: u32 = 6;
38const UDP: u32 = 273;
39const UDT: u32 = 301;
40const UNIX: u32 = 400;
41const UTP: u32 = 302;
42const WS: u32 = 477;
43const WS_WITH_PATH: u32 = 4770; const WSS: u32 = 478;
45const WSS_WITH_PATH: u32 = 4780; const PATH_SEGMENT_ENCODE_SET: &percent_encoding::AsciiSet = &percent_encoding::CONTROLS
48 .add(b'%')
49 .add(b'/')
50 .add(b'`')
51 .add(b'?')
52 .add(b'{')
53 .add(b'}')
54 .add(b' ')
55 .add(b'"')
56 .add(b'#')
57 .add(b'<')
58 .add(b'>');
59
60#[derive(PartialEq, Eq, Clone, Debug)]
67pub enum Protocol<'a> {
68 Dccp(u16),
69 Dns(Cow<'a, str>),
70 Dns4(Cow<'a, str>),
71 Dns6(Cow<'a, str>),
72 Dnsaddr(Cow<'a, str>),
73 Http,
74 Https,
75 Ip4(Ipv4Addr),
76 Ip6(Ipv6Addr),
77 P2pWebRtcDirect,
78 P2pWebRtcStar,
79 P2pWebSocketStar,
80 Memory(u64),
82 Onion(Cow<'a, [u8; 10]>, u16),
83 Onion3(Onion3Addr<'a>),
84 P2p(Multihash),
85 P2pCircuit,
86 Quic,
87 Sctp(u16),
88 Tcp(u16),
89 Udp(u16),
90 Udt,
91 Unix(Cow<'a, str>),
92 Utp,
93 Ws(Cow<'a, str>),
94 Wss(Cow<'a, str>),
95}
96
97impl<'a> Protocol<'a> {
98 pub fn from_str_parts<I>(mut iter: I) -> Result<Self>
105 where
106 I: Iterator<Item=&'a str>
107 {
108 match iter.next().ok_or(Error::InvalidProtocolString)? {
109 "ip4" => {
110 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
111 Ok(Protocol::Ip4(Ipv4Addr::from_str(s)?))
112 }
113 "tcp" => {
114 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
115 Ok(Protocol::Tcp(s.parse()?))
116 }
117 "udp" => {
118 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
119 Ok(Protocol::Udp(s.parse()?))
120 }
121 "dccp" => {
122 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
123 Ok(Protocol::Dccp(s.parse()?))
124 }
125 "ip6" => {
126 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
127 Ok(Protocol::Ip6(Ipv6Addr::from_str(s)?))
128 }
129 "dns" => {
130 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
131 Ok(Protocol::Dns(Cow::Borrowed(s)))
132 }
133 "dns4" => {
134 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
135 Ok(Protocol::Dns4(Cow::Borrowed(s)))
136 }
137 "dns6" => {
138 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
139 Ok(Protocol::Dns6(Cow::Borrowed(s)))
140 }
141 "dnsaddr" => {
142 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
143 Ok(Protocol::Dnsaddr(Cow::Borrowed(s)))
144 }
145 "sctp" => {
146 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
147 Ok(Protocol::Sctp(s.parse()?))
148 }
149 "udt" => Ok(Protocol::Udt),
150 "utp" => Ok(Protocol::Utp),
151 "unix" => {
152 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
153 Ok(Protocol::Unix(Cow::Borrowed(s)))
154 }
155 "p2p" => {
156 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
157 let decoded = bs58::decode(s).into_vec()?;
158 Ok(Protocol::P2p(Multihash::from_bytes(&decoded)?))
159 }
160 "http" => Ok(Protocol::Http),
161 "https" => Ok(Protocol::Https),
162 "onion" =>
163 iter.next()
164 .ok_or(Error::InvalidProtocolString)
165 .and_then(|s| read_onion(&s.to_uppercase()))
166 .map(|(a, p)| Protocol::Onion(Cow::Owned(a), p)),
167 "onion3" =>
168 iter.next()
169 .ok_or(Error::InvalidProtocolString)
170 .and_then(|s| read_onion3(&s.to_uppercase()))
171 .map(|(a, p)| Protocol::Onion3((a, p).into())),
172 "quic" => Ok(Protocol::Quic),
173 "ws" => Ok(Protocol::Ws(Cow::Borrowed("/"))),
174 "wss" => Ok(Protocol::Wss(Cow::Borrowed("/"))),
175 "x-parity-ws" => {
176 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
177 let decoded = percent_encoding::percent_decode(s.as_bytes()).decode_utf8()?;
178 Ok(Protocol::Ws(decoded))
179 }
180 "x-parity-wss" => {
181 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
182 let decoded = percent_encoding::percent_decode(s.as_bytes()).decode_utf8()?;
183 Ok(Protocol::Wss(decoded))
184 }
185 "p2p-websocket-star" => Ok(Protocol::P2pWebSocketStar),
186 "p2p-webrtc-star" => Ok(Protocol::P2pWebRtcStar),
187 "p2p-webrtc-direct" => Ok(Protocol::P2pWebRtcDirect),
188 "p2p-circuit" => Ok(Protocol::P2pCircuit),
189 "memory" => {
190 let s = iter.next().ok_or(Error::InvalidProtocolString)?;
191 Ok(Protocol::Memory(s.parse()?))
192 }
193 unknown => Err(Error::UnknownProtocolString(unknown.to_string()))
194 }
195 }
196
197 pub fn from_bytes(input: &'a [u8]) -> Result<(Self, &'a [u8])> {
200 fn split_at(n: usize, input: &[u8]) -> Result<(&[u8], &[u8])> {
201 if input.len() < n {
202 return Err(Error::DataLessThanLen)
203 }
204 Ok(input.split_at(n))
205 }
206 let (id, input) = decode::u32(input)?;
207 match id {
208 DCCP => {
209 let (data, rest) = split_at(2, input)?;
210 let mut rdr = Cursor::new(data);
211 let num = rdr.read_u16::<BigEndian>()?;
212 Ok((Protocol::Dccp(num), rest))
213 }
214 DNS => {
215 let (n, input) = decode::usize(input)?;
216 let (data, rest) = split_at(n, input)?;
217 Ok((Protocol::Dns(Cow::Borrowed(str::from_utf8(data)?)), rest))
218 }
219 DNS4 => {
220 let (n, input) = decode::usize(input)?;
221 let (data, rest) = split_at(n, input)?;
222 Ok((Protocol::Dns4(Cow::Borrowed(str::from_utf8(data)?)), rest))
223 }
224 DNS6 => {
225 let (n, input) = decode::usize(input)?;
226 let (data, rest) = split_at(n, input)?;
227 Ok((Protocol::Dns6(Cow::Borrowed(str::from_utf8(data)?)), rest))
228 }
229 DNSADDR => {
230 let (n, input) = decode::usize(input)?;
231 let (data, rest) = split_at(n, input)?;
232 Ok((Protocol::Dnsaddr(Cow::Borrowed(str::from_utf8(data)?)), rest))
233 }
234 HTTP => Ok((Protocol::Http, input)),
235 HTTPS => Ok((Protocol::Https, input)),
236 IP4 => {
237 let (data, rest) = split_at(4, input)?;
238 Ok((Protocol::Ip4(Ipv4Addr::new(data[0], data[1], data[2], data[3])), rest))
239 }
240 IP6 => {
241 let (data, rest) = split_at(16, input)?;
242 let mut rdr = Cursor::new(data);
243 let mut seg = [0_u16; 8];
244
245 for x in seg.iter_mut() {
246 *x = rdr.read_u16::<BigEndian>()?;
247 }
248
249 let addr = Ipv6Addr::new(seg[0],
250 seg[1],
251 seg[2],
252 seg[3],
253 seg[4],
254 seg[5],
255 seg[6],
256 seg[7]);
257
258 Ok((Protocol::Ip6(addr), rest))
259 }
260 P2P_WEBRTC_DIRECT => Ok((Protocol::P2pWebRtcDirect, input)),
261 P2P_WEBRTC_STAR => Ok((Protocol::P2pWebRtcStar, input)),
262 P2P_WEBSOCKET_STAR => Ok((Protocol::P2pWebSocketStar, input)),
263 MEMORY => {
264 let (data, rest) = split_at(8, input)?;
265 let mut rdr = Cursor::new(data);
266 let num = rdr.read_u64::<BigEndian>()?;
267 Ok((Protocol::Memory(num), rest))
268 }
269 ONION => {
270 let (data, rest) = split_at(12, input)?;
271 let port = BigEndian::read_u16(&data[10 ..]);
272 Ok((Protocol::Onion(Cow::Borrowed(array_ref!(data, 0, 10)), port), rest))
273 }
274 ONION3 => {
275 let (data, rest) = split_at(37, input)?;
276 let port = BigEndian::read_u16(&data[35 ..]);
277 Ok((Protocol::Onion3((array_ref!(data, 0, 35), port).into()), rest))
278 }
279 P2P => {
280 let (n, input) = decode::usize(input)?;
281 let (data, rest) = split_at(n, input)?;
282 Ok((Protocol::P2p(Multihash::from_bytes(data)?), rest))
283 }
284 P2P_CIRCUIT => Ok((Protocol::P2pCircuit, input)),
285 QUIC => Ok((Protocol::Quic, input)),
286 SCTP => {
287 let (data, rest) = split_at(2, input)?;
288 let mut rdr = Cursor::new(data);
289 let num = rdr.read_u16::<BigEndian>()?;
290 Ok((Protocol::Sctp(num), rest))
291 }
292 TCP => {
293 let (data, rest) = split_at(2, input)?;
294 let mut rdr = Cursor::new(data);
295 let num = rdr.read_u16::<BigEndian>()?;
296 Ok((Protocol::Tcp(num), rest))
297 }
298 UDP => {
299 let (data, rest) = split_at(2, input)?;
300 let mut rdr = Cursor::new(data);
301 let num = rdr.read_u16::<BigEndian>()?;
302 Ok((Protocol::Udp(num), rest))
303 }
304 UDT => Ok((Protocol::Udt, input)),
305 UNIX => {
306 let (n, input) = decode::usize(input)?;
307 let (data, rest) = split_at(n, input)?;
308 Ok((Protocol::Unix(Cow::Borrowed(str::from_utf8(data)?)), rest))
309 }
310 UTP => Ok((Protocol::Utp, input)),
311 WS => Ok((Protocol::Ws(Cow::Borrowed("/")), input)),
312 WS_WITH_PATH => {
313 let (n, input) = decode::usize(input)?;
314 let (data, rest) = split_at(n, input)?;
315 Ok((Protocol::Ws(Cow::Borrowed(str::from_utf8(data)?)), rest))
316 }
317 WSS => Ok((Protocol::Wss(Cow::Borrowed("/")), input)),
318 WSS_WITH_PATH => {
319 let (n, input) = decode::usize(input)?;
320 let (data, rest) = split_at(n, input)?;
321 Ok((Protocol::Wss(Cow::Borrowed(str::from_utf8(data)?)), rest))
322 }
323 _ => Err(Error::UnknownProtocolId(id))
324 }
325 }
326
327 pub fn write_bytes<W: Write>(&self, w: &mut W) -> Result<()> {
330 let mut buf = encode::u32_buffer();
331 match self {
332 Protocol::Ip4(addr) => {
333 w.write_all(encode::u32(IP4, &mut buf))?;
334 w.write_all(&addr.octets())?
335 }
336 Protocol::Ip6(addr) => {
337 w.write_all(encode::u32(IP6, &mut buf))?;
338 for &segment in &addr.segments() {
339 w.write_u16::<BigEndian>(segment)?
340 }
341 }
342 Protocol::Tcp(port) => {
343 w.write_all(encode::u32(TCP, &mut buf))?;
344 w.write_u16::<BigEndian>(*port)?
345 }
346 Protocol::Udp(port) => {
347 w.write_all(encode::u32(UDP, &mut buf))?;
348 w.write_u16::<BigEndian>(*port)?
349 }
350 Protocol::Dccp(port) => {
351 w.write_all(encode::u32(DCCP, &mut buf))?;
352 w.write_u16::<BigEndian>(*port)?
353 }
354 Protocol::Sctp(port) => {
355 w.write_all(encode::u32(SCTP, &mut buf))?;
356 w.write_u16::<BigEndian>(*port)?
357 }
358 Protocol::Dns(s) => {
359 w.write_all(encode::u32(DNS, &mut buf))?;
360 let bytes = s.as_bytes();
361 w.write_all(encode::usize(bytes.len(), &mut encode::usize_buffer()))?;
362 w.write_all(&bytes)?
363 }
364 Protocol::Dns4(s) => {
365 w.write_all(encode::u32(DNS4, &mut buf))?;
366 let bytes = s.as_bytes();
367 w.write_all(encode::usize(bytes.len(), &mut encode::usize_buffer()))?;
368 w.write_all(&bytes)?
369 }
370 Protocol::Dns6(s) => {
371 w.write_all(encode::u32(DNS6, &mut buf))?;
372 let bytes = s.as_bytes();
373 w.write_all(encode::usize(bytes.len(), &mut encode::usize_buffer()))?;
374 w.write_all(&bytes)?
375 }
376 Protocol::Dnsaddr(s) => {
377 w.write_all(encode::u32(DNSADDR, &mut buf))?;
378 let bytes = s.as_bytes();
379 w.write_all(encode::usize(bytes.len(), &mut encode::usize_buffer()))?;
380 w.write_all(&bytes)?
381 }
382 Protocol::Unix(s) => {
383 w.write_all(encode::u32(UNIX, &mut buf))?;
384 let bytes = s.as_bytes();
385 w.write_all(encode::usize(bytes.len(), &mut encode::usize_buffer()))?;
386 w.write_all(&bytes)?
387 }
388 Protocol::P2p(multihash) => {
389 w.write_all(encode::u32(P2P, &mut buf))?;
390 let bytes = multihash.to_bytes();
391 w.write_all(encode::usize(bytes.len(), &mut encode::usize_buffer()))?;
392 w.write_all(&bytes)?
393 }
394 Protocol::Onion(addr, port) => {
395 w.write_all(encode::u32(ONION, &mut buf))?;
396 w.write_all(addr.as_ref())?;
397 w.write_u16::<BigEndian>(*port)?
398 }
399 Protocol::Onion3(addr) => {
400 w.write_all(encode::u32(ONION3, &mut buf))?;
401 w.write_all(addr.hash().as_ref())?;
402 w.write_u16::<BigEndian>(addr.port())?
403 }
404 Protocol::Quic => w.write_all(encode::u32(QUIC, &mut buf))?,
405 Protocol::Utp => w.write_all(encode::u32(UTP, &mut buf))?,
406 Protocol::Udt => w.write_all(encode::u32(UDT, &mut buf))?,
407 Protocol::Http => w.write_all(encode::u32(HTTP, &mut buf))?,
408 Protocol::Https => w.write_all(encode::u32(HTTPS, &mut buf))?,
409 Protocol::Ws(ref s) if s == "/" => w.write_all(encode::u32(WS, &mut buf))?,
410 Protocol::Ws(s) => {
411 w.write_all(encode::u32(WS_WITH_PATH, &mut buf))?;
412 let bytes = s.as_bytes();
413 w.write_all(encode::usize(bytes.len(), &mut encode::usize_buffer()))?;
414 w.write_all(&bytes)?
415 },
416 Protocol::Wss(ref s) if s == "/" => w.write_all(encode::u32(WSS, &mut buf))?,
417 Protocol::Wss(s) => {
418 w.write_all(encode::u32(WSS_WITH_PATH, &mut buf))?;
419 let bytes = s.as_bytes();
420 w.write_all(encode::usize(bytes.len(), &mut encode::usize_buffer()))?;
421 w.write_all(&bytes)?
422 },
423 Protocol::P2pWebSocketStar => w.write_all(encode::u32(P2P_WEBSOCKET_STAR, &mut buf))?,
424 Protocol::P2pWebRtcStar => w.write_all(encode::u32(P2P_WEBRTC_STAR, &mut buf))?,
425 Protocol::P2pWebRtcDirect => w.write_all(encode::u32(P2P_WEBRTC_DIRECT, &mut buf))?,
426 Protocol::P2pCircuit => w.write_all(encode::u32(P2P_CIRCUIT, &mut buf))?,
427 Protocol::Memory(port) => {
428 w.write_all(encode::u32(MEMORY, &mut buf))?;
429 w.write_u64::<BigEndian>(*port)?
430 }
431 }
432 Ok(())
433 }
434
435 pub fn acquire<'b>(self) -> Protocol<'b> {
437 use self::Protocol::*;
438 match self {
439 Dccp(a) => Dccp(a),
440 Dns(cow) => Dns(Cow::Owned(cow.into_owned())),
441 Dns4(cow) => Dns4(Cow::Owned(cow.into_owned())),
442 Dns6(cow) => Dns6(Cow::Owned(cow.into_owned())),
443 Dnsaddr(cow) => Dnsaddr(Cow::Owned(cow.into_owned())),
444 Http => Http,
445 Https => Https,
446 Ip4(a) => Ip4(a),
447 Ip6(a) => Ip6(a),
448 P2pWebRtcDirect => P2pWebRtcDirect,
449 P2pWebRtcStar => P2pWebRtcStar,
450 P2pWebSocketStar => P2pWebSocketStar,
451 Memory(a) => Memory(a),
452 Onion(addr, port) => Onion(Cow::Owned(addr.into_owned()), port),
453 Onion3(addr) => Onion3(addr.acquire()),
454 P2p(a) => P2p(a),
455 P2pCircuit => P2pCircuit,
456 Quic => Quic,
457 Sctp(a) => Sctp(a),
458 Tcp(a) => Tcp(a),
459 Udp(a) => Udp(a),
460 Udt => Udt,
461 Unix(cow) => Unix(Cow::Owned(cow.into_owned())),
462 Utp => Utp,
463 Ws(cow) => Ws(Cow::Owned(cow.into_owned())),
464 Wss(cow) => Wss(Cow::Owned(cow.into_owned())),
465 }
466 }
467}
468
469impl<'a> fmt::Display for Protocol<'a> {
470 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
471 use self::Protocol::*;
472 match self {
473 Dccp(port) => write!(f, "/dccp/{}", port),
474 Dns(s) => write!(f, "/dns/{}", s),
475 Dns4(s) => write!(f, "/dns4/{}", s),
476 Dns6(s) => write!(f, "/dns6/{}", s),
477 Dnsaddr(s) => write!(f, "/dnsaddr/{}", s),
478 Http => f.write_str("/http"),
479 Https => f.write_str("/https"),
480 Ip4(addr) => write!(f, "/ip4/{}", addr),
481 Ip6(addr) => write!(f, "/ip6/{}", addr),
482 P2pWebRtcDirect => f.write_str("/p2p-webrtc-direct"),
483 P2pWebRtcStar => f.write_str("/p2p-webrtc-star"),
484 P2pWebSocketStar => f.write_str("/p2p-websocket-star"),
485 Memory(port) => write!(f, "/memory/{}", port),
486 Onion(addr, port) => {
487 let s = BASE32.encode(addr.as_ref());
488 write!(f, "/onion/{}:{}", s.to_lowercase(), port)
489 }
490 Onion3(addr ) => {
491 let s = BASE32.encode(addr.hash());
492 write!(f, "/onion3/{}:{}", s.to_lowercase(), addr.port())
493 }
494 P2p(c) => write!(f, "/p2p/{}", bs58::encode(c.to_bytes()).into_string()),
495 P2pCircuit => f.write_str("/p2p-circuit"),
496 Quic => f.write_str("/quic"),
497 Sctp(port) => write!(f, "/sctp/{}", port),
498 Tcp(port) => write!(f, "/tcp/{}", port),
499 Udp(port) => write!(f, "/udp/{}", port),
500 Udt => f.write_str("/udt"),
501 Unix(s) => write!(f, "/unix/{}", s),
502 Utp => f.write_str("/utp"),
503 Ws(ref s) if s == "/" => f.write_str("/ws"),
504 Ws(s) => {
505 let encoded = percent_encoding::percent_encode(s.as_bytes(), PATH_SEGMENT_ENCODE_SET);
506 write!(f, "/x-parity-ws/{}", encoded)
507 },
508 Wss(ref s) if s == "/" => f.write_str("/wss"),
509 Wss(s) => {
510 let encoded = percent_encoding::percent_encode(s.as_bytes(), PATH_SEGMENT_ENCODE_SET);
511 write!(f, "/x-parity-wss/{}", encoded)
512 },
513 }
514 }
515}
516
517impl<'a> From<IpAddr> for Protocol<'a> {
518 #[inline]
519 fn from(addr: IpAddr) -> Self {
520 match addr {
521 IpAddr::V4(addr) => Protocol::Ip4(addr),
522 IpAddr::V6(addr) => Protocol::Ip6(addr),
523 }
524 }
525}
526
527impl<'a> From<Ipv4Addr> for Protocol<'a> {
528 #[inline]
529 fn from(addr: Ipv4Addr) -> Self {
530 Protocol::Ip4(addr)
531 }
532}
533
534impl<'a> From<Ipv6Addr> for Protocol<'a> {
535 #[inline]
536 fn from(addr: Ipv6Addr) -> Self {
537 Protocol::Ip6(addr)
538 }
539}
540
541macro_rules! read_onion_impl {
542 ($name:ident, $len:expr, $encoded_len:expr) => {
543 fn $name(s: &str) -> Result<([u8; $len], u16)> {
544 let mut parts = s.split(':');
545
546 let b32 = parts.next().ok_or(Error::InvalidMultiaddr)?;
548 if b32.len() != $encoded_len {
549 return Err(Error::InvalidMultiaddr)
550 }
551
552 let port = parts.next()
554 .ok_or(Error::InvalidMultiaddr)
555 .and_then(|p| str::parse(p).map_err(From::from))?;
556
557 if port == 0 {
559 return Err(Error::InvalidMultiaddr);
560 }
561
562 if parts.next().is_some() {
564 return Err(Error::InvalidMultiaddr)
565 }
566
567 if $len != BASE32.decode_len(b32.len()).map_err(|_| Error::InvalidMultiaddr)? {
568 return Err(Error::InvalidMultiaddr)
569 }
570
571 let mut buf = [0u8; $len];
572 BASE32.decode_mut(b32.as_bytes(), &mut buf).map_err(|_| Error::InvalidMultiaddr)?;
573
574 Ok((buf, port))
575 }
576 }
577}
578
579read_onion_impl!(read_onion, 10, 16);
583read_onion_impl!(read_onion3, 35, 56);