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        let family = match self.ip {
30            IpAddr::V4(_) => FAMILY_IPV4,
31            IpAddr::V6(_) => FAMILY_IPV6,
32        };
33        if family == FAMILY_IPV4 {
34            write!(f, "{}:{}", self.ip, self.port)
35        } else {
36            write!(f, "[{}]:{}", self.ip, self.port)
37        }
38    }
39}
40
41impl Default for MappedAddress {
42    fn default() -> Self {
43        MappedAddress {
44            ip: IpAddr::V4(Ipv4Addr::from(0)),
45            port: 0,
46        }
47    }
48}
49
50impl Setter for MappedAddress {
51    /// add_to adds MAPPED-ADDRESS to message.
52    fn add_to(&self, m: &mut Message) -> Result<()> {
53        self.add_to_as(m, ATTR_MAPPED_ADDRESS)
54    }
55}
56
57impl Getter for MappedAddress {
58    /// get_from decodes MAPPED-ADDRESS from message.
59    fn get_from(&mut self, m: &Message) -> Result<()> {
60        self.get_from_as(m, ATTR_MAPPED_ADDRESS)
61    }
62}
63
64impl MappedAddress {
65    /// get_from_as decodes MAPPED-ADDRESS value in message m as an attribute of type t.
66    pub fn get_from_as(&mut self, m: &Message, t: AttrType) -> Result<()> {
67        let v = m.get(t)?;
68        if v.len() <= 4 {
69            return Err(Error::ErrUnexpectedEof);
70        }
71
72        let family = u16::from_be_bytes([v[0], v[1]]);
73        if family != FAMILY_IPV6 && family != FAMILY_IPV4 {
74            return Err(Error::Other(format!("bad value {family}")));
75        }
76        self.port = u16::from_be_bytes([v[2], v[3]]);
77
78        if family == FAMILY_IPV6 {
79            let mut ip = [0; IPV6LEN];
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::V6(Ipv6Addr::from(ip));
83        } else {
84            let mut ip = [0; IPV4LEN];
85            let l = std::cmp::min(ip.len(), v[4..].len());
86            ip[..l].copy_from_slice(&v[4..4 + l]);
87            self.ip = IpAddr::V4(Ipv4Addr::from(ip));
88        };
89
90        Ok(())
91    }
92
93    /// add_to_as adds MAPPED-ADDRESS value to m as t attribute.
94    pub fn add_to_as(&self, m: &mut Message, t: AttrType) -> Result<()> {
95        let family = match self.ip {
96            IpAddr::V4(_) => FAMILY_IPV4,
97            IpAddr::V6(_) => FAMILY_IPV6,
98        };
99
100        let mut value = vec![0u8; 4];
101        //value[0] = 0 // first 8 bits are zeroes
102        value[0..2].copy_from_slice(&family.to_be_bytes());
103        value[2..4].copy_from_slice(&self.port.to_be_bytes());
104
105        match self.ip {
106            IpAddr::V4(ipv4) => value.extend_from_slice(&ipv4.octets()),
107            IpAddr::V6(ipv6) => value.extend_from_slice(&ipv6.octets()),
108        };
109
110        m.add(t, &value);
111        Ok(())
112    }
113}
114
115/// AlternateServer represents ALTERNATE-SERVER attribute.
116///
117/// RFC 5389 Section 15.11
118pub type AlternateServer = MappedAddress;
119
120/// ResponseOrigin represents RESPONSE-ORIGIN attribute.
121///
122/// RFC 5780 Section 7.3
123pub type ResponseOrigin = MappedAddress;
124
125/// OtherAddress represents OTHER-ADDRESS attribute.
126///
127/// RFC 5780 Section 7.4
128pub type OtherAddress = MappedAddress;