haprox-rs 0.2.0

A HaProxy protocol parser.
Documentation
use std::{borrow::Cow, fmt, io::{Cursor, Read}, ops::RangeInclusive};

use byteorder::{BigEndian, ReadBytesExt};

use crate::{common, map_error, HaProxRes, PP2TlvClient, PP2Tlvs, TlType};

use super::{PP2TlvItem, PP2TlvItemMeta, PP2TlvRestore};


pub trait Test<const ID: u8>
{
    fn abcd();
}

struct Abbbb;

impl Test<1> for Abbbb
{
    fn abcd() {
        todo!()
    }
}
impl Test<2> for Abbbb
{
    fn abcd() {
        todo!()
    }
}

fn test()
{
    let v: &[fn()] = 
    &[
        <Abbbb as Test<1>>::abcd,
    ];
}

#[derive(Debug)]
pub struct PP2Root;

impl PP2TlvItem for PP2Root
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(
            PP2TlvsOp::TypeRoot as u8, 
            &[
                PP2TlvsOp::TypeAlpn as u8 ..= PP2TlvsOp::TypeSsl as u8,  
                PP2TlvsOp::TypeNetNs as u8 ..= PP2TlvsOp::TypeNetNs as u8
            ]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let mut alpns: Vec<Vec<u8>> = Vec::with_capacity(2);

        while let Some(alpn_len) = cur.read_u16::<BigEndian>().ok()
        {
            let mut alpn: Vec<u8> = vec![0_u8; alpn_len as usize];

            cur.read_exact(&mut alpn).map_err(common::map_io_err)?;

            alpns.push(alpn);
        }

        return Ok(Self::RestRet::TypeAlpn(alpns));
    }
}

#[derive(Debug)]
pub struct PP2Alpn;

impl PP2TlvItem for PP2Alpn
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeAlpn  as u8, &[]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let mut alpns: Vec<Vec<u8>> = Vec::with_capacity(2);

        while let Some(alpn_len) = cur.read_u16::<BigEndian>().ok()
        {
            let mut alpn: Vec<u8> = vec![0_u8; alpn_len as usize];

            cur.read_exact(&mut alpn).map_err(common::map_io_err)?;

            alpns.push(alpn);
        }

        return Ok(Self::RestRet::TypeAlpn(alpns));
    }
}


pub struct PP2Authority;

impl PP2TlvItem for PP2Authority
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeAuthority as u8, &[]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let tlv_len = cur.get_ref().len();

        let mut authority: Vec<u8> = vec![0_u8; tlv_len];

        cur.read_exact(&mut authority).map_err(common::map_io_err)?;

        return Ok(
            Self::RestRet::TypeAuthority(
                String::from_utf8(authority)
                    .map_err(|e| 
                        map_error!(MalformedData, "TLV TYPE_AUTHORITY restore error: '{}'", e)
                    )?
            )
        );
    }
}


pub struct PP2Crc32c;

impl PP2TlvItem for PP2Crc32c
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeCrc32c as u8, &[]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let crc = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;

        return Ok(Self::RestRet::TypeCrc32c(crc));
    }
}


pub struct PP2Noop;

impl PP2TlvItem for PP2Noop
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeNoop as u8, &[]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        return Ok(Self::RestRet::TypeNoop);
    }
}

pub struct PP2UniqId;

impl PP2TlvItem for PP2UniqId
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeUniqId as u8, &[]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let tlv_len = cur.get_ref().len();

        let mut authority: Vec<u8> = vec![0_u8; tlv_len];

        cur.read_exact(&mut authority).map_err(common::map_io_err)?;

        return Ok(
            Self::RestRet::TypeUniqId(authority)
        );
    }
}

pub struct PP2Ssl;

impl PP2TlvItem for PP2Ssl
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeSsl as u8, 
            &[PP2TlvsOp::TypeSubtypeSslVersion as u8 ..= PP2TlvsOp::TypeSubtypeSslKeyAlg as u8]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let client_bits = cur.read_u8().map_err(common::map_io_err)?;

        let client = 
            PP2TlvClient::from_bits(client_bits)
                .ok_or_else(|| map_error!(ProtocolUnknownData, "TLV TYPE_SSL unknown client bits: {}", client_bits))?;

        let verify = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;

        return Ok(
            Self::RestRet::TypeSsl{ client: client, verify: verify }
        );
    }
}

