diff --git a/rust-multiaddr/src/errors.rs b/rust-multiaddr/src/errors.rs index 9fc3e621..b7dd5c73 100644 --- a/rust-multiaddr/src/errors.rs +++ b/rust-multiaddr/src/errors.rs @@ -1,4 +1,4 @@ -use std::{net, fmt, error, io, num}; +use std::{net, fmt, error, io, num, string}; use cid; use byteorder; @@ -69,3 +69,9 @@ impl From for Error { Error::ParsingError(err.into()) } } + +impl From for Error { + fn from(err: string::FromUtf8Error) -> Error { + Error::ParsingError(err.into()) + } +} diff --git a/rust-multiaddr/src/protocol.rs b/rust-multiaddr/src/protocol.rs index 51cb9f9c..ad61015c 100644 --- a/rust-multiaddr/src/protocol.rs +++ b/rust-multiaddr/src/protocol.rs @@ -22,15 +22,21 @@ pub enum ProtocolId { UDP = 17, DCCP = 33, IP6 = 41, + DNS4 = 54, + DNS6 = 55, SCTP = 132, UDT = 301, UTP = 302, + UNIX = 400, + P2P = 420, IPFS = 421, HTTP = 480, HTTPS = 443, ONION = 444, + QUIC = 460, WS = 477, WSS = 478, + Libp2pWebsocketStar = 479, Libp2pWebrtcStar = 275, Libp2pWebrtcDirect = 276, P2pCircuit = 290, @@ -51,24 +57,30 @@ impl From for u64 { impl ToString for ProtocolId { fn to_string(&self) -> String { match *self { - ProtocolId::IP4 => "ip4".to_owned(), - ProtocolId::TCP => "tcp".to_owned(), - ProtocolId::UDP => "udp".to_owned(), - ProtocolId::DCCP => "dccp".to_owned(), - ProtocolId::IP6 => "ip6".to_owned(), - ProtocolId::SCTP => "sctp".to_owned(), - ProtocolId::UDT => "udt".to_owned(), - ProtocolId::UTP => "utp".to_owned(), - ProtocolId::IPFS => "ipfs".to_owned(), - ProtocolId::HTTP => "http".to_owned(), - ProtocolId::HTTPS => "https".to_owned(), - ProtocolId::ONION => "onion".to_owned(), - ProtocolId::WS => "ws".to_owned(), - ProtocolId::WSS => "wss".to_owned(), - ProtocolId::Libp2pWebrtcStar => "libp2p-webrtc-star".to_owned(), - ProtocolId::Libp2pWebrtcDirect => "libp2p-webrtc-direct".to_owned(), - ProtocolId::P2pCircuit => "p2p-circuit".to_owned(), - } + ProtocolId::IP4 => "ip4", + ProtocolId::TCP => "tcp", + ProtocolId::UDP => "udp", + ProtocolId::DCCP => "dccp", + ProtocolId::IP6 => "ip6", + ProtocolId::DNS4 => "dns4", + ProtocolId::DNS6 => "dns6", + ProtocolId::SCTP => "sctp", + ProtocolId::UDT => "udt", + ProtocolId::UTP => "utp", + ProtocolId::UNIX => "unix", + ProtocolId::P2P => "p2p", + ProtocolId::IPFS => "ipfs", + ProtocolId::HTTP => "http", + ProtocolId::HTTPS => "https", + ProtocolId::ONION => "onion", + ProtocolId::QUIC => "quic", + ProtocolId::WS => "ws", + ProtocolId::WSS => "wss", + ProtocolId::Libp2pWebsocketStar => "p2p-websocket-star", + ProtocolId::Libp2pWebrtcStar => "p2p-webrtc-star", + ProtocolId::Libp2pWebrtcDirect => "p2p-webrtc-direct", + ProtocolId::P2pCircuit => "p2p-circuit", + }.to_owned() } } @@ -82,17 +94,23 @@ impl FromStr for ProtocolId { "udp" => Ok(ProtocolId::UDP), "dccp" => Ok(ProtocolId::DCCP), "ip6" => Ok(ProtocolId::IP6), + "dns4" => Ok(ProtocolId::DNS4), + "dns6" => Ok(ProtocolId::DNS6), "sctp" => Ok(ProtocolId::SCTP), "udt" => Ok(ProtocolId::UDT), "utp" => Ok(ProtocolId::UTP), + "unix" => Ok(ProtocolId::UNIX), + "p2p" => Ok(ProtocolId::P2P), "ipfs" => Ok(ProtocolId::IPFS), "http" => Ok(ProtocolId::HTTP), "https" => Ok(ProtocolId::HTTPS), "onion" => Ok(ProtocolId::ONION), + "quic" => Ok(ProtocolId::QUIC), "ws" => Ok(ProtocolId::WS), "wss" => Ok(ProtocolId::WSS), - "libp2p-webrtc-star" => Ok(ProtocolId::Libp2pWebrtcStar), - "libp2p-webrtc-direct" => Ok(ProtocolId::Libp2pWebrtcDirect), + "p2p-websocket-star" => Ok(ProtocolId::Libp2pWebsocketStar), + "p2p-webrtc-star" => Ok(ProtocolId::Libp2pWebrtcStar), + "p2p-webrtc-direct" => Ok(ProtocolId::Libp2pWebrtcDirect), "p2p-circuit" => Ok(ProtocolId::P2pCircuit), _ => Err(Error::UnknownProtocolString), } @@ -118,15 +136,21 @@ impl ProtocolId { 17 => Ok(ProtocolId::UDP), 33 => Ok(ProtocolId::DCCP), 41 => Ok(ProtocolId::IP6), + 54 => Ok(ProtocolId::DNS4), + 55 => Ok(ProtocolId::DNS6), 132 => Ok(ProtocolId::SCTP), 301 => Ok(ProtocolId::UDT), 302 => Ok(ProtocolId::UTP), + 400 => Ok(ProtocolId::UNIX), + 420 => Ok(ProtocolId::P2P), 421 => Ok(ProtocolId::IPFS), 480 => Ok(ProtocolId::HTTP), 443 => Ok(ProtocolId::HTTPS), 444 => Ok(ProtocolId::ONION), + 460 => Ok(ProtocolId::QUIC), 477 => Ok(ProtocolId::WS), 478 => Ok(ProtocolId::WSS), + 479 => Ok(ProtocolId::Libp2pWebsocketStar), 275 => Ok(ProtocolId::Libp2pWebrtcStar), 276 => Ok(ProtocolId::Libp2pWebrtcDirect), 290 => Ok(ProtocolId::P2pCircuit), @@ -152,15 +176,21 @@ impl ProtocolId { ProtocolId::UDP => ProtocolArgSize::Fixed { bytes: 2 }, ProtocolId::DCCP => ProtocolArgSize::Fixed { bytes: 2 }, ProtocolId::IP6 => ProtocolArgSize::Fixed { bytes: 16 }, + ProtocolId::DNS4 => ProtocolArgSize::Variable, + ProtocolId::DNS6 => ProtocolArgSize::Variable, ProtocolId::SCTP => ProtocolArgSize::Fixed { bytes: 2 }, ProtocolId::UDT => ProtocolArgSize::Fixed { bytes: 0 }, ProtocolId::UTP => ProtocolArgSize::Fixed { bytes: 0 }, + ProtocolId::UNIX => ProtocolArgSize::Variable, + ProtocolId::P2P => ProtocolArgSize::Variable, ProtocolId::IPFS => ProtocolArgSize::Variable, ProtocolId::HTTP => ProtocolArgSize::Fixed { bytes: 0 }, ProtocolId::HTTPS => ProtocolArgSize::Fixed { bytes: 0 }, ProtocolId::ONION => ProtocolArgSize::Fixed { bytes: 10 }, + ProtocolId::QUIC => ProtocolArgSize::Fixed { bytes: 0 }, ProtocolId::WS => ProtocolArgSize::Fixed { bytes: 0 }, ProtocolId::WSS => ProtocolArgSize::Fixed { bytes: 0 }, + ProtocolId::Libp2pWebsocketStar => ProtocolArgSize::Fixed { bytes: 0 }, ProtocolId::Libp2pWebrtcStar => ProtocolArgSize::Fixed { bytes: 0 }, ProtocolId::Libp2pWebrtcDirect => ProtocolArgSize::Fixed { bytes: 0 }, ProtocolId::P2pCircuit => ProtocolArgSize::Fixed { bytes: 0 }, @@ -202,6 +232,12 @@ impl ProtocolId { let addr = Ipv6Addr::from_str(a)?; Ok(AddrComponent::IP6(addr)) } + ProtocolId::DNS4 => { + Ok(AddrComponent::DNS4(a.to_owned())) + } + ProtocolId::DNS6 => { + Ok(AddrComponent::DNS6(a.to_owned())) + } ProtocolId::TCP => { let parsed: u16 = a.parse()?; Ok(AddrComponent::TCP(parsed)) @@ -218,17 +254,26 @@ impl ProtocolId { let parsed: u16 = a.parse()?; Ok(AddrComponent::SCTP(parsed)) } + ProtocolId::P2P => { + let bytes = Cid::from(a)?.to_bytes(); + Ok(AddrComponent::P2P(bytes)) + } ProtocolId::IPFS => { let bytes = Cid::from(a)?.to_bytes(); Ok(AddrComponent::IPFS(bytes)) } ProtocolId::ONION => unimplemented!(), // TODO: + ProtocolId::QUIC => Ok(AddrComponent::QUIC), ProtocolId::UTP => Ok(AddrComponent::UTP), + ProtocolId::UNIX => { + Ok(AddrComponent::UNIX(a.to_owned())) + } ProtocolId::UDT => Ok(AddrComponent::UDT), ProtocolId::HTTP => Ok(AddrComponent::HTTP), ProtocolId::HTTPS => Ok(AddrComponent::HTTPS), ProtocolId::WS => Ok(AddrComponent::WS), ProtocolId::WSS => Ok(AddrComponent::WSS), + ProtocolId::Libp2pWebsocketStar => Ok(AddrComponent::Libp2pWebsocketStar), ProtocolId::Libp2pWebrtcStar => Ok(AddrComponent::Libp2pWebrtcStar), ProtocolId::Libp2pWebrtcDirect => Ok(AddrComponent::Libp2pWebrtcDirect), ProtocolId::P2pCircuit => Ok(AddrComponent::P2pCircuit), @@ -243,15 +288,21 @@ pub enum AddrComponent { UDP(u16), DCCP(u16), IP6(Ipv6Addr), + DNS4(String), + DNS6(String), SCTP(u16), UDT, UTP, + UNIX(String), + P2P(Vec), IPFS(Vec), HTTP, HTTPS, ONION(Vec), + QUIC, WS, WSS, + Libp2pWebsocketStar, Libp2pWebrtcStar, Libp2pWebrtcDirect, P2pCircuit, @@ -267,15 +318,21 @@ impl AddrComponent { AddrComponent::UDP(_) => ProtocolId::UDP, AddrComponent::DCCP(_) => ProtocolId::DCCP, AddrComponent::IP6(_) => ProtocolId::IP6, + AddrComponent::DNS4(_) => ProtocolId::DNS4, + AddrComponent::DNS6(_) => ProtocolId::DNS6, AddrComponent::SCTP(_) => ProtocolId::SCTP, AddrComponent::UDT => ProtocolId::UDT, AddrComponent::UTP => ProtocolId::UTP, + AddrComponent::UNIX(_) => ProtocolId::UNIX, + AddrComponent::P2P(_) => ProtocolId::P2P, AddrComponent::IPFS(_) => ProtocolId::IPFS, AddrComponent::HTTP => ProtocolId::HTTP, AddrComponent::HTTPS => ProtocolId::HTTPS, AddrComponent::ONION(_) => ProtocolId::ONION, + AddrComponent::QUIC => ProtocolId::QUIC, AddrComponent::WS => ProtocolId::WS, AddrComponent::WSS => ProtocolId::WSS, + AddrComponent::Libp2pWebsocketStar => ProtocolId::Libp2pWebsocketStar, AddrComponent::Libp2pWebrtcStar => ProtocolId::Libp2pWebrtcStar, AddrComponent::Libp2pWebrtcDirect => ProtocolId::Libp2pWebrtcDirect, AddrComponent::P2pCircuit => ProtocolId::P2pCircuit, @@ -320,6 +377,12 @@ impl AddrComponent { seg[7]); AddrComponent::IP6(addr) } + ProtocolId::DNS4 => { + AddrComponent::DNS4(String::from_utf8(data.to_owned())?) + } + ProtocolId::DNS6 => { + AddrComponent::DNS6(String::from_utf8(data.to_owned())?) + } ProtocolId::TCP => { let mut rdr = Cursor::new(data); let num = rdr.read_u16::()?; @@ -340,17 +403,26 @@ impl AddrComponent { let num = rdr.read_u16::()?; AddrComponent::SCTP(num) } + ProtocolId::UNIX => { + AddrComponent::UNIX(String::from_utf8(data.to_owned())?) + } + ProtocolId::P2P => { + let bytes = Cid::from(data)?.to_bytes(); + AddrComponent::P2P(bytes) + } ProtocolId::IPFS => { let bytes = Cid::from(data)?.to_bytes(); AddrComponent::IPFS(bytes) } ProtocolId::ONION => unimplemented!(), // TODO: + ProtocolId::QUIC => AddrComponent::QUIC, ProtocolId::UTP => AddrComponent::UTP, ProtocolId::UDT => AddrComponent::UDT, ProtocolId::HTTP => AddrComponent::HTTP, ProtocolId::HTTPS => AddrComponent::HTTPS, ProtocolId::WS => AddrComponent::WS, ProtocolId::WSS => AddrComponent::WSS, + ProtocolId::Libp2pWebsocketStar => AddrComponent::Libp2pWebsocketStar, ProtocolId::Libp2pWebrtcStar => AddrComponent::Libp2pWebrtcStar, ProtocolId::Libp2pWebrtcDirect => AddrComponent::Libp2pWebrtcDirect, ProtocolId::P2pCircuit => AddrComponent::P2pCircuit, @@ -376,19 +448,26 @@ impl AddrComponent { AddrComponent::SCTP(port) => { out.write_u16::(port)?; } - AddrComponent::IPFS(bytes) => { + AddrComponent::DNS4(s) | AddrComponent::DNS6(s) | AddrComponent::UNIX(s) => { + let bytes = s.as_bytes(); + out.write_varint(bytes.len())?; + out.write_all(&bytes)?; + } + AddrComponent::P2P(bytes) | AddrComponent::IPFS(bytes) => { out.write_varint(bytes.len())?; out.write_all(&bytes)?; } AddrComponent::ONION(_) => { unimplemented!() // TODO: }, + AddrComponent::QUIC | AddrComponent::UTP | AddrComponent::UDT | AddrComponent::HTTP | AddrComponent::HTTPS | AddrComponent::WS | AddrComponent::WSS | + AddrComponent::Libp2pWebsocketStar | AddrComponent::Libp2pWebrtcStar | AddrComponent::Libp2pWebrtcDirect | AddrComponent::P2pCircuit => {} @@ -406,9 +485,17 @@ impl ToString for AddrComponent { AddrComponent::UDP(port) => format!("/udp/{}", port), AddrComponent::DCCP(port) => format!("/dccp/{}", port), AddrComponent::IP6(ref addr) => format!("/ip6/{}", addr), + AddrComponent::DNS4(ref s) => format!("/dns4/{}", s.clone()), + AddrComponent::DNS6(ref s) => format!("/dns6/{}", s.clone()), AddrComponent::SCTP(port) => format!("/sctp/{}", port), AddrComponent::UDT => format!("/udt"), AddrComponent::UTP => format!("/utp"), + AddrComponent::UNIX(ref s) => format!("/unix/{}", s.clone()), + AddrComponent::P2P(ref bytes) => { + // TODO: meh for cloning + let c = Cid::from(bytes.clone()).expect("cid is known to be valid"); + format!("/p2p/{}", c) + }, AddrComponent::IPFS(ref bytes) => { // TODO: meh for cloning let c = Cid::from(bytes.clone()).expect("cid is known to be valid"); @@ -417,10 +504,12 @@ impl ToString for AddrComponent { AddrComponent::HTTP => format!("/http"), AddrComponent::HTTPS => format!("/https"), AddrComponent::ONION(_) => unimplemented!(),//format!("/onion"), // TODO: + AddrComponent::QUIC => format!("/quic"), AddrComponent::WS => format!("/ws"), AddrComponent::WSS => format!("/wss"), - AddrComponent::Libp2pWebrtcStar => format!("/libp2p-webrtc-star"), - AddrComponent::Libp2pWebrtcDirect => format!("/libp2p-webrtc-direct"), + AddrComponent::Libp2pWebsocketStar => format!("/p2p-websocket-star"), + AddrComponent::Libp2pWebrtcStar => format!("/p2p-webrtc-star"), + AddrComponent::Libp2pWebrtcDirect => format!("/p2p-webrtc-direct"), AddrComponent::P2pCircuit => format!("/p2p-circuit"), } } diff --git a/rust-multiaddr/tests/lib.rs b/rust-multiaddr/tests/lib.rs index fc4604d1..85bc8abe 100644 --- a/rust-multiaddr/tests/lib.rs +++ b/rust-multiaddr/tests/lib.rs @@ -90,7 +90,7 @@ fn construct_success() { "29200108A07AC542013AC986FFFE317095061F40DD03A5\ 03221220D52EBB89D85B02A284948203A62FF28389C57C9F42BEEC4EC20DB76A68911C0B", vec![IP6, TCP, WS, IPFS]); - ma_valid("/libp2p-webrtc-star/ip4/127.0.0.\ + ma_valid("/p2p-webrtc-star/ip4/127.0.0.\ 1/tcp/9090/ws/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC", "9302047F000001062382DD03A503221220D52EBB89D85B\ 02A284948203A62FF28389C57C9F42BEEC4EC20DB76A68911C0B",