ant-quic 0.27.4

QUIC transport protocol with advanced NAT traversal for P2P networks
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
// Copyright 2024 Saorsa Labs Ltd.
//
// This Saorsa Network Software is licensed under the General Public License (GPL), version 3.
// Please see the file LICENSE-GPL, or visit <http://www.gnu.org/licenses/> for the full text.
//
// Full details available at https://saorsalabs.com/licenses

//! ant-quic: QUIC transport protocol with advanced NAT traversal for P2P networks
#![allow(elided_lifetimes_in_paths)]
#![allow(missing_debug_implementations)]
#![allow(clippy::manual_is_multiple_of)]
//!
//! This library provides a clean, modular implementation of QUIC-native NAT traversal
//! using raw public keys for authentication. It is designed to be minimal, focused,
//! and highly testable, with exceptional cross-platform support.
//!
//! The library is organized into the following main modules:
//! - `transport`: Core QUIC transport functionality
//! - `nat_traversal`: QUIC-native NAT traversal protocol
//! - `discovery`: Platform-specific network interface discovery
//! - `crypto`: Raw public key authentication
//! - `trust`: Trust management with TOFU pinning and channel binding

// Documentation warnings enabled - all public APIs must be documented
#![cfg_attr(not(fuzzing), warn(missing_docs))]
#![allow(unreachable_pub)]
#![allow(clippy::cognitive_complexity)]
#![allow(clippy::too_many_arguments)]
#![allow(clippy::use_self)]
// Dead code warnings enabled - remove unused code
#![warn(dead_code)]
#![allow(clippy::field_reassign_with_default)]
#![allow(clippy::module_inception)]
#![allow(clippy::useless_vec)]
#![allow(private_interfaces)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::type_complexity)]
#![allow(clippy::manual_clamp)]
#![allow(clippy::needless_range_loop)]
#![allow(clippy::borrowed_box)]
#![allow(clippy::manual_strip)]
#![allow(clippy::if_same_then_else)]
#![allow(clippy::ptr_arg)]
#![allow(clippy::incompatible_msrv)]
#![allow(clippy::await_holding_lock)]
#![allow(clippy::single_match)]
#![allow(clippy::must_use_candidate)]
#![allow(clippy::let_underscore_must_use)]
#![allow(clippy::let_underscore_untyped)]
#![allow(clippy::large_enum_variant)]
#![allow(clippy::too_many_lines)]
#![allow(clippy::result_large_err)]
#![allow(clippy::enum_glob_use)]
#![allow(clippy::match_like_matches_macro)]
#![allow(clippy::struct_field_names)]
#![allow(clippy::cast_precision_loss)]
#![allow(clippy::cast_sign_loss)]
#![allow(clippy::cast_possible_wrap)]
#![allow(clippy::cast_possible_truncation)]
#![allow(clippy::unnecessary_wraps)]
#![allow(clippy::doc_markdown)]
#![allow(clippy::module_name_repetitions)]
#![allow(clippy::items_after_statements)]
#![allow(clippy::missing_panics_doc)]
#![allow(clippy::missing_errors_doc)]
#![allow(clippy::similar_names)]
#![allow(clippy::new_without_default)]
#![allow(clippy::unwrap_or_default)]
#![allow(clippy::uninlined_format_args)]
#![allow(clippy::redundant_field_names)]
#![allow(clippy::redundant_closure_for_method_calls)]
#![allow(clippy::redundant_pattern_matching)]
#![allow(clippy::option_if_let_else)]
#![allow(clippy::trivially_copy_pass_by_ref)]
#![allow(clippy::len_without_is_empty)]
#![allow(clippy::explicit_auto_deref)]
#![allow(clippy::blocks_in_conditions)]
#![allow(clippy::collapsible_else_if)]
#![allow(clippy::collapsible_if)]
#![allow(clippy::unnecessary_cast)]
#![allow(clippy::needless_bool)]
#![allow(clippy::needless_borrow)]
#![allow(clippy::redundant_static_lifetimes)]
#![allow(clippy::match_ref_pats)]
#![allow(clippy::should_implement_trait)]
#![allow(clippy::wildcard_imports)]
#![warn(unused_must_use)]
#![allow(improper_ctypes)]
#![allow(improper_ctypes_definitions)]
#![allow(non_upper_case_globals)]
#![allow(clippy::wrong_self_convention)]
#![allow(clippy::vec_init_then_push)]
#![allow(clippy::format_in_format_args)]
#![allow(clippy::from_over_into)]
#![allow(clippy::useless_conversion)]
#![allow(clippy::never_loop)]
#![allow(dropping_references)]
#![allow(non_snake_case)]
#![allow(clippy::unnecessary_literal_unwrap)]
#![allow(clippy::assertions_on_constants)]

