ant_quic/
lib.rs

1//! ant-quic: QUIC transport protocol with advanced NAT traversal for P2P networks
2//!
3//! This library provides a clean, modular implementation of QUIC-native NAT traversal
4//! using raw public keys for authentication. It is designed to be minimal, focused,
5//! and highly testable, with exceptional cross-platform support.
6//!
7//! The library is organized into the following main modules:
8//! - `transport`: Core QUIC transport functionality
9//! - `nat_traversal`: QUIC-native NAT traversal protocol
10//! - `discovery`: Platform-specific network interface discovery
11//! - `crypto`: Raw public key authentication
12//! - `api`: High-level P2P networking API
13
14// TODO: Re-enable after fixing all missing documentation
15// #![cfg_attr(not(fuzzing), warn(missing_docs))]
16#![allow(missing_docs)]
17#![allow(unreachable_pub)]
18#![allow(clippy::cognitive_complexity)]
19#![allow(clippy::too_many_arguments)]
20#![allow(clippy::use_self)]
21// FIXME: Temporary allows to get CI passing quickly
22// These should be gradually removed as the codebase is cleaned up
23// Priority items to fix:
24// 1. Re-enable missing_docs and document all public items
25// 2. Fix dead_code warnings by removing unused code
26// 3. Fix clippy style issues (field names, formatting, etc)
27// 4. Enable proper error handling instead of allowing unused_must_use
28#![allow(dead_code)]
29#![allow(clippy::field_reassign_with_default)]
30#![allow(clippy::module_inception)]
31#![allow(clippy::useless_vec)]
32#![allow(private_interfaces)]
33#![allow(clippy::upper_case_acronyms)]
34#![allow(clippy::type_complexity)]
35#![allow(clippy::manual_clamp)]
36#![allow(clippy::needless_range_loop)]
37#![allow(clippy::borrowed_box)]
38#![allow(clippy::manual_strip)]
39#![allow(clippy::if_same_then_else)]
40#![allow(clippy::ptr_arg)]
41#![allow(clippy::incompatible_msrv)]
42#![allow(clippy::await_holding_lock)]
43#![allow(clippy::single_match)]
44#![allow(clippy::must_use_candidate)]
45#![allow(clippy::let_underscore_must_use)]
46#![allow(clippy::let_underscore_untyped)]
47#![allow(clippy::large_enum_variant)]
48#![allow(clippy::too_many_lines)]
49#![allow(clippy::result_large_err)]
50#![allow(clippy::enum_glob_use)]
51#![allow(clippy::match_like_matches_macro)]
52#![allow(clippy::struct_field_names)]
53#![allow(clippy::cast_precision_loss)]
54#![allow(clippy::cast_sign_loss)]
55#![allow(clippy::cast_possible_wrap)]
56#![allow(clippy::cast_possible_truncation)]
57#![allow(clippy::unnecessary_wraps)]
58#![allow(clippy::doc_markdown)]
59#![allow(clippy::module_name_repetitions)]
60#![allow(clippy::items_after_statements)]
61#![allow(clippy::missing_panics_doc)]
62#![allow(clippy::missing_errors_doc)]
63#![allow(clippy::similar_names)]
64#![allow(clippy::new_without_default)]
65#![allow(clippy::unwrap_or_default)]
66#![allow(clippy::uninlined_format_args)]
67#![allow(clippy::redundant_field_names)]
68#![allow(clippy::redundant_closure_for_method_calls)]
69#![allow(clippy::redundant_pattern_matching)]
70#![allow(clippy::option_if_let_else)]
71#![allow(clippy::trivially_copy_pass_by_ref)]
72#![allow(clippy::len_without_is_empty)]
73#![allow(clippy::explicit_auto_deref)]
74#![allow(clippy::blocks_in_conditions)]
75#![allow(clippy::collapsible_else_if)]
76#![allow(clippy::collapsible_if)]
77#![allow(clippy::unnecessary_cast)]
78#![allow(clippy::needless_bool)]
79#![allow(clippy::needless_borrow)]
80#![allow(clippy::redundant_static_lifetimes)]
81#![allow(clippy::match_ref_pats)]
82#![allow(clippy::should_implement_trait)]
83#![allow(clippy::wildcard_imports)]
84#![allow(unused_must_use)]
85#![allow(improper_ctypes)]
86#![allow(improper_ctypes_definitions)]
87#![allow(non_upper_case_globals)]
88#![allow(clippy::wrong_self_convention)]
89#![allow(clippy::vec_init_then_push)]
90#![allow(clippy::format_in_format_args)]
91#![allow(clippy::from_over_into)]
92#![allow(clippy::useless_conversion)]
93#![allow(clippy::never_loop)]
94#![allow(dropping_references)]
95#![allow(non_snake_case)]
96#![allow(clippy::unnecessary_literal_unwrap)]
97#![allow(clippy::assertions_on_constants)]
98#![allow(unused_imports)]
99
100use std::{
101    fmt,
102    net::{IpAddr, SocketAddr},
103    ops,
104};
105
106// Core modules
107mod cid_queue;
108pub mod coding;
109mod constant_time;
110mod range_set;
111pub mod transport_parameters;
112mod varint;
113
114pub use varint::{VarInt, VarIntBoundsExceeded};
115
116// Removed optional bloom module
117
118// Core implementation modules
119/// Configuration structures and validation
120pub mod config;
121/// QUIC connection state machine and management
122pub mod connection;
123/// QUIC endpoint for accepting and initiating connections
124pub mod endpoint;
125/// QUIC frame types and encoding/decoding
126pub mod frame;
127/// QUIC packet structures and processing
128pub mod packet;
129/// Shared types and utilities
130pub mod shared;
131/// Transport error types and codes
132pub mod transport_error;
133// Simplified congestion control
134/// Network candidate discovery and management
135pub mod candidate_discovery;
136/// Connection ID generation strategies
137pub mod cid_generator;
138mod congestion;
139mod protocol_violations;
140#[cfg(test)]
141mod protocol_violations_tests;
142
143// Zero-cost tracing system
144mod connection_establishment_simple;
145/// High-level NAT traversal API
146pub mod nat_traversal_api;
147mod token;
148mod token_memory_cache;
149/// Zero-cost tracing and event logging system
150pub mod tracing;
151
152// Public modules with new structure
153/// High-level API for QUIC operations
154pub mod api;
155/// Cryptographic operations and raw public key support
156pub mod crypto;
157/// Platform-specific network interface discovery
158pub mod discovery;
159/// NAT traversal protocol implementation
160pub mod nat_traversal;
161/// Transport-level protocol implementation
162pub mod transport;
163
164// Additional modules
165/// Peer authentication system
166pub mod auth;
167/// Secure chat protocol implementation
168pub mod chat;
169/// Performance optimization utilities
170pub mod optimization;
171/// High-level QUIC P2P node implementation
172pub mod quic_node;
173/// Real-time statistics dashboard
174pub mod stats_dashboard;
175/// Terminal user interface components
176pub mod terminal_ui;
177
178// Compliance validation framework
179/// IETF compliance validation tools
180pub mod compliance_validator;
181
182// Comprehensive logging system
183/// Structured logging and diagnostics
184pub mod logging;
185
186// High-level async API modules (ported from quinn crate)
187pub mod high_level;
188
189// Re-export high-level API types for easier usage
190pub use high_level::{
191    Accept, Connecting, Connection as HighLevelConnection, Endpoint,
192    RecvStream as HighLevelRecvStream, SendStream as HighLevelSendStream,
193};
194
195// Re-export crypto utilities for peer ID management
196pub use crypto::raw_public_keys::key_utils::{
197    derive_peer_id_from_key_bytes, derive_peer_id_from_public_key, generate_ed25519_keypair,
198    public_key_from_bytes, public_key_to_bytes, verify_peer_id,
199};
200
201// Re-export key types for backward compatibility
202pub use candidate_discovery::{
203    CandidateDiscoveryManager, DiscoveryConfig, DiscoveryError, DiscoveryEvent, NetworkInterface,
204    ValidatedCandidate,
205};
206pub use connection::nat_traversal::{CandidateSource, CandidateState, NatTraversalRole};
207pub use connection::{
208    Chunk, Chunks, ClosedStream, Connection, ConnectionError, ConnectionStats, Datagrams, Event,
209    FinishError, ReadError, ReadableError, RecvStream, SendDatagramError, SendStream, StreamEvent,
210    Streams, WriteError, Written,
211};
212pub use connection_establishment_simple::{
213    SimpleConnectionEstablishmentManager, SimpleConnectionEvent, SimpleEstablishmentConfig,
214};
215pub use endpoint::{
216    AcceptError, ConnectError, ConnectionHandle, DatagramEvent, Endpoint as LowLevelEndpoint,
217    Incoming,
218};
219pub use nat_traversal_api::{
220    BootstrapNode, CandidateAddress, EndpointRole, NatTraversalConfig, NatTraversalEndpoint,
221    NatTraversalError, NatTraversalEvent, NatTraversalStatistics, PeerId,
222};
223pub use quic_node::{NodeStats as QuicNodeStats, QuicNodeConfig, QuicP2PNode};
224pub use shared::{ConnectionId, EcnCodepoint, EndpointEvent};
225pub use transport_error::{Code as TransportErrorCode, Error as TransportError};
226
227// #[cfg(fuzzing)]
228// pub mod fuzzing; // Module not implemented yet
229
230/// The QUIC protocol version implemented.
231///
232/// Simplified to include only the essential versions:
233/// - 0x00000001: QUIC v1 (RFC 9000)
234/// - 0xff00_001d: Draft 29
235pub const DEFAULT_SUPPORTED_VERSIONS: &[u32] = &[
236    0x00000001,  // QUIC v1 (RFC 9000)
237    0xff00_001d, // Draft 29
238];
239
240/// Whether an endpoint was the initiator of a connection
241#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
242#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
243pub enum Side {
244    /// The initiator of a connection
245    Client = 0,
246    /// The acceptor of a connection
247    Server = 1,
248}
249
250impl Side {
251    #[inline]
252    /// Shorthand for `self == Side::Client`
253    pub fn is_client(self) -> bool {
254        self == Self::Client
255    }
256
257    #[inline]
258    /// Shorthand for `self == Side::Server`
259    pub fn is_server(self) -> bool {
260        self == Self::Server
261    }
262}
263
264impl ops::Not for Side {
265    type Output = Self;
266    fn not(self) -> Self {
267        match self {
268            Self::Client => Self::Server,
269            Self::Server => Self::Client,
270        }
271    }
272}
273
274/// Whether a stream communicates data in both directions or only from the initiator
275#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
276#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
277pub enum Dir {
278    /// Data flows in both directions
279    Bi = 0,
280    /// Data flows only from the stream's initiator
281    Uni = 1,
282}
283
284impl Dir {
285    fn iter() -> impl Iterator<Item = Self> {
286        [Self::Bi, Self::Uni].iter().cloned()
287    }
288}
289
290impl fmt::Display for Dir {
291    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
292        use Dir::*;
293        f.pad(match *self {
294            Bi => "bidirectional",
295            Uni => "unidirectional",
296        })
297    }
298}
299
300/// Identifier for a stream within a particular connection
301#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
302#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
303pub struct StreamId(u64);
304
305impl fmt::Display for StreamId {
306    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
307        let initiator = match self.initiator() {
308            Side::Client => "client",
309            Side::Server => "server",
310        };
311        let dir = match self.dir() {
312            Dir::Uni => "uni",
313            Dir::Bi => "bi",
314        };
315        write!(
316            f,
317            "{} {}directional stream {}",
318            initiator,
319            dir,
320            self.index()
321        )
322    }
323}
324
325impl StreamId {
326    /// Create a new StreamId
327    pub fn new(initiator: Side, dir: Dir, index: u64) -> Self {
328        Self((index << 2) | ((dir as u64) << 1) | initiator as u64)
329    }
330    /// Which side of a connection initiated the stream
331    pub fn initiator(self) -> Side {
332        if self.0 & 0x1 == 0 {
333            Side::Client
334        } else {
335            Side::Server
336        }
337    }
338    /// Which directions data flows in
339    pub fn dir(self) -> Dir {
340        if self.0 & 0x2 == 0 { Dir::Bi } else { Dir::Uni }
341    }
342    /// Distinguishes streams of the same initiator and directionality
343    pub fn index(self) -> u64 {
344        self.0 >> 2
345    }
346}
347
348impl From<StreamId> for VarInt {
349    fn from(x: StreamId) -> Self {
350        unsafe { Self::from_u64_unchecked(x.0) }
351    }
352}
353
354impl From<VarInt> for StreamId {
355    fn from(v: VarInt) -> Self {
356        Self(v.0)
357    }
358}
359
360impl From<StreamId> for u64 {
361    fn from(x: StreamId) -> Self {
362        x.0
363    }
364}
365
366impl coding::Codec for StreamId {
367    fn decode<B: bytes::Buf>(buf: &mut B) -> coding::Result<Self> {
368        VarInt::decode(buf).map(|x| Self(x.into_inner()))
369    }
370    fn encode<B: bytes::BufMut>(&self, buf: &mut B) {
371        VarInt::from_u64(self.0).unwrap().encode(buf);
372    }
373}
374
375/// An outgoing packet
376#[derive(Debug)]
377#[must_use]
378pub struct Transmit {
379    /// The socket this datagram should be sent to
380    pub destination: SocketAddr,
381    /// Explicit congestion notification bits to set on the packet
382    pub ecn: Option<EcnCodepoint>,
383    /// Amount of data written to the caller-supplied buffer
384    pub size: usize,
385    /// The segment size if this transmission contains multiple datagrams.
386    /// This is `None` if the transmit only contains a single datagram
387    pub segment_size: Option<usize>,
388    /// Optional source IP address for the datagram
389    pub src_ip: Option<IpAddr>,
390}
391
392// Deal with time
393#[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
394pub(crate) use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
395#[cfg(all(target_family = "wasm", target_os = "unknown"))]
396pub(crate) use web_time::{Duration, Instant, SystemTime, UNIX_EPOCH};
397
398//
399// Useful internal constants
400//
401
402/// The maximum number of CIDs we bother to issue per connection
403pub(crate) const LOC_CID_COUNT: u64 = 8;
404pub(crate) const RESET_TOKEN_SIZE: usize = 16;
405pub(crate) const MAX_CID_SIZE: usize = 20;
406pub(crate) const MIN_INITIAL_SIZE: u16 = 1200;
407/// <https://www.rfc-editor.org/rfc/rfc9000.html#name-datagram-size>
408pub(crate) const INITIAL_MTU: u16 = 1200;
409pub(crate) const MAX_UDP_PAYLOAD: u16 = 65527;
410pub(crate) const TIMER_GRANULARITY: Duration = Duration::from_millis(1);
411/// Maximum number of streams that can be tracked per connection
412pub(crate) const MAX_STREAM_COUNT: u64 = 1 << 60;
413
414// Internal type re-exports for crate modules
415pub use cid_generator::RandomConnectionIdGenerator;
416pub use config::{
417    AckFrequencyConfig, ClientConfig, EndpointConfig, MtuDiscoveryConfig, ServerConfig,
418    TransportConfig,
419};
420pub(crate) use frame::Frame;
421pub(crate) use token::{NoneTokenLog, ResetToken, TokenLog, TokenStore};
422pub(crate) use token_memory_cache::TokenMemoryCache;