webrtc_stun/
addr.rs

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