Skip to main content

moq_native/
lib.rs

1//! Helper library for native MoQ applications.
2//!
3//! Establishes MoQ connections over:
4//! - WebTransport (HTTP/3)
5//! - Raw QUIC (with ALPN negotiation)
6//! - WebSocket (fallback via [web-transport-ws](https://crates.io/crates/web-transport-ws))
7//! - Plain TCP via the `tcp://` scheme (qmux, no TLS; requires `tcp` feature)
8//! - Unix domain socket via the `unix://` scheme (qmux, peer-credential aware; requires `uds` feature, unix-only)
9//! - Iroh P2P (requires `iroh` feature)
10//!
11//! See [`Client`] for connecting to relays and [`Server`] for accepting connections.
12
13#![warn(missing_docs)]
14
15pub mod bind;
16mod client;
17mod connect;
18mod crypto;
19mod error;
20#[cfg(feature = "jemalloc")]
21pub mod jemalloc;
22mod log;
23#[cfg(feature = "noq")]
24pub mod noq;
25pub mod quic;
26#[cfg(feature = "quinn")]
27pub mod quinn;
28mod reconnect;
29mod server;
30#[cfg(feature = "tcp")]
31pub mod tcp;
32pub mod tls;
33#[cfg(all(feature = "uds", unix))]
34pub mod unix;
35mod util;
36#[cfg(feature = "watch")]
37pub mod watch;
38#[cfg(feature = "websocket")]
39pub mod websocket;
40
41// Enumerated rather than globbed, so the root surface is a deliberate list and a
42// new `pub` item in these modules doesn't silently join it.
43pub use client::{Client, ClientConfig};
44pub use connect::ConnectError;
45pub use error::{Error, Result};
46pub use log::Log;
47pub use reconnect::{Backoff, ConnectionStatsReader, Reconnect, Status};
48pub use server::{Request, Server, ServerConfig, Transport};
49
50/// Spawn the session's protocol driver on the current tokio runtime, handing back
51/// the session it drives.
52///
53/// The driver holds no session clone, so the session still closes when the caller
54/// drops their last [`moq_net::Session`] handle, which in turn lets the driver
55/// task finish.
56pub(crate) fn spawn_session((session, driver): (moq_net::Session, moq_net::Driver)) -> moq_net::Session {
57	tokio::spawn(driver);
58	session
59}
60
61// Re-export these crates.
62pub use moq_net;
63pub use rustls;
64
65/// Re-exported because [`watch::FileWatcher`] surfaces `notify::Result`/`notify::Error`
66/// in its API; a major `notify` bump is therefore a breaking change for this crate.
67#[cfg(feature = "watch")]
68pub use notify;
69
70/// Re-exported because [`tls::init_android`] takes a `jni::Env` handle; a major
71/// `jni` bump is therefore a breaking change for this crate.
72#[cfg(target_os = "android")]
73pub use jni;
74
75#[cfg(feature = "quiche")]
76pub mod quiche;
77
78#[cfg(feature = "iroh")]
79pub mod iroh;
80
81/// The QUIC backend to use for connections.
82#[derive(Clone, Debug, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
83#[serde(rename_all = "lowercase")]
84#[non_exhaustive]
85pub enum QuicBackend {
86	/// [web-transport-quinn](https://crates.io/crates/web-transport-quinn)
87	#[cfg(feature = "quinn")]
88	Quinn,
89
90	/// [web-transport-quiche](https://crates.io/crates/web-transport-quiche)
91	#[cfg(feature = "quiche")]
92	Quiche,
93
94	/// [web-transport-noq](https://crates.io/crates/web-transport-noq)
95	#[cfg(feature = "noq")]
96	Noq,
97}
98
99fn default_quic_backend() -> QuicBackend {
100	#[cfg(feature = "quinn")]
101	{
102		QuicBackend::Quinn
103	}
104	#[cfg(all(feature = "noq", not(feature = "quinn")))]
105	{
106		QuicBackend::Noq
107	}
108	#[cfg(all(feature = "quiche", not(feature = "quinn"), not(feature = "noq")))]
109	{
110		QuicBackend::Quiche
111	}
112	#[cfg(all(not(feature = "quiche"), not(feature = "quinn"), not(feature = "noq")))]
113	panic!("no QUIC backend compiled; enable noq, quinn, or quiche feature");
114}
115
116#[cfg(test)]
117mod tests {
118	#[cfg(feature = "quinn")]
119	#[test]
120	fn quinn_is_the_default_backend() {
121		assert!(matches!(super::default_quic_backend(), super::QuicBackend::Quinn));
122	}
123}