stochastic-routing-extended 1.0.2

SRX (Stochastic Routing eXtended) — a next-generation VPN protocol with stochastic routing, DPI evasion, post-quantum cryptography, and multi-transport channel splitting
Documentation
//! In-band signaling: control messages hidden in pseudo-legitimate data.

/// Magic tag so signals are distinguishable from random padding.
const TAG: u8 = 0x5B;

/// Encodes/decodes control signals within normal-looking traffic.
pub struct InBandSignaling {
    _private: (),
}

/// Types of in-band signals.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Signal {
    /// Request seed rotation.
    SeedRotation,
    /// Request re-keying.
    ReKey,
    /// Request transport switch.
    TransportSwitch,
    /// Session teardown.
    Shutdown,
    /// Custom signal with payload.
    Custom(Vec<u8>),
}

impl InBandSignaling {
    pub fn new() -> Self {
        Self { _private: () }
    }

    /// Encode a signal into bytes suitable for embedding in cover traffic.
    pub fn encode(&self, signal: &Signal) -> Vec<u8> {
        match signal {
            Signal::SeedRotation => vec![TAG, 1],
            Signal::ReKey => vec![TAG, 2],
            Signal::TransportSwitch => vec![TAG, 3],
            Signal::Shutdown => vec![TAG, 4],
            Signal::Custom(p) => {
                let mut v = vec![TAG, 5];
                let len = u16::try_from(p.len()).expect("custom signal payload exceeds u16::MAX");
                v.extend_from_slice(&len.to_be_bytes());
                v.extend_from_slice(p);
                v
            }
        }
    }

    /// Decode a signal; returns [`None`] if data does not match framing.
    pub fn decode(&self, data: &[u8]) -> Option<Signal> {
        if data.len() < 2 || data[0] != TAG {
            return None;
        }
        match data[1] {
            1 => Some(Signal::SeedRotation),
            2 => Some(Signal::ReKey),
            3 => Some(Signal::TransportSwitch),
            4 => Some(Signal::Shutdown),
            5 => {
                if data.len() < 4 {
                    return None;
                }
                let len = u16::from_be_bytes([data[2], data[3]]) as usize;
                if data.len() != 4 + len {
                    return None;
                }
                Some(Signal::Custom(data[4..].to_vec()))
            }
            _ => None,
        }
    }
}

impl Default for InBandSignaling {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn roundtrip_custom() {
        let s = InBandSignaling::new();
        let sig = Signal::Custom(b"ctl".to_vec());
        let b = s.encode(&sig);
        assert_eq!(s.decode(&b), Some(sig));
    }
}