rtc_stun/
addr.rs

1#[cfg(test)]
2mod addr_test;
3
4use crate::attributes::*;
5use crate::message::*;
6use shared::error::*;
7
8use std::fmt;
9use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
10
11pub(crate) const FAMILY_IPV4: u16 = 0x01;
12pub(crate) const FAMILY_IPV6: u16 = 0x02;
13pub(crate) const IPV4LEN: usize = 4;
14pub(crate) const IPV6LEN: usize = 16;
15
16/// MappedAddress represents MAPPED-ADDRESS attribute.
17///
18/// This attribute is used only by servers for achieving backwards
19/// compatibility with RFC 3489 clients.
20///
21/// RFC 5389 Section 15.1
22pub struct MappedAddress {
23    pub ip: IpAddr,
24    pub port: u16,
25}
26
27impl fmt::Display for MappedAddress {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        match self.ip {
30            IpAddr::V4(ipv4) => write!(f, "{}:{}", ipv4, self.port),
31            IpAddr::V6(ipv6) => write!(f, "[{}]:{}", ipv6, self.port),
32        }
33    }
34}
35
36impl Default for MappedAddress {
37    fn default() -> Self {
38        MappedAddress {
39            ip: IpAddr::V4(Ipv4Addr::from(0)),
40            port: 0,
41        }
42    }
43}
44
45impl Setter for MappedAddress {
46    /// add_to adds MAPPED-ADDRESS to message.
47    fn add_to(&self, m: &mut Message) -> Result<()> {
48        self.add_to_as(m, ATTR_MAPPED_ADDRESS)
49    }
50}
51
52impl Getter for MappedAddress {
53    /// get_from decodes MAPPED-ADDRESS from message.
54    fn get_from(&mut self, m: &Message) -> Result<()> {
55        self.get_from_as(m, ATTR_MAPPED_ADDRESS)
56    }
57}
58
59impl MappedAddress {
60    /// get_from_as decodes MAPPED-ADDRESS value in message m as an attribute of type t.
61    pub fn get_from_as(&mut self, m: &Message, t: AttrType) -> Result<()> {
62        let v = m.get(t)?;
63        if v.len() <= 4 {
64            return Err(Error::ErrUnexpectedEof);
65        }
66
67        let family = u16::from_be_bytes([v[0], v[1]]);
68        if family != FAMILY_IPV6 && family != FAMILY_IPV4 {
69            return Err(Error::Other(format!("bad value {family}")));
70        }
71        self.port = u16::from_be_bytes([v[2], v[3]]);
72
73        if family == FAMILY_IPV6 {
74            let mut ip = [0; IPV6LEN];
75            let l = std::cmp::min(ip.len(), v[4..].len());
76            ip[..l].copy_from_slice(&v[4..4 + l]);
77            self.ip = IpAddr::V6(Ipv6Addr::from(ip));
78        } else {
79            let mut ip = [0; IPV4LEN];
80            let l = std::cmp::min(ip.len(), v[4..].len());
81            ip[..l].copy_from_slice(&v[4..4 + l]);
82            self.ip = IpAddr::V4(Ipv4Addr::from(ip));
83        };
84
85        Ok(())
86    }
87
88    /// add_to_as adds MAPPED-ADDRESS value to m as t attribute.
89    pub fn add_to_as(&self, m: &mut Message, t: AttrType) -> Result<()> {
90        let family = match self.ip {
91            IpAddr::V4(_) => FAMILY_IPV4,
92            IpAddr::V6(_) => FAMILY_IPV6,
93        };
94
95        let mut value = vec![0u8; 4];
96        //value[0] = 0 // first 8 bits are zeroes
97        value[0..2].copy_from_slice(&family.to_be_bytes());
98        value[2..4].copy_from_slice(&self.port.to_be_bytes());
99
100        match self.ip {
101            IpAddr::V4(ipv4) => value.extend_from_slice(&ipv4.octets()),
102            IpAddr::V6(ipv6) => value.extend_from_slice(&ipv6.octets()),
103        };
104
105        m.add(t, &value);
106        Ok(())
107    }
108}
109
110/// AlternateServer represents ALTERNATE-SERVER attribute.
111///
112/// RFC 5389 Section 15.11
113pub type AlternateServer = MappedAddress;
114
115/// ResponseOrigin represents RESPONSE-ORIGIN attribute.
116///
117/// RFC 5780 Section 7.3
118pub type ResponseOrigin = MappedAddress;
119
120/// OtherAddress represents OTHER-ADDRESS attribute.
121///
122/// RFC 5780 Section 7.4
123pub type OtherAddress = MappedAddress;