1use std::net::SocketAddr;
2
3use crate::error::ProxyStreamError;
4
5#[derive(Debug, Clone)]
6pub enum DestinationAddress {
7 Domain(String, u16),
8 Ip(SocketAddr),
9}
10
11impl DestinationAddress {
12 pub fn to_bytes(&self) -> Vec<u8> {
13 match self {
14 DestinationAddress::Domain(domain, port) => {
15 [domain.as_bytes(), port.to_be_bytes().as_ref()].concat()
16 }
17 DestinationAddress::Ip(addr) => match addr {
18 SocketAddr::V4(addr) => {
19 [&addr.ip().octets(), addr.port().to_be_bytes().as_ref()].concat()
20 }
21 SocketAddr::V6(addr) => {
22 [&addr.ip().octets(), addr.port().to_be_bytes().as_ref()].concat()
23 }
24 },
25 }
26 }
27 pub fn from_bytes(buf: &[u8], ip: bool) -> Result<Self, ProxyStreamError> {
28 if buf.len() < 3 {
29 return Err(ProxyStreamError::InvalidAddress);
30 }
31 if ip {
32 let port = u16::from_be_bytes([buf[buf.len() - 2], buf[buf.len() - 1]]);
33 let ip = match buf.len() {
34 6 => {
35 let mut octets = [0; 4];
36 octets.copy_from_slice(&buf[0..4]);
37 SocketAddr::V4(std::net::SocketAddrV4::new(
38 std::net::Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]),
39 port,
40 ))
41 }
42 18 => {
43 let mut octets = [0; 16];
44 octets.copy_from_slice(&buf[0..16]);
45 SocketAddr::V6(std::net::SocketAddrV6::new(
46 std::net::Ipv6Addr::new(
47 u16::from_be_bytes([octets[0], octets[1]]),
48 u16::from_be_bytes([octets[2], octets[3]]),
49 u16::from_be_bytes([octets[4], octets[5]]),
50 u16::from_be_bytes([octets[6], octets[7]]),
51 u16::from_be_bytes([octets[8], octets[9]]),
52 u16::from_be_bytes([octets[10], octets[11]]),
53 u16::from_be_bytes([octets[12], octets[13]]),
54 u16::from_be_bytes([octets[14], octets[15]]),
55 ),
56 port,
57 0,
58 0,
59 ))
60 }
61 _ => return Err(ProxyStreamError::InvalidAddress),
62 };
63 Ok(DestinationAddress::Ip(ip))
64 } else {
65 let port = u16::from_be_bytes([buf[buf.len() - 2], buf[buf.len() - 1]]);
66 let domain = String::from_utf8_lossy(&buf[0..buf.len() - 2]).to_string();
67 Ok(DestinationAddress::Domain(domain, port))
68 }
69 }
70}
71
72impl Default for DestinationAddress {
73 fn default() -> Self {
74 DestinationAddress::Ip(SocketAddr::from(([0, 0, 0, 0], 0)))
75 }
76}
77pub trait ToSocketDestination {
78 fn to_destination_address(&self) -> Result<DestinationAddress, ProxyStreamError>;
79}
80
81impl ToSocketDestination for SocketAddr {
82 fn to_destination_address(&self) -> Result<DestinationAddress, ProxyStreamError> {
83 Ok(DestinationAddress::Ip(*self))
84 }
85}
86
87impl ToSocketDestination for &str {
88 fn to_destination_address(&self) -> Result<DestinationAddress, ProxyStreamError> {
89 if let Ok(ip) = self.parse::<SocketAddr>() {
90 return Ok(DestinationAddress::Ip(ip));
91 }
92 self.rsplit_once(':')
93 .and_then(|(domain, port)| {
94 port.parse::<u16>()
95 .ok()
96 .map(|port| DestinationAddress::Domain(domain.to_string(), port))
97 })
98 .ok_or(ProxyStreamError::InvalidAddress)
99 }
100}
101
102impl From<&DestinationAddress> for (String, u16) {
103 fn from(value: &DestinationAddress) -> Self {
104 match value {
105 DestinationAddress::Domain(domain, port) => (domain.to_owned(), *port),
106 DestinationAddress::Ip(addr) => match addr {
107 SocketAddr::V4(addr) => (addr.ip().to_string(), addr.port()),
108 SocketAddr::V6(addr) => (addr.ip().to_string(), addr.port()),
109 },
110 }
111 }
112}