const XOR_MAPPED_ADDRESS: u16 = 0x0020;
crate::common::xor_socket_addr_attribute!(
XorMappedAddress,
XOR_MAPPED_ADDRESS,
);
#[cfg(test)]
mod tests {
use super::*;
use crate::common::{xor_decode, xor_encode};
use crate::types::TRANSACTION_ID_SIZE;
use crate::StunAttribute;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::str::FromStr;
fn transaction_id() -> [u8; TRANSACTION_ID_SIZE] {
[
0xB7, 0xE7, 0xA7, 0x01, 0xBC, 0x34, 0xD6, 0x86, 0xFA, 0x87, 0xDF, 0xAE, ]
}
#[test]
fn decode_ipv4() {
let xor_buffer = [
0x00, 0x01, 0xA1, 0x47, 0xE1, 0x12, 0xA6, 0x43, ];
let tr = transaction_id();
let (addr, size) = xor_decode(&tr, &xor_buffer).expect("Can not decode XorMappedAddress");
let attr = XorMappedAddress::from(addr);
assert_eq!(size, 8);
assert!(attr.socket_address().is_ipv4());
assert_eq!(attr.socket_address().port(), 32853);
assert_eq!(attr.socket_address().to_string(), "192.0.2.1:32853");
}
#[test]
fn decode_ipv6() {
let xor_buffer = [
0x00, 0x02, 0xa1, 0x47, 0x01, 0x13, 0xa9, 0xfa, 0xa5, 0xd3, 0xf1, 0x79, 0xbc, 0x25, 0xf4, 0xb5, 0xbe, 0xd2, 0xb9, 0xd9, ];
let tr = transaction_id();
let (addr, size) = xor_decode(&tr, &xor_buffer).expect("Can not decode XorMappedAddress");
let attr = XorMappedAddress::from(addr);
assert_eq!(size, 20);
assert!(attr.socket_address().is_ipv6());
assert_eq!(attr.socket_address().port(), 32853);
assert_eq!(
attr.socket_address().to_string(),
"[2001:db8:1234:5678:11:2233:4455:6677]:32853"
);
}
#[test]
fn encode_ipv4() {
let tr = transaction_id();
let addr = SocketAddr::from_str("192.0.2.1:32853").expect("Can not parse SocketAddress");
let attr = XorMappedAddress::from(addr);
let mut buffer: [u8; 8] = [0x00; 8];
let result = xor_encode(&tr, &attr, &mut buffer);
assert_eq!(result, Ok(8));
let xor_buffer = [
0x00, 0x01, 0xA1, 0x47, 0xE1, 0x12, 0xA6, 0x43, ];
assert_eq!(&buffer[..], &xor_buffer[..]);
}
#[test]
fn encode_ipv6() {
let tr = transaction_id();
let addr = SocketAddr::from_str("[2001:db8:1234:5678:11:2233:4455:6677]:32853")
.expect("Can not parse SocketAddress");
let attr = XorMappedAddress::from(addr);
let mut buffer: [u8; 20] = [0x00; 20];
let result = xor_encode(&tr, &attr, &mut buffer);
assert_eq!(result, Ok(20));
let xor_buffer = [
0x00, 0x02, 0xa1, 0x47, 0x01, 0x13, 0xa9, 0xfa, 0xa5, 0xd3, 0xf1, 0x79, 0xbc, 0x25, 0xf4, 0xb5, 0xbe, 0xd2, 0xb9, 0xd9, ];
assert_eq!(&buffer[..], &xor_buffer[..]);
}
#[test]
fn xor_mapped_address_stunt_attribute() {
let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
let attr = StunAttribute::XorMappedAddress(XorMappedAddress::from(socket));
assert!(attr.is_xor_mapped_address());
assert!(attr.as_xor_mapped_address().is_ok());
assert!(attr.as_error_code().is_err());
assert!(attr.attribute_type().is_comprehension_required());
assert!(!attr.attribute_type().is_comprehension_optional());
let dbg_fmt = format!("{:?}", attr);
assert_eq!(
"XorMappedAddress(XorMappedAddress(127.0.0.1:8080))",
dbg_fmt
);
}
}