pub struct PP2SslVersion;

impl PP2TlvItem for PP2SslVersion
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeSubtypeSslVersion as u8, &[]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let tlv_len = cur.get_ref().len();

        let mut ssl_version: Vec<u8> = vec![0_u8; tlv_len];

        cur.read_exact(&mut ssl_version).map_err(common::map_io_err)?;

        let ssl_version_str = 
            String::from_utf8(ssl_version)
                .map_err(|e| 
                    map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
                )?;

        return Ok(
            Self::RestRet::TypeSubtypeSslVersion(Cow::Owned(ssl_version_str))
        );
    }
}

pub struct PP2SslCn;

impl PP2TlvItem for PP2SslCn
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeSubtypeSslCn as u8, &[]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let tlv_len = cur.get_ref().len();

        let mut ssl_cn: Vec<u8> = vec![0_u8; tlv_len];

        cur.read_exact(&mut ssl_cn).map_err(common::map_io_err)?;

        let ssl_cn = 
            String::from_utf8(ssl_cn)
                .map_err(|e| 
                    map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_CN restore error: '{}'", e)
                )?;

        return Ok(
            Self::RestRet::TypeSubtypeSslCn(Cow::Owned(ssl_cn))
        );
    }
}

pub struct PP2SslCipher;

impl PP2TlvItem for PP2SslCipher
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeSubtypeSslCipher as u8, &[]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let tlv_len = cur.get_ref().len();

        let mut ssl_cipher: Vec<u8> = vec![0_u8; tlv_len];

        cur.read_exact(&mut ssl_cipher).map_err(common::map_io_err)?;

        let ssl_cipher = 
            String::from_utf8(ssl_cipher)
                .map_err(|e| 
                    map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_CIPHER restore error: '{}'", e)
                )?;

        return Ok(
            Self::RestRet::TypeSubtypeSslCipher(Cow::Owned(ssl_cipher))
        );
    }
}

pub struct PP2SslSigAlg;

impl PP2TlvItem for PP2SslSigAlg
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeSubtypeSslSigAlg as u8, &[]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let tlv_len = cur.get_ref().len();

        let mut ssl_sigalg: Vec<u8> = vec![0_u8; tlv_len];

        cur.read_exact(&mut ssl_sigalg).map_err(common::map_io_err)?;

        let ssl_sigalg = 
            String::from_utf8(ssl_sigalg)
                .map_err(|e| 
                    map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_SIGALG restore error: '{}'", e)
                )?;

        return Ok(
            Self::RestRet::TypeSubtypeSslSigAlg( Cow::Owned(ssl_sigalg) )
        );
    }
}

pub struct PP2SslKeyAlg;

impl PP2TlvItem for PP2SslKeyAlg
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeSubtypeSslKeyAlg as u8, &[]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let tlv_len = cur.get_ref().len();

        let mut ssl_keyalg: Vec<u8> = vec![0_u8; tlv_len];

        cur.read_exact(&mut ssl_keyalg).map_err(common::map_io_err)?;

        let ssl_keyalg = 
            String::from_utf8(ssl_keyalg)
                .map_err(|e| 
                    map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_KEYALG restore error: '{}'", e)
                )?;

        return Ok(
            Self::RestRet::TypeSubtypeSslKeyAlg(Cow::Owned(ssl_keyalg))
        );
    }
}

pub struct PP2SslNs;

impl PP2TlvItem for PP2SslNs
{
    const PP2_TLV_META: PP2TlvItemMeta = 
        PP2TlvItemMeta::new(PP2TlvsOp::TypeSubtypeSslKeyAlg as u8, &[]);

    type RestRet = PP2Tlvs;

    fn restore(cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::RestRet> 
    {
        let tlv_len = cur.get_ref().len();

        let mut netns: Vec<u8> = vec![0_u8; tlv_len];

        cur.read_exact(&mut netns).map_err(common::map_io_err)?;

        let netns = 
            String::from_utf8(netns)
                .map_err(|e| 
                    map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
                )?;

        return Ok(
            Self::RestRet::TypeNetNs(netns)
        );
    }
}