#![allow(elided_lifetimes_in_paths)]
#![allow(missing_debug_implementations)]
#![allow(clippy::manual_is_multiple_of)]
#![cfg_attr(not(fuzzing), warn(missing_docs))]
#![allow(unreachable_pub)]
#![allow(clippy::cognitive_complexity)]
#![allow(clippy::too_many_arguments)]
#![allow(clippy::use_self)]
#![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,
};
mod cid_queue;
pub mod coding;
mod constant_time;
mod range_set;
pub mod transport_parameters;
mod varint;
pub use varint::{VarInt, VarIntBoundsExceeded};
pub mod bounded_pending_buffer;
pub mod path_selection;
pub mod shutdown;
pub mod watchable;
pub mod fair_polling;
pub mod transport_resilience;
pub mod connection_strategy;
pub mod happy_eyeballs;
pub mod discovery_trait;
pub mod structured_events;
pub mod node;
pub mod node_config;
pub mod node_status;
mod coordinator_control;
pub(crate) mod coordinator_health;
pub mod mdns;
pub mod node_event;
mod port_mapping;
pub mod reachability;
pub mod config;
pub mod connection;
pub mod endpoint;
pub mod frame;
pub mod packet;
pub mod shared;
pub mod transport_error;
pub mod candidate_discovery;
pub mod cid_generator;
mod congestion;
pub mod nat_traversal_api;
mod token;
mod token_memory_cache;
pub mod tracing;
pub mod constrained;
pub mod crypto;
pub mod discovery;
pub mod nat_traversal;
pub mod transport;
pub mod connection_router;
pub mod chat;
pub mod p2p_endpoint;
pub mod unified_config;
pub mod stats_dashboard;
pub mod terminal_ui;
pub mod compliance_validator;
pub mod logging;
pub mod metrics;
pub mod relay;
pub mod masque;
pub mod trust;
pub mod token_v2;
pub mod high_level;
pub use high_level::{
Accept, Connecting, Connection as HighLevelConnection, Endpoint,
RecvStream as HighLevelRecvStream, SendStream as HighLevelSendStream,
};
pub mod link_transport;
mod link_transport_impl;
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,
};
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,
};
pub mod host_identity;
pub use host_identity::{EndpointKeyPolicy, HostIdentity, HostKeyStorage, StorageError};
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,
};
pub use candidate_discovery::{
CandidateDiscoveryManager, DiscoveryConfig, DiscoveryError, DiscoveryEvent, NetworkInterface,
ValidatedCandidate,
};
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 endpoint::{
AcceptError, ConnectError, ConnectionHandle, DatagramEvent, Endpoint as LowLevelEndpoint,
Incoming,
};
pub use nat_traversal_api::{
BootstrapNode, CandidateAddress, NatTraversalConfig, NatTraversalEndpoint, NatTraversalError,
NatTraversalEvent, NatTraversalStatistics, PeerId,
};
pub use reachability::{ReachabilityScope, TraversalMethod};
pub use node::{Node, NodeError};
pub use node_config::{NodeConfig, NodeConfigBuilder};
pub use node_status::{NatType, NodeStatus};
pub use node_event::{DisconnectReason as NodeDisconnectReason, NodeEvent};
pub use p2p_endpoint::{
ConnectionMetrics, DisconnectReason, EndpointError, EndpointStats, P2pEndpoint, P2pEvent,
PeerConnection, TraversalPhase,
};
pub use unified_config::{
ConfigError, MtuConfig, NatConfig, P2pConfig, P2pConfigBuilder, PortMappingConfig,
};
pub use connection_strategy::{
AttemptedMethod, ConnectionAttemptError, ConnectionMethod, ConnectionStage, ConnectionStrategy,
StrategyConfig,
};
pub use relay::{
AuthToken,
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};
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;
pub use connection_router::{
ConnectionRouter, RoutedConnection, RouterConfig, RouterError, RouterStats,
};
pub const DEFAULT_SUPPORTED_VERSIONS: &[u32] = &[
0x00000001, 0xff00_001d, ];
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Side {
Client = 0,
Server = 1,
}
impl Side {
#[inline]
pub fn is_client(self) -> bool {
self == Self::Client
}
#[inline]
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,
}
}
}
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Dir {
Bi = 0,
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",
})
}
}
#[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 {
pub fn new(initiator: Side, dir: Dir, index: u64) -> Self {
Self((index << 2) | ((dir as u64) << 1) | initiator as u64)
}
pub fn initiator(self) -> Side {
if self.0 & 0x1 == 0 {
Side::Client
} else {
Side::Server
}
}
pub fn dir(self) -> Dir {
if self.0 & 0x2 == 0 { Dir::Bi } else { Dir::Uni }
}
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) {
match VarInt::from_u64(self.0) {
Ok(varint) => varint.encode(buf),
Err(_) => {
VarInt::MAX.encode(buf);
}
}
}
}
#[derive(Debug)]
#[must_use]
pub struct Transmit {
pub destination: SocketAddr,
pub ecn: Option<EcnCodepoint>,
pub size: usize,
pub segment_size: Option<usize>,
pub src_ip: Option<IpAddr>,
}
#[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};
pub const SHUTDOWN_DRAIN_TIMEOUT: Duration = Duration::from_secs(5);
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;
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);
pub(crate) const MAX_STREAM_COUNT: u64 = 1 << 60;
pub use cid_generator::RandomConnectionIdGenerator;
pub use config::{
AckFrequencyConfig, ClientConfig, EndpointConfig, MtuDiscoveryConfig, ServerConfig,
TransportConfig,
};
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;