#[derive(Debug, Clone, PartialEq)]
pub enum TransportMode {
Tcp,
Udp,
Auto,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ReliabilityMode {
Reliable,
Partial,
Unreliable,
Adaptive,
}
#[derive(Debug, Clone)]
pub struct VCLConfig {
pub transport: TransportMode,
pub reliability: ReliabilityMode,
pub max_retries: u32,
pub retry_interval_ms: u64,
pub fragment_size: usize,
pub flow_window_size: usize,
}
impl VCLConfig {
pub fn vpn() -> Self {
VCLConfig {
transport: TransportMode::Tcp,
reliability: ReliabilityMode::Reliable,
max_retries: 10,
retry_interval_ms: 100,
fragment_size: 1200,
flow_window_size: 64,
}
}
pub fn gaming() -> Self {
VCLConfig {
transport: TransportMode::Udp,
reliability: ReliabilityMode::Partial,
max_retries: 2,
retry_interval_ms: 16,
fragment_size: 1400,
flow_window_size: 128,
}
}
pub fn streaming() -> Self {
VCLConfig {
transport: TransportMode::Udp,
reliability: ReliabilityMode::Unreliable,
max_retries: 0,
retry_interval_ms: 0,
fragment_size: 1400,
flow_window_size: 256,
}
}
pub fn auto() -> Self {
VCLConfig {
transport: TransportMode::Auto,
reliability: ReliabilityMode::Adaptive,
max_retries: 5,
retry_interval_ms: 100,
fragment_size: 1200,
flow_window_size: 64,
}
}
pub fn is_tcp(&self) -> bool {
self.transport == TransportMode::Tcp
|| (self.transport == TransportMode::Auto
&& self.reliability == ReliabilityMode::Reliable)
}
pub fn has_retransmission(&self) -> bool {
matches!(
self.reliability,
ReliabilityMode::Reliable | ReliabilityMode::Partial | ReliabilityMode::Adaptive
)
}
pub fn needs_fragmentation(&self, size: usize) -> bool {
size > self.fragment_size
}
}
impl Default for VCLConfig {
fn default() -> Self {
Self::auto()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vpn_preset() {
let c = VCLConfig::vpn();
assert_eq!(c.transport, TransportMode::Tcp);
assert_eq!(c.reliability, ReliabilityMode::Reliable);
assert!(c.has_retransmission());
assert!(c.is_tcp());
}
#[test]
fn test_gaming_preset() {
let c = VCLConfig::gaming();
assert_eq!(c.transport, TransportMode::Udp);
assert_eq!(c.reliability, ReliabilityMode::Partial);
assert!(c.has_retransmission());
assert!(!c.is_tcp());
}
#[test]
fn test_streaming_preset() {
let c = VCLConfig::streaming();
assert_eq!(c.transport, TransportMode::Udp);
assert_eq!(c.reliability, ReliabilityMode::Unreliable);
assert!(!c.has_retransmission());
assert!(!c.is_tcp());
}
#[test]
fn test_auto_preset() {
let c = VCLConfig::auto();
assert_eq!(c.transport, TransportMode::Auto);
assert_eq!(c.reliability, ReliabilityMode::Adaptive);
assert!(c.has_retransmission());
}
#[test]
fn test_default_is_auto() {
let c = VCLConfig::default();
assert_eq!(c.transport, TransportMode::Auto);
}
#[test]
fn test_needs_fragmentation() {
let c = VCLConfig::vpn(); assert!(!c.needs_fragmentation(1000));
assert!(!c.needs_fragmentation(1200));
assert!(c.needs_fragmentation(1201));
assert!(c.needs_fragmentation(65535));
}
#[test]
fn test_custom_config() {
let c = VCLConfig {
transport: TransportMode::Udp,
reliability: ReliabilityMode::Partial,
max_retries: 3,
retry_interval_ms: 50,
fragment_size: 800,
flow_window_size: 32,
};
assert_eq!(c.transport, TransportMode::Udp);
assert!(c.needs_fragmentation(801));
assert!(!c.needs_fragmentation(800));
}
}