1 #[cfg(test)] 2 mod addr_test; 3 4 use crate::attributes::*; 5 use crate::error::*; 6 use crate::message::*; 7 8 use std::fmt; 9 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; 10 11 pub(crate) const FAMILY_IPV4: u16 = 0x01; 12 pub(crate) const FAMILY_IPV6: u16 = 0x02; 13 pub(crate) const IPV4LEN: usize = 4; 14 pub(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 22 pub struct MappedAddress { 23 pub ip: IpAddr, 24 pub port: u16, 25 } 26 27 impl fmt::Display for MappedAddress { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result28 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 41 impl Default for MappedAddress { default() -> Self42 fn default() -> Self { 43 MappedAddress { 44 ip: IpAddr::V4(Ipv4Addr::from(0)), 45 port: 0, 46 } 47 } 48 } 49 50 impl Setter for MappedAddress { 51 /// add_to adds MAPPED-ADDRESS to message. add_to(&self, m: &mut Message) -> Result<()>52 fn add_to(&self, m: &mut Message) -> Result<()> { 53 self.add_to_as(m, ATTR_MAPPED_ADDRESS) 54 } 55 } 56 57 impl Getter for MappedAddress { 58 /// get_from decodes MAPPED-ADDRESS from message. get_from(&mut self, m: &Message) -> Result<()>59 fn get_from(&mut self, m: &Message) -> Result<()> { 60 self.get_from_as(m, ATTR_MAPPED_ADDRESS) 61 } 62 } 63 64 impl MappedAddress { 65 /// get_from_as decodes MAPPED-ADDRESS value in message m as an attribute of type t. get_from_as(&mut self, m: &Message, t: AttrType) -> Result<()>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. add_to_as(&self, m: &mut Message, t: AttrType) -> Result<()>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 118 pub type AlternateServer = MappedAddress; 119 120 /// ResponseOrigin represents RESPONSE-ORIGIN attribute. 121 /// 122 /// RFC 5780 Section 7.3 123 pub type ResponseOrigin = MappedAddress; 124 125 /// OtherAddress represents OTHER-ADDRESS attribute. 126 /// 127 /// RFC 5780 Section 7.4 128 pub type OtherAddress = MappedAddress; 129