stun_rs/attributes/stun/
xor_mapped_address.rs

1const XOR_MAPPED_ADDRESS: u16 = 0x0020;
2
3crate::common::xor_socket_addr_attribute!(
4    /// The `XorMappedAddress` attribute is identical to the
5    /// [`MappedAddress`](crate::attributes::stun::MappedAddress)
6    /// attribute, except that the reflexive transport address is
7    /// obfuscated through the XOR function.
8    ///
9    /// # Examples
10    ///```rust
11    /// # use std::net::{IpAddr, Ipv4Addr, SocketAddr};
12    /// # use stun_rs::attributes::stun::XorMappedAddress;
13    /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
14    /// let attr = XorMappedAddress::from(socket);
15    ///
16    /// let socket = attr.socket_address();
17    /// assert_eq!(socket.port(), 8080);
18    /// assert_eq!(socket.is_ipv4(), true);
19    ///```
20    XorMappedAddress,
21    XOR_MAPPED_ADDRESS,
22);
23
24#[cfg(test)]
25mod tests {
26    use super::*;
27    use crate::common::{xor_decode, xor_encode};
28    use crate::types::TRANSACTION_ID_SIZE;
29    use crate::StunAttribute;
30    use std::net::{IpAddr, Ipv4Addr, SocketAddr};
31    use std::str::FromStr;
32
33    fn transaction_id() -> [u8; TRANSACTION_ID_SIZE] {
34        [
35            0xB7, 0xE7, 0xA7, 0x01, //  }
36            0xBC, 0x34, 0xD6, 0x86, //  }  Transaction ID
37            0xFA, 0x87, 0xDF, 0xAE, // }
38        ]
39    }
40
41    #[test]
42    fn decode_ipv4() {
43        // XOR Mapped Address: 192.0.2.1:32853
44        let xor_buffer = [
45            0x00, 0x01, 0xA1, 0x47, // Address family (IPv6) and xor'd mapped port number
46            0xE1, 0x12, 0xA6, 0x43, // }  Xor'd mapped IPv6 address
47        ];
48        let tr = transaction_id();
49        let (addr, size) = xor_decode(&tr, &xor_buffer).expect("Can not decode XorMappedAddress");
50        let attr = XorMappedAddress::from(addr);
51
52        assert_eq!(size, 8);
53        assert!(attr.socket_address().is_ipv4());
54        assert_eq!(attr.socket_address().port(), 32853);
55        assert_eq!(attr.socket_address().to_string(), "192.0.2.1:32853");
56    }
57
58    #[test]
59    fn decode_ipv6() {
60        // XOR Mapped Address: `2001:db8:1234:5678:11:2233:4455:6677` port 32853
61        let xor_buffer = [
62            0x00, 0x02, 0xa1, 0x47, // Address family (IPv6) and xor'd mapped port number
63            0x01, 0x13, 0xa9, 0xfa, // }
64            0xa5, 0xd3, 0xf1, 0x79, // }  Xor'd mapped IPv6 address
65            0xbc, 0x25, 0xf4, 0xb5, // }
66            0xbe, 0xd2, 0xb9, 0xd9, // }
67        ];
68        let tr = transaction_id();
69        let (addr, size) = xor_decode(&tr, &xor_buffer).expect("Can not decode XorMappedAddress");
70        let attr = XorMappedAddress::from(addr);
71
72        assert_eq!(size, 20);
73        assert!(attr.socket_address().is_ipv6());
74        assert_eq!(attr.socket_address().port(), 32853);
75        assert_eq!(
76            attr.socket_address().to_string(),
77            "[2001:db8:1234:5678:11:2233:4455:6677]:32853"
78        );
79    }
80
81    #[test]
82    fn encode_ipv4() {
83        let tr = transaction_id();
84        let addr = SocketAddr::from_str("192.0.2.1:32853").expect("Can not parse SocketAddress");
85
86        let attr = XorMappedAddress::from(addr);
87
88        let mut buffer: [u8; 8] = [0x00; 8];
89        let result = xor_encode(&tr, &attr, &mut buffer);
90
91        assert_eq!(result, Ok(8));
92
93        let xor_buffer = [
94            0x00, 0x01, 0xA1, 0x47, // Address family (IPv6) and xor'd mapped port number
95            0xE1, 0x12, 0xA6, 0x43, // }  Xor'd mapped IPv6 address
96        ];
97        assert_eq!(&buffer[..], &xor_buffer[..]);
98    }
99
100    #[test]
101    fn encode_ipv6() {
102        let tr = transaction_id();
103        let addr = SocketAddr::from_str("[2001:db8:1234:5678:11:2233:4455:6677]:32853")
104            .expect("Can not parse SocketAddress");
105        let attr = XorMappedAddress::from(addr);
106
107        let mut buffer: [u8; 20] = [0x00; 20];
108        let result = xor_encode(&tr, &attr, &mut buffer);
109
110        assert_eq!(result, Ok(20));
111
112        let xor_buffer = [
113            0x00, 0x02, 0xa1, 0x47, // Address family (IPv6) and xor'd mapped port number
114            0x01, 0x13, 0xa9, 0xfa, // }
115            0xa5, 0xd3, 0xf1, 0x79, // }  Xor'd mapped IPv6 address
116            0xbc, 0x25, 0xf4, 0xb5, // }
117            0xbe, 0xd2, 0xb9, 0xd9, // }
118        ];
119        assert_eq!(&buffer[..], &xor_buffer[..]);
120    }
121
122    #[test]
123    fn xor_mapped_address_stunt_attribute() {
124        let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
125        let attr = StunAttribute::XorMappedAddress(XorMappedAddress::from(socket));
126        assert!(attr.is_xor_mapped_address());
127        assert!(attr.as_xor_mapped_address().is_ok());
128        assert!(attr.as_error_code().is_err());
129
130        assert!(attr.attribute_type().is_comprehension_required());
131        assert!(!attr.attribute_type().is_comprehension_optional());
132
133        let dbg_fmt = format!("{:?}", attr);
134        assert_eq!(
135            "XorMappedAddress(XorMappedAddress(127.0.0.1:8080))",
136            dbg_fmt
137        );
138    }
139}