Skip to main content

saorsa_core/
transport.rs

1// Copyright 2024 Saorsa Labs Limited
2//
3// This software is dual-licensed under:
4// - GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later)
5// - Commercial License
6//
7// For AGPL-3.0 license, see LICENSE-AGPL-3.0
8// For commercial licensing, contact: david@saorsalabs.com
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under these licenses is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
14//! Transport Layer
15//!
16//! This module provides native ant-quic integration for the P2P Foundation.
17//!
18//! Use `ant_quic_adapter::P2PNetworkNode` directly for all networking needs.
19
20// Native ant-quic integration with advanced NAT traversal and PQC support
21pub mod ant_quic_adapter;
22
23// DHT protocol handler for SharedTransport integration
24pub mod dht_handler;
25
26use crate::validation::{Validate, ValidationContext, validate_message_size, validate_peer_id};
27use crate::{P2PError, PeerId, Result};
28use serde::{Deserialize, Serialize};
29use std::collections::HashMap;
30use std::fmt;
31use std::time::{Duration, Instant};
32
33/// Transport protocol types
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
35pub enum TransportType {
36    /// QUIC transport protocol with NAT traversal
37    QUIC,
38}
39
40/// Transport selection strategy (simplified for QUIC-only)
41#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
42pub enum TransportSelection {
43    /// Use QUIC transport (default and only option)
44    #[default]
45    QUIC,
46}
47
48/// Connection quality metrics
49#[derive(Debug, Clone)]
50pub struct ConnectionQuality {
51    /// Round-trip latency
52    pub latency: Duration,
53    /// Throughput in Mbps
54    pub throughput_mbps: f64,
55    /// Packet loss percentage
56    pub packet_loss: f64,
57    /// Jitter (latency variation)
58    pub jitter: Duration,
59    /// Connection establishment time
60    pub connect_time: Duration,
61}
62
63/// Connection information
64#[derive(Debug, Clone)]
65pub struct ConnectionInfo {
66    /// Transport type being used
67    pub transport_type: TransportType,
68    /// Local address
69    pub local_addr: crate::NetworkAddress,
70    /// Remote address
71    pub remote_addr: crate::NetworkAddress,
72    /// Whether connection is encrypted
73    pub is_encrypted: bool,
74    /// Cipher suite being used
75    pub cipher_suite: String,
76    /// Whether 0-RTT was used
77    pub used_0rtt: bool,
78    /// Connection establishment time
79    pub established_at: Instant,
80    /// Last activity timestamp
81    pub last_activity: Instant,
82}
83
84/// Connection pool information
85#[derive(Debug, Clone)]
86pub struct ConnectionPoolInfo {
87    /// Number of active connections
88    pub active_connections: usize,
89    /// Total connections ever created
90    pub total_connections: usize,
91    /// Bytes sent through pool
92    pub bytes_sent: u64,
93    /// Bytes received through pool
94    pub bytes_received: u64,
95}
96
97/// Connection pool statistics
98#[derive(Debug, Clone)]
99pub struct ConnectionPoolStats {
100    /// Messages sent per connection
101    pub messages_per_connection: HashMap<String, usize>,
102    /// Bytes per connection
103    pub bytes_per_connection: HashMap<String, u64>,
104    /// Average latency per connection
105    pub latency_per_connection: HashMap<String, Duration>,
106}
107
108/// Message received from transport
109#[derive(Debug, Clone)]
110pub struct TransportMessage {
111    /// Sender peer ID
112    pub sender: PeerId,
113    /// Message data
114    pub data: Vec<u8>,
115    /// Protocol identifier
116    pub protocol: String,
117    /// Timestamp when received
118    pub received_at: Instant,
119}
120
121impl Validate for TransportMessage {
122    fn validate(&self, ctx: &ValidationContext) -> Result<()> {
123        // Validate sender peer ID
124        validate_peer_id(&self.sender)?;
125
126        // Validate message size
127        validate_message_size(self.data.len(), ctx.max_message_size)?;
128
129        // Validate protocol identifier
130        if self.protocol.is_empty() || self.protocol.len() > 64 {
131            return Err(P2PError::validation("Invalid protocol identifier"));
132        }
133
134        Ok(())
135    }
136}
137
138/// Transport configuration options
139#[derive(Debug, Clone)]
140pub struct TransportOptions {
141    /// Enable 0-RTT for QUIC
142    pub enable_0rtt: bool,
143    /// Force encryption
144    pub require_encryption: bool,
145    /// Connection timeout
146    pub connect_timeout: Duration,
147    /// Keep-alive interval
148    pub keep_alive: Duration,
149    /// Maximum message size
150    pub max_message_size: usize,
151}
152
153impl fmt::Display for TransportType {
154    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155        match self {
156            TransportType::QUIC => write!(f, "quic"),
157        }
158    }
159}
160
161impl Default for TransportOptions {
162    fn default() -> Self {
163        Self {
164            enable_0rtt: true,
165            require_encryption: true,
166            connect_timeout: Duration::from_secs(30),
167            keep_alive: Duration::from_secs(60),
168            max_message_size: 64 * 1024 * 1024, // 64MB
169        }
170    }
171}
172
173impl Default for ConnectionQuality {
174    fn default() -> Self {
175        Self {
176            latency: Duration::from_millis(50),
177            throughput_mbps: 100.0,
178            packet_loss: 0.0,
179            jitter: Duration::from_millis(5),
180            connect_time: Duration::from_millis(100),
181        }
182    }
183}
184
185/// Legacy transport types module for backward compatibility
186pub mod transport_types {
187    pub use super::TransportType;
188}
189
190#[cfg(test)]
191mod tests {
192    use super::*;
193
194    #[test]
195    fn test_transport_type_display() {
196        assert_eq!(format!("{}", TransportType::QUIC), "quic");
197    }
198
199    #[test]
200    fn test_transport_type_serialization() {
201        let quic_type = TransportType::QUIC;
202        assert_eq!(quic_type, TransportType::QUIC);
203    }
204
205    #[test]
206    fn test_transport_selection_variants() {
207        let quic_selection = TransportSelection::QUIC;
208        assert!(matches!(quic_selection, TransportSelection::QUIC));
209    }
210
211    #[test]
212    fn test_transport_selection_default() {
213        let default = TransportSelection::default();
214        assert!(matches!(default, TransportSelection::QUIC));
215    }
216
217    #[test]
218    fn test_transport_options_default() {
219        let options = TransportOptions::default();
220
221        assert!(options.enable_0rtt);
222        assert!(options.require_encryption);
223        assert_eq!(options.connect_timeout, Duration::from_secs(30));
224        assert_eq!(options.keep_alive, Duration::from_secs(60));
225        assert_eq!(options.max_message_size, 64 * 1024 * 1024);
226    }
227
228    #[test]
229    fn test_connection_quality_default() {
230        let quality = ConnectionQuality::default();
231
232        assert_eq!(quality.latency, Duration::from_millis(50));
233        assert_eq!(quality.throughput_mbps, 100.0);
234        assert_eq!(quality.packet_loss, 0.0);
235        assert_eq!(quality.jitter, Duration::from_millis(5));
236        assert_eq!(quality.connect_time, Duration::from_millis(100));
237    }
238
239    #[test]
240    fn test_transport_options_configuration() {
241        let options = TransportOptions {
242            enable_0rtt: false,
243            require_encryption: false,
244            connect_timeout: Duration::from_secs(10),
245            keep_alive: Duration::from_secs(30),
246            max_message_size: 1024,
247        };
248
249        assert!(!options.enable_0rtt);
250        assert!(!options.require_encryption);
251        assert_eq!(options.connect_timeout, Duration::from_secs(10));
252        assert_eq!(options.keep_alive, Duration::from_secs(30));
253        assert_eq!(options.max_message_size, 1024);
254    }
255
256    #[test]
257    fn test_transport_message_structure() {
258        let message = TransportMessage {
259            sender: "test_peer".to_string(),
260            data: vec![1, 2, 3, 4],
261            protocol: "/p2p/test/1.0.0".to_string(),
262            received_at: Instant::now(),
263        };
264
265        assert_eq!(message.sender, "test_peer");
266        assert_eq!(message.data, vec![1, 2, 3, 4]);
267        assert_eq!(message.protocol, "/p2p/test/1.0.0");
268    }
269}