haprox-rs 0.3.2

A HaProxy v1/v2 protocol parser.
Documentation
/*-
 * haprox-rs - a HaProxy protocol parser.
 * 
 * Copyright 2025 (c) Aleksandr Morozov
 * The scram-rs crate can be redistributed and/or modified
 * under the terms of either of the following licenses:
 *
 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
 *
 *   2. The MIT License (MIT)
 *                     
 *   3. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
 */

/// Characters match the US-ASCII representation of "PROXY"
pub const HEADER_MAGIC_V1: &[u8] = b"\x50\x52\x4F\x58\x59";

pub const HEADER_MAGIC_V1_STR: &str = "\x50\x52\x4F\x58\x59";

pub const HEADER_V1_WSPACE: &str = "\x20";

pub const HEADER_V1_EOM: &str = "\r\n";

/// 108-byte buffer is always enough to store all the line and a trailing zero
/// for string processing.
pub const HEADER_V1_MAX_LEN: usize = 108;

/// Binary header format starts with a constant 12 bytes.
pub const HEADER_MAGIC_V2: &[u8] = b"\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A";

/// Binary header format starts with a constant 12 bytes.
pub const MSG_HEADER_LOCAL_V2: &[u8] = b"\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x20\x00\x00\x00";

/// Length if the `HEADER_MAGIC_V2`
pub const HEADER_MAGINC_LEN: usize = HEADER_MAGIC_V2.len();

pub const HEADER_UNIX_ADDR_LEN: usize = 108;

/// \x54 \x43 \x50 \x34
pub const HEADER_V1_INET_TCP4: &str = "TCP4";

/// \x54 \x43 \x50 \x36
pub const HEADER_V1_INET_TCP6: &str = "TCP6";

pub const HEADER_V1_INET_UNKNWON: &str = "UNKNOWN";

#[allow(unused)]
#[repr(C, packed)]
pub struct PP2TlvSsl
{
    pub client: u8,
    pub verify: u32,
    pub data: [u8; 0],
}

#[repr(C, packed)]
pub struct PP2Tlv
{
    pub mtype: u8,
    pub length_hi: u8,
    pub length_lo: u8,
    pub value: [u8; 0],
}

#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
pub struct Ipv4Addr
{
    pub src_addr: u32,
    pub dst_addr: u32,
    pub src_port: u16,
    pub dst_port: u16
}

#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
pub struct Ipv6Addr
{
    pub src_addr: [u8; 16],
    pub  dst_addr: [u8; 16],
    pub src_port: u16,
    pub dst_port: u16
}

#[allow(unused)]
#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
pub struct UnixAddr
{
    pub src_addr: [u8; HEADER_UNIX_ADDR_LEN],
    pub dst_addr: [u8; HEADER_UNIX_ADDR_LEN],
}

#[allow(unused)]
#[repr(C, packed)]
pub union ProxyAddr
{
    pub ipv4_addr: Ipv4Addr,
    pub ipv6_addr: Ipv6Addr,
    pub unix_addr: UnixAddr,
}

#[repr(C, packed)]
pub struct ProxyHdrV2
{
    /// [HEADER_MAGIC] const
    pub signature: [u8; HEADER_MAGINC_LEN],

    /// protocol version and command 
    pub ver_cmd: u8,

    /// protocol family and address
    pub fam: u8,

    /// number of following bytes part of the header
    pub len: u16,

    ///   17th byte, addresses in network byte order.
    pub address: [u8; 0]//ProxyAddr,
}

#[allow(unused)]
impl ProxyHdrV2
{
    pub const VERSION_MASK: u8 = 0xF0;
    pub const COMMAND_MASK: u8 = 0x0F;
    pub const TRANSPT_MASK: u8 = 0x0F;
    pub const ADDRESS_MASK: u8 = 0xF0;

    pub const VERSION_RAW: u8 = 0x20;

    pub const HEADER_LEN: usize = size_of::<Self>();
    pub const HEADER_ADDR_LEN: usize = size_of::<Self>() + size_of::<ProxyAddr>();
}