Skip to main content

vcl_protocol/
config.rs

1//! # VCL Connection Configuration
2//!
3//! [`VCLConfig`] controls how a [`VCLConnection`] handles transport and reliability.
4//!
5//! Use one of the preset constructors for common scenarios, or build your own:
6//!
7//! ```rust
8//! use vcl_protocol::config::{VCLConfig, TransportMode, ReliabilityMode};
9//!
10//! // Use a preset
11//! let vpn_config = VCLConfig::vpn();
12//! let gaming_config = VCLConfig::gaming();
13//!
14//! // Or build custom
15//! let custom = VCLConfig {
16//!     transport: TransportMode::Udp,
17//!     reliability: ReliabilityMode::Partial,
18//!     max_retries: 3,
19//!     retry_interval_ms: 50,
20//!     fragment_size: 1200,
21//!     flow_window_size: 32,
22//! };
23//! ```
24//!
25//! [`VCLConnection`]: crate::connection::VCLConnection
26
27/// Transport protocol used by the connection.
28///
29/// Controls whether VCL uses TCP or UDP as the underlying transport.
30/// In `Auto` mode, VCL selects the transport based on the [`ReliabilityMode`].
31#[derive(Debug, Clone, PartialEq)]
32pub enum TransportMode {
33    /// TCP transport — reliable, ordered delivery.
34    /// Best for VPN tunnels, file transfer, audit logging.
35    Tcp,
36
37    /// UDP transport — low latency, unordered.
38    /// Best for gaming, real-time audio/video, telemetry.
39    Udp,
40
41    /// VCL automatically selects TCP or UDP based on [`ReliabilityMode`]:
42    /// - `Reliable` → TCP
43    /// - `Partial` / `Unreliable` → UDP
44    /// - `Adaptive` → starts UDP, upgrades to TCP on packet loss
45    Auto,
46}
47
48/// Reliability guarantee for packet delivery.
49///
50/// Controls retransmission behaviour and how VCL reacts to packet loss.
51#[derive(Debug, Clone, PartialEq)]
52pub enum ReliabilityMode {
53    /// Every packet is delivered exactly once, in order.
54    /// Lost packets are retransmitted up to [`VCLConfig::max_retries`] times.
55    /// Best for VPN, file transfer, financial transactions.
56    Reliable,
57
58    /// Only packets marked as critical are retransmitted.
59    /// Non-critical packets (e.g. position updates) are dropped on loss.
60    /// Best for gaming where old state is irrelevant.
61    Partial,
62
63    /// No retransmission. Lost packets are dropped silently.
64    /// Best for video/audio streaming where latency matters more than completeness.
65    Unreliable,
66
67    /// VCL monitors network conditions and adjusts retransmission dynamically.
68    /// Starts in `Unreliable` mode, ramps up reliability on detected loss.
69    /// Recommended default for unknown network conditions.
70    Adaptive,
71}
72
73/// Full configuration for a VCL connection.
74///
75/// Controls transport, reliability, fragmentation, and flow control behaviour.
76/// Use one of the preset constructors or build a custom config.
77///
78/// # Presets
79///
80/// | Preset | Transport | Reliability | Use case |
81/// |--------|-----------|-------------|----------|
82/// | `vpn()` | TCP | Reliable | VPN tunnels, secure comms |
83/// | `gaming()` | UDP | Partial | Real-time games |
84/// | `streaming()` | UDP | Unreliable | Video/audio streaming |
85/// | `auto()` | Auto | Adaptive | Unknown / mixed traffic |
86#[derive(Debug, Clone)]
87pub struct VCLConfig {
88    /// Transport protocol to use.
89    pub transport: TransportMode,
90
91    /// Reliability guarantee for packet delivery.
92    pub reliability: ReliabilityMode,
93
94    /// Maximum number of retransmission attempts for lost packets.
95    /// Only used when `reliability` is `Reliable` or `Partial`.
96    /// Default: `5`
97    pub max_retries: u32,
98
99    /// Time in milliseconds between retransmission attempts.
100    /// Default: `100`
101    pub retry_interval_ms: u64,
102
103    /// Maximum payload size per fragment in bytes.
104    /// Packets larger than this are split into multiple fragments.
105    /// Default: `1200` (safe for most networks including VPN overhead)
106    pub fragment_size: usize,
107
108    /// Number of packets that can be in-flight simultaneously (flow control window).
109    /// Default: `64`
110    pub flow_window_size: usize,
111}
112
113impl VCLConfig {
114    /// **VPN mode** — reliability over speed.
115    ///
116    /// Uses TCP with guaranteed delivery. Every packet is retransmitted on loss.
117    /// Suitable for VPN tunnels, secure communications, financial transactions.
118    ///
119    /// ```rust
120    /// use vcl_protocol::config::{VCLConfig, TransportMode, ReliabilityMode};
121    ///
122    /// let config = VCLConfig::vpn();
123    /// assert_eq!(config.transport, TransportMode::Tcp);
124    /// assert_eq!(config.reliability, ReliabilityMode::Reliable);
125    /// ```
126    pub fn vpn() -> Self {
127        VCLConfig {
128            transport: TransportMode::Tcp,
129            reliability: ReliabilityMode::Reliable,
130            max_retries: 10,
131            retry_interval_ms: 100,
132            fragment_size: 1200,
133            flow_window_size: 64,
134        }
135    }
136
137    /// **Gaming mode** — speed over reliability.
138    ///
139    /// Uses UDP with partial reliability. Only critical packets are retransmitted.
140    /// Suitable for real-time games, position updates, input events.
141    ///
142    /// ```rust
143    /// use vcl_protocol::config::{VCLConfig, TransportMode, ReliabilityMode};
144    ///
145    /// let config = VCLConfig::gaming();
146    /// assert_eq!(config.transport, TransportMode::Udp);
147    /// assert_eq!(config.reliability, ReliabilityMode::Partial);
148    /// ```
149    pub fn gaming() -> Self {
150        VCLConfig {
151            transport: TransportMode::Udp,
152            reliability: ReliabilityMode::Partial,
153            max_retries: 2,
154            retry_interval_ms: 16,
155            fragment_size: 1400,
156            flow_window_size: 128,
157        }
158    }
159
160    /// **Streaming mode** — lowest latency, no retransmission.
161    ///
162    /// Uses UDP with no reliability guarantees. Lost packets are dropped silently.
163    /// Suitable for video/audio streaming where a missed frame is better than lag.
164    ///
165    /// ```rust
166    /// use vcl_protocol::config::{VCLConfig, TransportMode, ReliabilityMode};
167    ///
168    /// let config = VCLConfig::streaming();
169    /// assert_eq!(config.transport, TransportMode::Udp);
170    /// assert_eq!(config.reliability, ReliabilityMode::Unreliable);
171    /// ```
172    pub fn streaming() -> Self {
173        VCLConfig {
174            transport: TransportMode::Udp,
175            reliability: ReliabilityMode::Unreliable,
176            max_retries: 0,
177            retry_interval_ms: 0,
178            fragment_size: 1400,
179            flow_window_size: 256,
180        }
181    }
182
183    /// **Auto mode** — recommended default.
184    ///
185    /// VCL selects transport and reliability dynamically based on network conditions.
186    /// Starts with UDP, upgrades to TCP on detected packet loss.
187    ///
188    /// ```rust
189    /// use vcl_protocol::config::{VCLConfig, TransportMode, ReliabilityMode};
190    ///
191    /// let config = VCLConfig::auto();
192    /// assert_eq!(config.transport, TransportMode::Auto);
193    /// assert_eq!(config.reliability, ReliabilityMode::Adaptive);
194    /// ```
195    pub fn auto() -> Self {
196        VCLConfig {
197            transport: TransportMode::Auto,
198            reliability: ReliabilityMode::Adaptive,
199            max_retries: 5,
200            retry_interval_ms: 100,
201            fragment_size: 1200,
202            flow_window_size: 64,
203        }
204    }
205
206    /// Returns `true` if this config uses TCP transport or will select TCP in Auto mode.
207    pub fn is_tcp(&self) -> bool {
208        self.transport == TransportMode::Tcp
209            || (self.transport == TransportMode::Auto
210                && self.reliability == ReliabilityMode::Reliable)
211    }
212
213    /// Returns `true` if retransmission is enabled for this config.
214    pub fn has_retransmission(&self) -> bool {
215        matches!(
216            self.reliability,
217            ReliabilityMode::Reliable | ReliabilityMode::Partial | ReliabilityMode::Adaptive
218        )
219    }
220
221    /// Returns `true` if fragmentation is needed for a payload of `size` bytes.
222    pub fn needs_fragmentation(&self, size: usize) -> bool {
223        size > self.fragment_size
224    }
225}
226
227impl Default for VCLConfig {
228    /// Default config is [`VCLConfig::auto()`].
229    fn default() -> Self {
230        Self::auto()
231    }
232}
233
234#[cfg(test)]
235mod tests {
236    use super::*;
237
238    #[test]
239    fn test_vpn_preset() {
240        let c = VCLConfig::vpn();
241        assert_eq!(c.transport, TransportMode::Tcp);
242        assert_eq!(c.reliability, ReliabilityMode::Reliable);
243        assert!(c.has_retransmission());
244        assert!(c.is_tcp());
245    }
246
247    #[test]
248    fn test_gaming_preset() {
249        let c = VCLConfig::gaming();
250        assert_eq!(c.transport, TransportMode::Udp);
251        assert_eq!(c.reliability, ReliabilityMode::Partial);
252        assert!(c.has_retransmission());
253        assert!(!c.is_tcp());
254    }
255
256    #[test]
257    fn test_streaming_preset() {
258        let c = VCLConfig::streaming();
259        assert_eq!(c.transport, TransportMode::Udp);
260        assert_eq!(c.reliability, ReliabilityMode::Unreliable);
261        assert!(!c.has_retransmission());
262        assert!(!c.is_tcp());
263    }
264
265    #[test]
266    fn test_auto_preset() {
267        let c = VCLConfig::auto();
268        assert_eq!(c.transport, TransportMode::Auto);
269        assert_eq!(c.reliability, ReliabilityMode::Adaptive);
270        assert!(c.has_retransmission());
271    }
272
273    #[test]
274    fn test_default_is_auto() {
275        let c = VCLConfig::default();
276        assert_eq!(c.transport, TransportMode::Auto);
277    }
278
279    #[test]
280    fn test_needs_fragmentation() {
281        let c = VCLConfig::vpn(); // fragment_size = 1200
282        assert!(!c.needs_fragmentation(1000));
283        assert!(!c.needs_fragmentation(1200));
284        assert!(c.needs_fragmentation(1201));
285        assert!(c.needs_fragmentation(65535));
286    }
287
288    #[test]
289    fn test_custom_config() {
290        let c = VCLConfig {
291            transport: TransportMode::Udp,
292            reliability: ReliabilityMode::Partial,
293            max_retries: 3,
294            retry_interval_ms: 50,
295            fragment_size: 800,
296            flow_window_size: 32,
297        };
298        assert_eq!(c.transport, TransportMode::Udp);
299        assert!(c.needs_fragmentation(801));
300        assert!(!c.needs_fragmentation(800));
301    }
302}