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