use std::{
    fmt,
    net::{IpAddr, SocketAddr},
    ops,
};

// Core modules
mod ack_frame;
mod cid_queue;
pub mod coding;
mod constant_time;
mod range_set;
pub mod transport_parameters;
mod varint;

pub use varint::{VarInt, VarIntBoundsExceeded};

// Removed optional bloom module

/// Bounded pending data buffer with TTL expiration
pub mod bounded_pending_buffer;

/// RTT-based path selection with hysteresis
pub mod path_selection;

/// Coordinated shutdown for endpoints
pub mod shutdown;

/// Watchable state pattern for reactive observation
pub mod watchable;

/// Fair polling for multiple transports
pub mod fair_polling;

/// Graceful transport degradation
pub mod transport_resilience;

/// Connection strategy state machine for progressive NAT traversal fallback
pub mod connection_strategy;

/// RFC 8305 Happy Eyeballs v2 for parallel IPv4/IPv6 connection racing
pub mod happy_eyeballs;

/// Discovery trait for stream composition
pub mod discovery_trait;

/// Structured event logging for observability
pub mod structured_events;

// ============================================================================
// SIMPLE API - Zero Configuration P2P
// ============================================================================

/// Zero-configuration P2P node - THE PRIMARY API
///
/// Use [`Node`] for the simplest possible P2P experience:
/// ```rust,ignore
/// let node = Node::new().await?;
/// ```
pub mod node;

/// Minimal configuration for zero-config P2P nodes
pub mod node_config;

/// Consolidated node status for observability
pub mod node_status;

mod coordinator_control;
/// Circuit-breaker for NAT traversal coordinators.
pub(crate) mod coordinator_health;
/// First-party mDNS discovery state and query types
pub mod mdns;
/// Unified events for P2P nodes
pub mod node_event;
mod peer_directory;
mod port_mapping;

/// Reachability scope and traversal metadata shared across APIs
pub mod reachability;

// Core implementation modules
/// Configuration structures and validation
pub mod config;
/// QUIC connection state machine and management
pub mod connection;
/// QUIC endpoint for accepting and initiating connections
pub mod endpoint;
/// QUIC frame types and encoding/decoding
pub mod frame;
/// QUIC packet structures and processing
pub mod packet;
/// Shared types and utilities
pub mod shared;
/// Transport error types and codes
pub mod transport_error;
// Simplified congestion control
/// Network candidate discovery and management
pub mod candidate_discovery;
/// Connection ID generation strategies
pub mod cid_generator;
mod congestion;

// Zero-cost tracing system
/// High-level NAT traversal API
pub mod nat_traversal_api;
mod token;
mod token_memory_cache;
/// Zero-cost tracing and event logging system
pub mod tracing;

// Public modules with new structure
/// Constrained protocol engine for low-bandwidth transports (BLE, LoRa)
pub mod constrained;
/// Cryptographic operations and raw public key support
pub mod crypto;
/// Platform-specific network interface discovery
pub mod discovery;
/// NAT traversal protocol implementation
pub mod nat_traversal;
/// Transport-level protocol implementation
pub mod transport;

/// Connection router for automatic protocol engine selection (QUIC vs Constrained)
pub mod connection_router;

// Additional modules
// v0.2: auth module removed - TLS handles peer authentication via ML-DSA-65
/// Secure chat protocol implementation
pub mod chat;

// ============================================================================
// P2P API
// ============================================================================

/// Lifecycle close-reason helpers shared by the transport and P2P layers.
mod connection_lifecycle;

/// P2P endpoint - the primary API for ant-quic
///
/// This module provides the main API for P2P networking with NAT traversal,
/// connection management, and secure communication.
pub mod p2p_endpoint;

/// P2P configuration system
///
/// This module provides `P2pConfig` with builder pattern support for
/// configuring endpoints, NAT traversal, MTU, PQC, and other settings.
pub mod unified_config;

/// Real-time statistics dashboard
pub mod stats_dashboard;
/// Terminal user interface components
pub mod terminal_ui;

// Compliance validation framework
/// IETF compliance validation tools
pub mod compliance_validator;

