feat(smart-proxy): add hot-reloadable global ingress security policy across Rust and TypeScript proxy layers
This commit is contained in:
@@ -54,8 +54,8 @@ pub fn parse_v1(data: &[u8]) -> Result<(ProxyProtocolHeader, usize), ProxyProtoc
|
||||
.position(|w| w == b"\r\n")
|
||||
.ok_or(ProxyProtocolError::InvalidHeader)?;
|
||||
|
||||
let line = std::str::from_utf8(&data[..line_end])
|
||||
.map_err(|_| ProxyProtocolError::InvalidHeader)?;
|
||||
let line =
|
||||
std::str::from_utf8(&data[..line_end]).map_err(|_| ProxyProtocolError::InvalidHeader)?;
|
||||
|
||||
if !line.starts_with("PROXY ") {
|
||||
return Err(ProxyProtocolError::InvalidHeader);
|
||||
@@ -148,7 +148,10 @@ pub fn parse_v2(data: &[u8]) -> Result<(ProxyProtocolHeader, usize), ProxyProtoc
|
||||
let command = data[12] & 0x0F;
|
||||
// 0x0 = LOCAL, 0x1 = PROXY
|
||||
if command > 1 {
|
||||
return Err(ProxyProtocolError::Parse(format!("Unknown command: {}", command)));
|
||||
return Err(ProxyProtocolError::Parse(format!(
|
||||
"Unknown command: {}",
|
||||
command
|
||||
)));
|
||||
}
|
||||
|
||||
// Address family (high nibble) + transport (low nibble) of byte 13
|
||||
@@ -182,7 +185,9 @@ pub fn parse_v2(data: &[u8]) -> Result<(ProxyProtocolHeader, usize), ProxyProtoc
|
||||
// AF_INET (0x1) + STREAM (0x1) = TCP4
|
||||
(0x1, 0x1) => {
|
||||
if addr_len < 12 {
|
||||
return Err(ProxyProtocolError::Parse("IPv4 address block too short".to_string()));
|
||||
return Err(ProxyProtocolError::Parse(
|
||||
"IPv4 address block too short".to_string(),
|
||||
));
|
||||
}
|
||||
let src_ip = Ipv4Addr::new(addr_block[0], addr_block[1], addr_block[2], addr_block[3]);
|
||||
let dst_ip = Ipv4Addr::new(addr_block[4], addr_block[5], addr_block[6], addr_block[7]);
|
||||
@@ -200,7 +205,9 @@ pub fn parse_v2(data: &[u8]) -> Result<(ProxyProtocolHeader, usize), ProxyProtoc
|
||||
// AF_INET (0x1) + DGRAM (0x2) = UDP4
|
||||
(0x1, 0x2) => {
|
||||
if addr_len < 12 {
|
||||
return Err(ProxyProtocolError::Parse("IPv4 address block too short".to_string()));
|
||||
return Err(ProxyProtocolError::Parse(
|
||||
"IPv4 address block too short".to_string(),
|
||||
));
|
||||
}
|
||||
let src_ip = Ipv4Addr::new(addr_block[0], addr_block[1], addr_block[2], addr_block[3]);
|
||||
let dst_ip = Ipv4Addr::new(addr_block[4], addr_block[5], addr_block[6], addr_block[7]);
|
||||
@@ -218,7 +225,9 @@ pub fn parse_v2(data: &[u8]) -> Result<(ProxyProtocolHeader, usize), ProxyProtoc
|
||||
// AF_INET6 (0x2) + STREAM (0x1) = TCP6
|
||||
(0x2, 0x1) => {
|
||||
if addr_len < 36 {
|
||||
return Err(ProxyProtocolError::Parse("IPv6 address block too short".to_string()));
|
||||
return Err(ProxyProtocolError::Parse(
|
||||
"IPv6 address block too short".to_string(),
|
||||
));
|
||||
}
|
||||
let src_ip = Ipv6Addr::from(<[u8; 16]>::try_from(&addr_block[0..16]).unwrap());
|
||||
let dst_ip = Ipv6Addr::from(<[u8; 16]>::try_from(&addr_block[16..32]).unwrap());
|
||||
@@ -236,7 +245,9 @@ pub fn parse_v2(data: &[u8]) -> Result<(ProxyProtocolHeader, usize), ProxyProtoc
|
||||
// AF_INET6 (0x2) + DGRAM (0x2) = UDP6
|
||||
(0x2, 0x2) => {
|
||||
if addr_len < 36 {
|
||||
return Err(ProxyProtocolError::Parse("IPv6 address block too short".to_string()));
|
||||
return Err(ProxyProtocolError::Parse(
|
||||
"IPv6 address block too short".to_string(),
|
||||
));
|
||||
}
|
||||
let src_ip = Ipv6Addr::from(<[u8; 16]>::try_from(&addr_block[0..16]).unwrap());
|
||||
let dst_ip = Ipv6Addr::from(<[u8; 16]>::try_from(&addr_block[16..32]).unwrap());
|
||||
@@ -268,11 +279,7 @@ pub fn parse_v2(data: &[u8]) -> Result<(ProxyProtocolHeader, usize), ProxyProtoc
|
||||
}
|
||||
|
||||
/// Generate a PROXY protocol v2 binary header.
|
||||
pub fn generate_v2(
|
||||
source: &SocketAddr,
|
||||
dest: &SocketAddr,
|
||||
transport: ProxyV2Transport,
|
||||
) -> Vec<u8> {
|
||||
pub fn generate_v2(source: &SocketAddr, dest: &SocketAddr, transport: ProxyV2Transport) -> Vec<u8> {
|
||||
let transport_nibble: u8 = match transport {
|
||||
ProxyV2Transport::Stream => 0x1,
|
||||
ProxyV2Transport::Datagram => 0x2,
|
||||
@@ -462,7 +469,10 @@ mod tests {
|
||||
header.push(0x11);
|
||||
header.extend_from_slice(&12u16.to_be_bytes());
|
||||
header.extend_from_slice(&[0u8; 12]);
|
||||
assert!(matches!(parse_v2(&header), Err(ProxyProtocolError::UnsupportedVersion)));
|
||||
assert!(matches!(
|
||||
parse_v2(&header),
|
||||
Err(ProxyProtocolError::UnsupportedVersion)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user