1const XOR_MAPPED_ADDRESS: u16 = 0x0020;
2
3crate::common::xor_socket_addr_attribute!(
4 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, 0xBC, 0x34, 0xD6, 0x86, 0xFA, 0x87, 0xDF, 0xAE, ]
39 }
40
41 #[test]
42 fn decode_ipv4() {
43 let xor_buffer = [
45 0x00, 0x01, 0xA1, 0x47, 0xE1, 0x12, 0xA6, 0x43, ];
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 let xor_buffer = [
62 0x00, 0x02, 0xa1, 0x47, 0x01, 0x13, 0xa9, 0xfa, 0xa5, 0xd3, 0xf1, 0x79, 0xbc, 0x25, 0xf4, 0xb5, 0xbe, 0xd2, 0xb9, 0xd9, ];
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, 0xE1, 0x12, 0xA6, 0x43, ];
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, 0x01, 0x13, 0xa9, 0xfa, 0xa5, 0xd3, 0xf1, 0x79, 0xbc, 0x25, 0xf4, 0xb5, 0xbe, 0xd2, 0xb9, 0xd9, ];
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}