use crate::error::*;
use bytes::{Buf as _, BufMut as _, Bytes, BytesMut};
pub const CONNECTION_PREFIX: [u8; 12] = [
0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A,
];
#[allow(dead_code)] #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
#[repr(u8)]
pub enum ProxyCommand {
Local = 0x0,
Proxy = 0x1,
}
#[allow(dead_code)] #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
#[repr(u8)]
pub enum ProxyTransportProtocol {
Unspec = 0x0,
Stream = 0x1,
DGram = 0x2,
}
#[allow(dead_code)] #[allow(clippy::large_enum_variant)]
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum ProxyAddress {
Unspec,
IpV4 {
source: [u8; 4],
destination: [u8; 4],
},
IpV6 {
source: [u8; 16],
destination: [u8; 16],
},
UnixSocket {
source: Vec<u8>,
destination: Vec<u8>,
},
}
impl ProxyAddress {
pub fn read_addresses(
family: ProxyAddressFamily,
bytes: &mut Bytes,
) -> Result<Self, BinaryParsingError> {
match family {
ProxyAddressFamily::Unspec => Ok(Self::Unspec),
ProxyAddressFamily::InetV4 => Self::read_ipv4(bytes),
ProxyAddressFamily::InetV6 => Self::read_ipv6(bytes),
ProxyAddressFamily::UnixSocket => Self::read_unix_socket(bytes),
}
}
pub fn family(&self) -> ProxyAddressFamily {
match self {
Self::Unspec => ProxyAddressFamily::Unspec,
Self::IpV4 { .. } => ProxyAddressFamily::InetV4,
Self::IpV6 { .. } => ProxyAddressFamily::InetV6,
Self::UnixSocket { .. } => ProxyAddressFamily::UnixSocket,
}
}
pub fn write(&self, buf: &mut BytesMut) {
match self {
Self::Unspec => (),
Self::IpV4 {
source,
destination,
} => {
buf.put_slice(&source[..]);
buf.put_slice(&destination[..]);
}
Self::IpV6 {
source,
destination,
} => {
buf.put_slice(&source[..]);
buf.put_slice(&destination[..]);
}
Self::UnixSocket {
source,
destination,
} => {
buf.put_slice(&source);
buf.put_slice(&destination);
}
}
}
fn read_ipv4(bytes: &mut Bytes) -> Result<Self, BinaryParsingError> {
if bytes.remaining() < 8 {
return Err(BinaryParsingError::BufferSmall(8));
}
let source = [
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
];
let dest = [
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
];
Ok(Self::IpV4 {
source,
destination: dest,
})
}
fn read_ipv6(bytes: &mut Bytes) -> Result<Self, BinaryParsingError> {
if bytes.remaining() < 32 {
return Err(BinaryParsingError::BufferSmall(32));
}
let source = [
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
];
let dest = [
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
bytes.get_u8(),
];
Ok(Self::IpV6 {
source,
destination: dest,
})
}
fn read_unix_socket(bytes: &mut Bytes) -> Result<Self, BinaryParsingError> {
if bytes.remaining() < 216 {
return Err(BinaryParsingError::BufferSmall(216));
}
let mut source = vec![0; 108];
let mut dest = vec![0; 108];
bytes.copy_to_slice(&mut source);
bytes.copy_to_slice(&mut dest);
Ok(Self::UnixSocket {
source,
destination: dest,
})
}
}
#[allow(dead_code)] #[derive(Debug, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum ProxyAddressFamily {
Unspec = 0x0,
InetV4 = 0x1,
InetV6 = 0x2,
UnixSocket = 0x3,
}
impl ProxyCommand {
pub fn read_command_binary(byte: u8) -> Option<Self> {
Some(match byte & 0b0000_1111 {
0x0 => Self::Local,
0x1 => Self::Proxy,
_ => return None,
})
}
}
impl ProxyAddressFamily {
pub fn read_family_binary(byte: u8) -> Option<Self> {
Some(match byte >> 4 {
0x0 => Self::Unspec,
0x1 => Self::InetV4,
0x2 => Self::InetV6,
0x3 => Self::UnixSocket,
_ => return None,
})
}
}
impl ProxyTransportProtocol {
pub fn read_protocol_binary(byte: u8) -> Option<Self> {
Some(match byte & 0b0000_1111 {
0x0 => Self::Unspec,
0x1 => Self::Stream,
0x2 => Self::DGram,
_ => return None,
})
}
}