multiaddr/
lib.rs

1//! Implementation of [multiaddr](https://github.com/multiformats/multiaddr) in Rust.
2
3pub use multihash;
4
5mod errors;
6mod onion_addr;
7mod protocol;
8
9#[cfg(feature = "url")]
10mod from_url;
11
12pub use self::errors::{Error, Result};
13pub use self::onion_addr::Onion3Addr;
14pub use self::protocol::Protocol;
15use scionnet::ScionAddr;
16use serde::{
17    de::{self, Error as DeserializerError},
18    Deserialize, Deserializer, Serialize, Serializer,
19};
20use std::{
21    convert::TryFrom,
22    fmt, io,
23    iter::FromIterator,
24    net::{IpAddr, Ipv4Addr, Ipv6Addr},
25    result::Result as StdResult,
26    str::FromStr,
27    sync::Arc,
28};
29
30use libp2p_identity::PeerId;
31
32#[cfg(feature = "url")]
33pub use self::from_url::{from_url, from_url_lossy, FromUrlErr};
34
35static_assertions::const_assert! {
36    // This check is most certainly overkill right now, but done here
37    // anyway to ensure the `as u64` casts in this crate are safe.
38    std::mem::size_of::<usize>() <= std::mem::size_of::<u64>()
39}
40
41/// Representation of a Multiaddr.
42#[allow(clippy::rc_buffer)]
43#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
44pub struct Multiaddr {
45    bytes: Arc<Vec<u8>>,
46}
47
48impl Multiaddr {
49    /// Create a new, empty multiaddress.
50    pub fn empty() -> Self {
51        Self {
52            bytes: Arc::new(Vec::new()),
53        }
54    }
55
56    /// Create a new, empty multiaddress with the given capacity.
57    pub fn with_capacity(n: usize) -> Self {
58        Self {
59            bytes: Arc::new(Vec::with_capacity(n)),
60        }
61    }
62
63    /// Return the length in bytes of this multiaddress.
64    pub fn len(&self) -> usize {
65        self.bytes.len()
66    }
67
68    /// Returns true if the length of this multiaddress is 0.
69    pub fn is_empty(&self) -> bool {
70        self.bytes.len() == 0
71    }
72
73    /// Return a copy of this [`Multiaddr`]'s byte representation.
74    pub fn to_vec(&self) -> Vec<u8> {
75        Vec::from(&self.bytes[..])
76    }
77
78    /// Adds an already-parsed address component to the end of this multiaddr.
79    ///
80    /// # Examples
81    ///
82    /// ```
83    /// use multiaddr::{Multiaddr, Protocol};
84    ///
85    /// let mut address: Multiaddr = "/ip4/127.0.0.1".parse().unwrap();
86    /// address.push(Protocol::Tcp(10000));
87    /// assert_eq!(address, "/ip4/127.0.0.1/tcp/10000".parse().unwrap());
88    /// ```
89    ///
90    pub fn push(&mut self, p: Protocol<'_>) {
91        let mut w = io::Cursor::<&mut Vec<u8>>::new(Arc::make_mut(&mut self.bytes));
92        w.set_position(w.get_ref().len() as u64);
93        p.write_bytes(&mut w)
94            .expect("Writing to a `io::Cursor<&mut Vec<u8>>` never fails.")
95    }
96
97    /// Pops the last `Protocol` of this multiaddr, or `None` if the multiaddr is empty.
98    /// ```
99    /// use multiaddr::{Multiaddr, Protocol};
100    ///
101    /// let mut address: Multiaddr = "/ip4/127.0.0.1/udt/sctp/5678".parse().unwrap();
102    ///
103    /// assert_eq!(address.pop().unwrap(), Protocol::Sctp(5678));
104    /// assert_eq!(address.pop().unwrap(), Protocol::Udt);
105    /// ```
106    ///
107    pub fn pop<'a>(&mut self) -> Option<Protocol<'a>> {
108        let mut slice = &self.bytes[..]; // the remaining multiaddr slice
109        if slice.is_empty() {
110            return None;
111        }
112        let protocol = loop {
113            let (p, s) = Protocol::from_bytes(slice).expect("`slice` is a valid `Protocol`.");
114            if s.is_empty() {
115                break p.acquire();
116            }
117            slice = s
118        };
119        let remaining_len = self.bytes.len() - slice.len();
120        Arc::make_mut(&mut self.bytes).truncate(remaining_len);
121        Some(protocol)
122    }
123
124    /// Like [`Multiaddr::push`] but consumes `self`.
125    pub fn with(mut self, p: Protocol<'_>) -> Self {
126        let mut w = io::Cursor::<&mut Vec<u8>>::new(Arc::make_mut(&mut self.bytes));
127        w.set_position(w.get_ref().len() as u64);
128        p.write_bytes(&mut w)
129            .expect("Writing to a `io::Cursor<&mut Vec<u8>>` never fails.");
130        self
131    }
132
133    /// Appends the given [`PeerId`] if not yet present at the end of this multiaddress.
134    ///
135    /// Fails if this address ends in a _different_ [`PeerId`].
136    /// In that case, the original, unmodified address is returned.
137    pub fn with_p2p(self, peer: PeerId) -> std::result::Result<Self, Self> {
138        match self.iter().last() {
139            Some(Protocol::P2p(p)) if p == peer => Ok(self),
140            Some(Protocol::P2p(_)) => Err(self),
141            _ => Ok(self.with(Protocol::P2p(peer))),
142        }
143    }
144
145    /// Returns the components of this multiaddress.
146    ///
147    /// # Example
148    ///
149    /// ```rust
150    /// use std::net::Ipv4Addr;
151    /// use multiaddr::{Multiaddr, Protocol};
152    ///
153    /// let address: Multiaddr = "/ip4/127.0.0.1/udt/sctp/5678".parse().unwrap();
154    ///
155    /// let components = address.iter().collect::<Vec<_>>();
156    /// assert_eq!(components[0], Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1)));
157    /// assert_eq!(components[1], Protocol::Udt);
158    /// assert_eq!(components[2], Protocol::Sctp(5678));
159    /// ```
160    ///
161    pub fn iter(&self) -> Iter<'_> {
162        Iter(&self.bytes)
163    }
164
165    /// Replace a [`Protocol`] at some position in this `Multiaddr`.
166    ///
167    /// The parameter `at` denotes the index of the protocol at which the function
168    /// `by` will be applied to the current protocol, returning an optional replacement.
169    ///
170    /// If `at` is out of bounds or `by` does not yield a replacement value,
171    /// `None` will be returned. Otherwise a copy of this `Multiaddr` with the
172    /// updated `Protocol` at position `at` will be returned.
173    pub fn replace<'a, F>(&self, at: usize, by: F) -> Option<Multiaddr>
174    where
175        F: FnOnce(&Protocol<'_>) -> Option<Protocol<'a>>,
176    {
177        let mut address = Multiaddr::with_capacity(self.len());
178        let mut fun = Some(by);
179        let mut replaced = false;
180
181        for (i, p) in self.iter().enumerate() {
182            if i == at {
183                let f = fun.take().expect("i == at only happens once");
184                if let Some(q) = f(&p) {
185                    address = address.with(q);
186                    replaced = true;
187                    continue;
188                }
189                return None;
190            }
191            address = address.with(p)
192        }
193
194        if replaced {
195            Some(address)
196        } else {
197            None
198        }
199    }
200
201    /// Checks whether the given `Multiaddr` is a suffix of this `Multiaddr`.
202    pub fn ends_with(&self, other: &Multiaddr) -> bool {
203        let n = self.bytes.len();
204        let m = other.bytes.len();
205        if n < m {
206            return false;
207        }
208        self.bytes[(n - m)..] == other.bytes[..]
209    }
210
211    /// Returns &str identifiers for the protocol names themselves.
212    /// This omits specific info like addresses, ports, peer IDs, and the like.
213    /// Example: `"/ip4/127.0.0.1/tcp/5001"` would return `["ip4", "tcp"]`  
214    pub fn protocol_stack(&self) -> ProtoStackIter {
215        ProtoStackIter { parts: self.iter() }
216    }
217}
218
219impl fmt::Debug for Multiaddr {
220    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221        fmt::Display::fmt(self, f)
222    }
223}
224
225impl fmt::Display for Multiaddr {
226    /// Convert a Multiaddr to a string
227    ///
228    /// # Example
229    ///
230    /// ```
231    /// use multiaddr::Multiaddr;
232    ///
233    /// let address: Multiaddr = "/ip4/127.0.0.1/udt".parse().unwrap();
234    /// assert_eq!(address.to_string(), "/ip4/127.0.0.1/udt");
235    /// ```
236    ///
237    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
238        for s in self.iter() {
239            s.fmt(f)?;
240        }
241        Ok(())
242    }
243}
244
245impl AsRef<[u8]> for Multiaddr {
246    fn as_ref(&self) -> &[u8] {
247        self.bytes.as_ref()
248    }
249}
250
251impl<'a> IntoIterator for &'a Multiaddr {
252    type Item = Protocol<'a>;
253    type IntoIter = Iter<'a>;
254
255    fn into_iter(self) -> Iter<'a> {
256        Iter(&self.bytes)
257    }
258}
259
260impl<'a> FromIterator<Protocol<'a>> for Multiaddr {
261    fn from_iter<T>(iter: T) -> Self
262    where
263        T: IntoIterator<Item = Protocol<'a>>,
264    {
265        let mut writer = Vec::new();
266        for cmp in iter {
267            cmp.write_bytes(&mut writer)
268                .expect("Writing to a `Vec` never fails.");
269        }
270        Multiaddr {
271            bytes: Arc::new(writer),
272        }
273    }
274}
275
276impl FromStr for Multiaddr {
277    type Err = Error;
278
279    fn from_str(input: &str) -> Result<Self> {
280        let mut writer = Vec::new();
281        let mut parts = input.split('/').peekable();
282
283        if Some("") != parts.next() {
284            // A multiaddr must start with `/`
285            return Err(Error::InvalidMultiaddr);
286        }
287
288        while parts.peek().is_some() {
289            let p = Protocol::from_str_parts(&mut parts)?;
290            p.write_bytes(&mut writer)
291                .expect("Writing to a `Vec` never fails.");
292        }
293
294        Ok(Multiaddr {
295            bytes: Arc::new(writer),
296        })
297    }
298}
299
300/// Iterator over `Multiaddr` [`Protocol`]s.
301pub struct Iter<'a>(&'a [u8]);
302
303impl<'a> Iterator for Iter<'a> {
304    type Item = Protocol<'a>;
305
306    fn next(&mut self) -> Option<Self::Item> {
307        if self.0.is_empty() {
308            return None;
309        }
310
311        let (p, next_data) =
312            Protocol::from_bytes(self.0).expect("`Multiaddr` is known to be valid.");
313
314        self.0 = next_data;
315        Some(p)
316    }
317}
318
319/// Iterator over the string idtenfiers of the protocols (not addrs) in a multiaddr
320pub struct ProtoStackIter<'a> {
321    parts: Iter<'a>,
322}
323
324impl<'a> Iterator for ProtoStackIter<'a> {
325    type Item = &'static str;
326    fn next(&mut self) -> Option<Self::Item> {
327        self.parts.next().as_ref().map(Protocol::tag)
328    }
329}
330
331impl<'a> From<Protocol<'a>> for Multiaddr {
332    fn from(p: Protocol<'a>) -> Multiaddr {
333        let mut w = Vec::new();
334        p.write_bytes(&mut w)
335            .expect("Writing to a `Vec` never fails.");
336        Multiaddr { bytes: Arc::new(w) }
337    }
338}
339
340impl From<IpAddr> for Multiaddr {
341    fn from(v: IpAddr) -> Multiaddr {
342        match v {
343            IpAddr::V4(a) => a.into(),
344            IpAddr::V6(a) => a.into(),
345        }
346    }
347}
348
349impl From<ScionAddr> for Multiaddr {
350    fn from(v: ScionAddr ) ->Multiaddr
351    {
352        <Protocol as From<ScionAddr>>::from(v).into()
353    }
354}
355
356impl From<Ipv4Addr> for Multiaddr {
357    fn from(v: Ipv4Addr) -> Multiaddr {
358        Protocol::Ip4(v).into()
359    }
360}
361
362impl From<Ipv6Addr> for Multiaddr {
363    fn from(v: Ipv6Addr) -> Multiaddr {
364        Protocol::Ip6(v).into()
365    }
366}
367
368
369impl From<scionnet::Ipv4Addr> for Multiaddr {
370    fn from(v: scionnet::Ipv4Addr) -> Multiaddr {
371        Protocol::Ip4(v.into()).into()
372    }
373}
374
375impl From<scionnet::Ipv6Addr> for Multiaddr {
376    fn from(v: scionnet::Ipv6Addr) -> Multiaddr {
377        Protocol::Ip6(v.into()).into()
378    }
379}
380
381impl From<scionnet::SocketAddr> for Multiaddr {
382    fn from(addr: scionnet::SocketAddr) -> Multiaddr {          
383         
384            match addr {
385                scionnet::SocketAddr::V4(a) =>{ 
386                    let l3proto:Protocol =  (*a.ip()).into() ;
387                    let ma: Multiaddr = l3proto.into();
388                    return ma.with(Protocol::Tcp(a.port()))
389                },
390                scionnet::SocketAddr::V6(a) =>
391                {
392                    let l3proto:Protocol  = (*a.ip()).into() ;
393                    let ma: Multiaddr = l3proto.into();
394                    return ma.with(Protocol::Tcp(a.port()))
395                },
396                scionnet::SocketAddr::SCION(s) =>{
397                    let l3proto:Protocol = (<scionnet::SocketAddrScion as Into<ScionAddr>>::into(s) ).into();
398                    let ma: Multiaddr = l3proto.into();
399                  return  ma.with(Protocol::Udp(s.port()))
400                }
401            }
402        }
403    
404}
405
406impl TryFrom<Vec<u8>> for Multiaddr {
407    type Error = Error;
408
409    fn try_from(v: Vec<u8>) -> Result<Self> {
410        // Check if the argument is a valid `Multiaddr` by reading its protocols.
411        let mut slice = &v[..];
412        while !slice.is_empty() {
413            let (_, s) = Protocol::from_bytes(slice)?;
414            slice = s
415        }
416        Ok(Multiaddr { bytes: Arc::new(v) })
417    }
418}
419
420impl TryFrom<String> for Multiaddr {
421    type Error = Error;
422
423    fn try_from(s: String) -> Result<Multiaddr> {
424        s.parse()
425    }
426}
427
428impl<'a> TryFrom<&'a str> for Multiaddr {
429    type Error = Error;
430
431    fn try_from(s: &'a str) -> Result<Multiaddr> {
432        s.parse()
433    }
434}
435
436impl Serialize for Multiaddr {
437    fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
438    where
439        S: Serializer,
440    {
441        if serializer.is_human_readable() {
442            serializer.serialize_str(&self.to_string())
443        } else {
444            serializer.serialize_bytes(self.as_ref())
445        }
446    }
447}
448
449impl<'de> Deserialize<'de> for Multiaddr {
450    fn deserialize<D>(deserializer: D) -> StdResult<Self, D::Error>
451    where
452        D: Deserializer<'de>,
453    {
454        struct Visitor {
455            is_human_readable: bool,
456        }
457
458        impl<'de> de::Visitor<'de> for Visitor {
459            type Value = Multiaddr;
460
461            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
462                formatter.write_str("multiaddress")
463            }
464            fn visit_seq<A: de::SeqAccess<'de>>(
465                self,
466                mut seq: A,
467            ) -> StdResult<Self::Value, A::Error> {
468                let mut buf: Vec<u8> =
469                    Vec::with_capacity(std::cmp::min(seq.size_hint().unwrap_or(0), 4096));
470                while let Some(e) = seq.next_element()? {
471                    buf.push(e);
472                }
473                if self.is_human_readable {
474                    let s = String::from_utf8(buf).map_err(DeserializerError::custom)?;
475                    s.parse().map_err(DeserializerError::custom)
476                } else {
477                    Multiaddr::try_from(buf).map_err(DeserializerError::custom)
478                }
479            }
480            fn visit_str<E: de::Error>(self, v: &str) -> StdResult<Self::Value, E> {
481                v.parse().map_err(DeserializerError::custom)
482            }
483            fn visit_borrowed_str<E: de::Error>(self, v: &'de str) -> StdResult<Self::Value, E> {
484                self.visit_str(v)
485            }
486            fn visit_string<E: de::Error>(self, v: String) -> StdResult<Self::Value, E> {
487                self.visit_str(&v)
488            }
489            fn visit_bytes<E: de::Error>(self, v: &[u8]) -> StdResult<Self::Value, E> {
490                self.visit_byte_buf(v.into())
491            }
492            fn visit_borrowed_bytes<E: de::Error>(self, v: &'de [u8]) -> StdResult<Self::Value, E> {
493                self.visit_byte_buf(v.into())
494            }
495            fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> StdResult<Self::Value, E> {
496                Multiaddr::try_from(v).map_err(DeserializerError::custom)
497            }
498        }
499
500        if deserializer.is_human_readable() {
501            deserializer.deserialize_str(Visitor {
502                is_human_readable: true,
503            })
504        } else {
505            deserializer.deserialize_bytes(Visitor {
506                is_human_readable: false,
507            })
508        }
509    }
510}
511
512/// Easy way for a user to create a `Multiaddr`.
513///
514/// Example:
515///
516/// ```rust
517/// # use multiaddr::multiaddr;
518/// let addr = multiaddr!(Ip4([127, 0, 0, 1]), Tcp(10500u16));
519/// ```
520///
521/// Each element passed to `multiaddr!` should be a variant of the `Protocol` enum. The
522/// optional parameter is turned into the proper type with the `Into` trait.
523///
524/// For example, `Ip4([127, 0, 0, 1])` works because `Ipv4Addr` implements `From<[u8; 4]>`.
525#[macro_export]
526macro_rules! multiaddr {
527    ($($comp:ident $(($param:expr))*),+) => {
528        {
529            use std::iter;
530            let elem = iter::empty::<$crate::Protocol>();
531            $(
532                let elem = {
533                    let cmp = $crate::Protocol::$comp $(( $param.into() ))*;
534                    elem.chain(iter::once(cmp))
535                };
536            )+
537            elem.collect::<$crate::Multiaddr>()
538        }
539    }
540}