// Comprehensive logging system
/// Structured logging and diagnostics
pub mod logging;

/// Metrics collection and export system (basic metrics always available)
pub mod metrics;

/// TURN-style relay protocol for NAT traversal fallback
pub mod relay;

/// MASQUE CONNECT-UDP Bind protocol for fully connectable P2P nodes
pub mod masque;

/// Transport trust module (TOFU, rotations, channel binding surfaces)
pub mod trust;

/// Address-validation tokens bound to (PeerId||CID||nonce)
pub mod token_v2;

// High-level async API modules (ported from quinn crate)
pub mod high_level;

// Re-export high-level API types for easier usage
pub use high_level::{
    Accept, Connecting, Connection as HighLevelConnection, Endpoint,
    RecvStream as HighLevelRecvStream, SendStream as HighLevelSendStream,
};

// Link transport abstraction layer for overlay networks
pub mod link_transport;
mod link_transport_impl;

// Re-export link transport types
pub use link_transport::{
    BoxFuture, BoxStream, BoxedHandler, Capabilities, ConnectionStats as LinkConnectionStats,
    DisconnectReason as LinkDisconnectReason, Incoming as LinkIncoming, LinkConn, LinkError,
    LinkEvent, LinkRecvStream, LinkResult, LinkSendStream, LinkTransport, NatHint, ProtocolHandler,
    ProtocolHandlerExt, ProtocolId, StreamFilter, StreamType, StreamTypeFamily,
};
pub use link_transport_impl::{
    P2pLinkConn, P2pLinkTransport, P2pRecvStream, P2pSendStream, SharedTransport,
};

// Bootstrap cache for peer persistence and quality-based selection
pub mod bootstrap_cache;
pub use bootstrap_cache::{
    BootstrapCache, BootstrapCacheConfig, BootstrapCacheConfigBuilder, CacheEvent, CacheStats,
    CachedPeer, ConnectionOutcome, ConnectionStats as CacheConnectionStats,
    NatType as CacheNatType, PeerCapabilities, PeerSource, QualityWeights, SelectionStrategy,
};

// Host identity for local-only HostKey management (ADR-007)
pub mod host_identity;
pub use host_identity::{EndpointKeyPolicy, HostIdentity, HostKeyStorage, StorageError};

// Re-export crypto utilities for peer ID management (v0.2: Pure PQC with ML-DSA-65)
pub use crypto::raw_public_keys::key_utils::{
    ML_DSA_65_PUBLIC_KEY_SIZE, ML_DSA_65_SECRET_KEY_SIZE, MlDsaPublicKey, MlDsaSecretKey,
    derive_peer_id_from_key_bytes, derive_peer_id_from_public_key, generate_ml_dsa_keypair,
    verify_peer_id,
};

// Re-export key types for backward compatibility
pub use candidate_discovery::{
    CandidateDiscoveryManager, DiscoveryConfig, DiscoveryError, DiscoveryEvent, NetworkInterface,
    ValidatedCandidate,
};
// v0.13.0: NatTraversalRole removed - all nodes are symmetric P2P nodes
pub use connection::nat_traversal::{CandidateSource, CandidateState};
pub use connection::{
    Chunk, Chunks, ClosedStream, Connection, ConnectionError, ConnectionStats, DatagramDropStats,
    Datagrams, Event, FinishError, ReadError, ReadableError, RecvStream, SendDatagramError,
    SendStream, StreamEvent, Streams, WriteError, Written,
};
pub use coordinator_control::RejectionReason;
pub use endpoint::{
    AcceptError, ConnectError, ConnectionHandle, DatagramEvent, Endpoint as LowLevelEndpoint,
    Incoming,
};
pub use nat_traversal_api::{
    BootstrapNode, CandidateAddress, NatTraversalConfig, NatTraversalEndpoint, NatTraversalError,
    NatTraversalEvent, NatTraversalStatistics, PeerId, TraversalDeadlineKind,
    TraversalFailureReason,
};
pub use reachability::{ReachabilityScope, TraversalMethod};

// ============================================================================
// SIMPLE API EXPORTS - Zero Configuration P2P (RECOMMENDED)
// ============================================================================

/// Zero-configuration P2P node - THE PRIMARY API
pub use node::{Node, NodeError};

/// Minimal configuration for zero-config P2P nodes
pub use node_config::{NodeConfig, NodeConfigBuilder};

/// Consolidated node status for observability
pub use node_status::{NatType, NodeStatus};

