Skip to main content

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