///! # multiaddr ///! ///! Implementation of [multiaddr](https://github.com/jbenet/multiaddr) ///! in Rust. extern crate byteorder; extern crate cid; extern crate integer_encoding; mod protocol; mod errors; pub use errors::{Result, Error}; pub use protocol::{ProtocolId, ProtocolArgSize, AddrComponent}; use std::fmt; use std::iter::FromIterator; use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6, IpAddr, Ipv4Addr, Ipv6Addr}; use std::str::FromStr; /// Representation of a Multiaddr. #[derive(PartialEq, Eq, Clone, Hash)] pub struct Multiaddr { bytes: Vec, } impl ToString for Multiaddr { /// Convert a Multiaddr to a string /// /// # Examples /// /// ``` /// use multiaddr::Multiaddr; /// /// let address = Multiaddr::new("/ip4/127.0.0.1/udt").unwrap(); /// assert_eq!(address.to_string(), "/ip4/127.0.0.1/udt"); /// ``` /// fn to_string(&self) -> String { let mut out = String::new(); for s in self.iter() { out.push_str(&s.to_string()); } out } } impl fmt::Debug for Multiaddr { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.to_string().fmt(f) } } impl Multiaddr { /// Create a new multiaddr based on a string representation, like /// `/ip4/127.0.0.1/udp/1234`. /// /// # Examples /// /// Simple construction /// /// ``` /// use multiaddr::Multiaddr; /// /// let address = Multiaddr::new("/ip4/127.0.0.1/udp/1234").unwrap(); /// assert_eq!(address.to_bytes(), [ /// 4, 127, 0, 0, 1, /// 17, 4, 210 /// ]); /// ``` /// pub fn new(input: &str) -> Result { let mut bytes = Vec::new(); let mut parts = input.split('/'); if !parts.next().ok_or(Error::InvalidMultiaddr)?.is_empty() { return Err(Error::InvalidMultiaddr); } while let Some(part) = parts.next() { let protocol: ProtocolId = part.parse()?; let addr_component = match protocol.size() { ProtocolArgSize::Fixed { bytes: 0 } => { protocol.parse_data("")? // TODO: bad design }, _ => { let data = parts.next().ok_or(Error::MissingAddress)?; protocol.parse_data(data)? }, }; addr_component.write_bytes(&mut bytes).expect("writing to a Vec never fails"); } Ok(Multiaddr { bytes: bytes }) } /// Return a copy to disallow changing the bytes directly pub fn to_bytes(&self) -> Vec { self.bytes.to_owned() } /// Extracts a slice containing the entire underlying vector. pub fn as_slice(&self) -> &[u8] { &self.bytes } /// Return a list of protocols /// /// # Examples /// /// A single protocol /// /// ``` /// use multiaddr::{Multiaddr, ProtocolId}; /// /// let address = Multiaddr::new("/ip4/127.0.0.1").unwrap(); /// assert_eq!(address.protocol(), vec![ProtocolId::IP4]); /// ``` /// #[inline] pub fn protocol(&self) -> Vec { self.iter().map(|addr| addr.protocol_id()).collect() } /// Wrap a given Multiaddr and return the combination. /// /// # Examples /// /// ``` /// use multiaddr::Multiaddr; /// /// let address = Multiaddr::new("/ip4/127.0.0.1").unwrap(); /// let nested = address.encapsulate("/udt").unwrap(); /// assert_eq!(nested, Multiaddr::new("/ip4/127.0.0.1/udt").unwrap()); /// ``` /// pub fn encapsulate(&self, input: T) -> Result { let new = input.to_multiaddr()?; let mut bytes = self.bytes.clone(); bytes.extend(new.to_bytes()); Ok(Multiaddr { bytes: bytes }) } /// Remove the outer most address from itself. /// /// # Examples /// /// ``` /// use multiaddr::{Multiaddr, ToMultiaddr}; /// /// let address = Multiaddr::new("/ip4/127.0.0.1/udt/sctp/5678").unwrap(); /// let unwrapped = address.decapsulate("/udt").unwrap(); /// assert_eq!(unwrapped, Multiaddr::new("/ip4/127.0.0.1").unwrap()); /// /// assert_eq!( /// address.decapsulate("/udt").unwrap(), /// "/ip4/127.0.0.1".to_multiaddr().unwrap() /// ); /// ``` /// /// Returns the original if the passed in address is not found /// /// ``` /// use multiaddr::ToMultiaddr; /// /// let address = "/ip4/127.0.0.1/udt/sctp/5678".to_multiaddr().unwrap(); /// let unwrapped = address.decapsulate("/ip4/127.0.1.1").unwrap(); /// assert_eq!(unwrapped, address); /// ``` /// pub fn decapsulate(&self, input: T) -> Result { let input = input.to_multiaddr()?.to_bytes(); let bytes_len = self.bytes.len(); let input_length = input.len(); let mut input_pos = 0; let mut matches = false; for (i, _) in self.bytes.iter().enumerate() { let next = i + input_length; if next > bytes_len { continue; } if &self.bytes[i..next] == input.as_slice() { matches = true; input_pos = i; break; } } if !matches { return Ok(Multiaddr { bytes: self.bytes.clone() }); } let mut bytes = self.bytes.clone(); bytes.truncate(input_pos); Ok(Multiaddr { bytes: bytes }) } /// Returns the components of this multiaddress. /// /// ``` /// use std::net::Ipv4Addr; /// use multiaddr::AddrComponent; /// use multiaddr::Multiaddr; /// /// let address: Multiaddr = "/ip4/127.0.0.1/udt/sctp/5678".parse().unwrap(); /// /// let components = address.iter().collect::>(); /// assert_eq!(components[0], AddrComponent::IP4(Ipv4Addr::new(127, 0, 0, 1))); /// assert_eq!(components[1], AddrComponent::UDT); /// assert_eq!(components[2], AddrComponent::SCTP(5678)); /// ``` /// #[inline] pub fn iter(&self) -> Iter { Iter(&self.bytes) } /// Pops the last `AddrComponent` of this multiaddr, or `None` if the multiaddr is empty. /// ``` /// use multiaddr::AddrComponent; /// use multiaddr::Multiaddr; /// /// let address: Multiaddr = "/ip4/127.0.0.1/udt/sctp/5678".parse().unwrap(); /// /// assert_eq!(address.pop().unwrap(), AddrComponent::SCTP(5678)); /// assert_eq!(address.pop().unwrap(), AddrComponent::UDT); /// ``` /// pub fn pop(&mut self) -> Option { // Note: could be more optimized let mut list = self.iter().collect::>(); let last_elem = list.pop(); *self = list.into_iter().collect(); last_elem } } impl From for Multiaddr { fn from(addr: AddrComponent) -> Multiaddr { let mut out = Vec::new(); addr.write_bytes(&mut out).expect("writing to a Vec never fails"); Multiaddr { bytes: out } } } impl FromIterator for Multiaddr { fn from_iter(iter: T) -> Self where T: IntoIterator { let mut bytes = Vec::new(); for cmp in iter { cmp.write_bytes(&mut bytes).expect("writing to a Vec never fails"); } Multiaddr { bytes: bytes } } } impl FromStr for Multiaddr { type Err = Error; #[inline] fn from_str(s: &str) -> Result { Multiaddr::new(s) } } /// Iterator for the address components in a multiaddr. pub struct Iter<'a>(&'a [u8]); impl<'a> Iterator for Iter<'a> { type Item = AddrComponent; fn next(&mut self) -> Option { if self.0.is_empty() { return None; } let (component, next_data) = AddrComponent::from_bytes(self.0) .expect("multiaddr is known to be valid"); self.0 = next_data; Some(component) } } /// A trait for objects which can be converted to a /// Multiaddr. /// /// This trait is implemented by default for /// /// * `SocketAddr`, `SocketAddrV4` and `SocketAddrV6`, assuming that the /// the given port is a tcp port. /// /// * `Ipv4Addr`, `Ipv6Addr` /// /// * `String` and `&str`, requiring the default string format for a Multiaddr. /// pub trait ToMultiaddr { /// Converts this object to a Multiaddr /// /// # Errors /// /// Any errors encountered during parsing will be returned /// as an `Err`. fn to_multiaddr(&self) -> Result; } impl ToMultiaddr for SocketAddr { fn to_multiaddr(&self) -> Result { match *self { SocketAddr::V4(ref a) => (*a).to_multiaddr(), SocketAddr::V6(ref a) => (*a).to_multiaddr(), } } } impl ToMultiaddr for SocketAddrV4 { fn to_multiaddr(&self) -> Result { Multiaddr::new(&format!("/ip4/{}/tcp/{}", self.ip(), self.port())) } } impl ToMultiaddr for SocketAddrV6 { fn to_multiaddr(&self) -> Result { // TODO: Should how should we handle `flowinfo` and `scope_id`? Multiaddr::new(&format!("/ip6/{}/tcp/{}", self.ip(), self.port())) } } impl ToMultiaddr for IpAddr { fn to_multiaddr(&self) -> Result { match *self { IpAddr::V4(ref a) => (*a).to_multiaddr(), IpAddr::V6(ref a) => (*a).to_multiaddr(), } } } impl ToMultiaddr for Ipv4Addr { fn to_multiaddr(&self) -> Result { Multiaddr::new(&format!("/ip4/{}", &self)) } } impl ToMultiaddr for Ipv6Addr { fn to_multiaddr(&self) -> Result { Multiaddr::new(&format!("/ip6/{}", &self)) } } impl ToMultiaddr for String { fn to_multiaddr(&self) -> Result { Multiaddr::new(self) } } impl<'a> ToMultiaddr for &'a str { fn to_multiaddr(&self) -> Result { Multiaddr::new(self) } } impl ToMultiaddr for Multiaddr { fn to_multiaddr(&self) -> Result { Ok(self.clone()) } }