/// Unified events for P2P nodes
pub use node_event::{DisconnectReason as NodeDisconnectReason, NodeEvent};

// ============================================================================
// P2P API EXPORTS (for advanced use)
// ============================================================================

/// P2P endpoint - for advanced use, prefer Node for most applications
pub use ack_frame::ReceiveRejectReason;
pub use connection_lifecycle::ConnectionCloseReason;
pub use p2p_endpoint::{
    ConnectionHealth, ConnectionMetrics, DirectPathStatus, DirectPathUnavailableReason,
    DisconnectReason, EndpointError, EndpointStats, P2pEndpoint, P2pEvent, PeerConnection,
    PeerLifecycleEvent, TraversalPhase,
};

/// P2P configuration with builder pattern
pub use unified_config::{
    ConfigError, MtuConfig, NatConfig, P2pConfig, P2pConfigBuilder, PortMappingConfig,
};

/// Connection strategy for progressive NAT traversal fallback
pub use connection_strategy::{
    AttemptedMethod, ConnectionAttemptError, ConnectionMethod, ConnectionStage, ConnectionStrategy,
    StrategyConfig,
};

pub use relay::{
    AuthToken,
    // MASQUE types re-exported from relay module
    MasqueRelayClient,
    MasqueRelayConfig,
    MasqueRelayServer,
    MasqueRelayStats,
    MigrationConfig,
    MigrationCoordinator,
    MigrationState,
    RelayAuthenticator,
    RelayError,
    RelayManager,
    RelayManagerConfig,
    RelayResult,
    RelaySession,
    RelaySessionConfig,
    RelaySessionState,
    RelayStatisticsCollector,
};
pub use shared::{ConnectionId, EcnCodepoint, EndpointEvent};
pub use transport_error::{Code as TransportErrorCode, Error as TransportError};

// Re-export transport abstraction types
pub use transport::{
    BandwidthClass, InboundDatagram, LinkQuality, LoRaParams, ProtocolEngine, ProviderError,
    TransportAddr, TransportCapabilities, TransportCapabilitiesBuilder, TransportDiagnostics,
    TransportProvider, TransportRegistry, TransportStats, TransportType, UdpTransport,
};

#[cfg(feature = "ble")]
pub use transport::BleTransport;

// Re-export connection router types for automatic protocol engine selection
pub use connection_router::{
    ConnectionRouter, RoutedConnection, RouterConfig, RouterError, RouterStats,
};

// #[cfg(fuzzing)]
// pub mod fuzzing; // Module not implemented yet

/// The QUIC protocol version implemented.
///
/// Simplified to include only the essential versions:
/// - 0x00000001: QUIC v1 (RFC 9000)
/// - 0xff00_001d: Draft 29
pub const DEFAULT_SUPPORTED_VERSIONS: &[u32] = &[
    0x00000001,  // QUIC v1 (RFC 9000)
    0xff00_001d, // Draft 29
];

/// Whether an endpoint was the initiator of a connection
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Side {
    /// The initiator of a connection
    Client = 0,
    /// The acceptor of a connection
    Server = 1,
}

impl Side {
    #[inline]
    /// Shorthand for `self == Side::Client`
    pub fn is_client(self) -> bool {
        self == Self::Client
    }

    #[inline]
    /// Shorthand for `self == Side::Server`
    pub fn is_server(self) -> bool {
        self == Self::Server
    }
}

impl ops::Not for Side {
    type Output = Self;
    fn not(self) -> Self {
        match self {
            Self::Client => Self::Server,
            Self::Server => Self::Client,
        }
    }
}

/// Whether a stream communicates data in both directions or only from the initiator
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Dir {
    /// Data flows in both directions
    Bi = 0,
    /// Data flows only from the stream's initiator
    Uni = 1,
}

impl Dir {
    fn iter() -> impl Iterator<Item = Self> {
        [Self::Bi, Self::Uni].iter().cloned()
    }
}

impl fmt::Display for Dir {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        use Dir::*;
        f.pad(match *self {
            Bi => "bidirectional",
            Uni => "unidirectional",
        })
    }
}

/// Identifier for a stream within a particular connection
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct StreamId(u64);

impl fmt::Display for StreamId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let initiator = match self.initiator() {
            Side::Client => "client",
            Side::Server => "server",
        };
        let dir = match self.dir() {
            Dir::Uni => "uni",
            Dir::Bi => "bi",
        };
        write!(
            f,
            "{} {}directional stream {}",
            initiator,
            dir,
            self.index()
        )
    }
}

impl StreamId {
    /// Create a new StreamId
    pub fn new(initiator: Side, dir: Dir, index: u64) -> Self {
        Self((index << 2) | ((dir as u64) << 1) | initiator as u64)
    }
    /// Which side of a connection initiated the stream
    pub fn initiator(self) -> Side {
        if self.0 & 0x1 == 0 {
            Side::Client
        } else {
            Side::Server
        }
    }
    /// Which directions data flows in
    pub fn dir(self) -> Dir {
        if self.0 & 0x2 == 0 { Dir::Bi } else { Dir::Uni }
    }
    /// Distinguishes streams of the same initiator and directionality
    pub fn index(self) -> u64 {
        self.0 >> 2
    }
}

impl From<StreamId> for VarInt {
    fn from(x: StreamId) -> Self {
        unsafe { Self::from_u64_unchecked(x.0) }
    }
}

impl From<VarInt> for StreamId {
    fn from(v: VarInt) -> Self {
        Self(v.0)
    }
}

impl From<StreamId> for u64 {
    fn from(x: StreamId) -> Self {
        x.0
    }
}

impl coding::Codec for StreamId {
    fn decode<B: bytes::Buf>(buf: &mut B) -> coding::Result<Self> {
        VarInt::decode(buf).map(|x| Self(x.into_inner()))
    }
    fn encode<B: bytes::BufMut>(&self, buf: &mut B) {
        // StreamId values should always be valid VarInt values, but handle the error case
        match VarInt::from_u64(self.0) {
            Ok(varint) => varint.encode(buf),
            Err(_) => {
                // This should never happen for valid StreamIds, but use a safe fallback
                VarInt::MAX.encode(buf);
            }
        }
    }
}

/// An outgoing packet
#[derive(Debug)]
#[must_use]
pub struct Transmit {
    /// The socket this datagram should be sent to
    pub destination: SocketAddr,
    /// Explicit congestion notification bits to set on the packet
    pub ecn: Option<EcnCodepoint>,
    /// Amount of data written to the caller-supplied buffer
    pub size: usize,
    /// The segment size if this transmission contains multiple datagrams.
    /// This is `None` if the transmit only contains a single datagram
    pub segment_size: Option<usize>,
    /// Optional source IP address for the datagram
    pub src_ip: Option<IpAddr>,
}

// Deal with time
#[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
pub(crate) use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
pub(crate) use web_time::{Duration, Instant, SystemTime, UNIX_EPOCH};

//
// Useful internal constants
//

/// Maximum time to wait for QUIC connections and tasks to drain during shutdown.
///
/// Used by both `P2pEndpoint` and `NatTraversalEndpoint` to bound graceful-shutdown waits.
pub const SHUTDOWN_DRAIN_TIMEOUT: Duration = Duration::from_secs(5);

/// The maximum number of CIDs we bother to issue per connection
pub(crate) const LOC_CID_COUNT: u64 = 8;
pub(crate) const RESET_TOKEN_SIZE: usize = 16;
pub(crate) const MAX_CID_SIZE: usize = 20;
pub(crate) const MIN_INITIAL_SIZE: u16 = 1200;
/// <https://www.rfc-editor.org/rfc/rfc9000.html#name-datagram-size>
pub(crate) const INITIAL_MTU: u16 = 1200;
pub(crate) const MAX_UDP_PAYLOAD: u16 = 65527;
pub(crate) const TIMER_GRANULARITY: Duration = Duration::from_millis(1);
/// Maximum number of streams that can be tracked per connection
pub(crate) const MAX_STREAM_COUNT: u64 = 1 << 60;

// Internal type re-exports for crate modules
pub use cid_generator::RandomConnectionIdGenerator;
pub use config::{
    AckFrequencyConfig, ClientConfig, EndpointConfig, MtuDiscoveryConfig, ServerConfig,
    TransportConfig,
};

// Post-Quantum Cryptography (PQC) re-exports - always available
// v0.2: Pure PQC only - HybridKem and HybridSignature removed
pub use crypto::pqc::{MlDsa65, MlKem768, PqcConfig, PqcConfigBuilder, PqcError, PqcResult};
pub(crate) use frame::Frame;
pub use token::TokenStore;
pub(crate) use token::{NoneTokenLog, ResetToken, TokenLog};
pub(crate) use token_memory_cache::TokenMemoryCache;