feat(transport,tunnel): implement Wave 3 — QUIC transport + split-tunnel router
aura-transport: quinn 0.11 endpoint with HTTP/3 mimicry (ALPN h3/h3-29, Chrome-like transport params), outer-TLS accept-any (real auth is the inner Aura handshake), packet padding to HTTPS sizes; AuraServer/AuraClient drive the proto handshake over a QUIC bidi stream; AuraConnection impls aura_proto::PacketConnection (full-duplex via Session::split + per-half mutex). 14 tests incl. a real-QUIC loopback end-to-end (crypto+pki+proto+transport). aura-tunnel: RouteTable (longest-prefix split-tunnel classify), AuraDns (hickory) host-route registration, AuraRouter over a PacketIo TUN seam + Arc<dyn PacketConnection>, AuraTun (tun 0.8 unix; wintun cfg-gated Windows). 10 tests (route classify/priority, dst-IP parse, mock router). send_direct is a v1 stub. Whole workspace: tests green, clippy clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1 +1,86 @@
|
||||
//! aura-tunnel — TUN interface and split tunneling (skeleton; implemented in Wave 3).
|
||||
//! aura-tunnel — the Aura VPN data-plane tunnel (project §8).
|
||||
//!
|
||||
//! This crate turns a host's IP traffic into something the encrypted transport can carry, and back
|
||||
//! again. It has four pieces:
|
||||
//!
|
||||
//! * [`AuraTun`] — a cross-platform layer-3 TUN device (Linux/macOS via the `tun` crate; Windows via
|
||||
//! `wintun`, `cfg`-gated). See [`tun`](mod@crate::tun).
|
||||
//! * [`RouteTable`] / [`RouteAction`] — a longest-prefix-match split-tunnel routing table deciding
|
||||
//! VPN-vs-direct per destination IP. See [`routes`](mod@crate::routes).
|
||||
//! * [`AuraDns`] — a hickory-backed resolver that registers resolved domain addresses as host
|
||||
//! routes in a shared [`RouteTable`]. See [`dns`](mod@crate::dns).
|
||||
//! * [`AuraRouter`] — the run-loop bridging the TUN device and an
|
||||
//! [`aura_proto::PacketConnection`]. See [`router`](mod@crate::router).
|
||||
//!
|
||||
//! ## Wiring it together (for the CLI)
|
||||
//!
|
||||
//! The router is generic over the [`PacketIo`] device seam and shares the routing table and the
|
||||
//! packet connection by `Arc`:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # async fn demo(conn: std::sync::Arc<dyn aura_proto::PacketConnection>) -> anyhow::Result<()> {
|
||||
//! use std::sync::Arc;
|
||||
//! use tokio::sync::RwLock;
|
||||
//! use aura_tunnel::{AuraDns, AuraRouter, AuraTun, RouteAction, RouteTable};
|
||||
//!
|
||||
//! // 1. Build a shared routing table (default: everything through the VPN).
|
||||
//! let routes = Arc::new(RwLock::new(RouteTable::new(RouteAction::Vpn)));
|
||||
//! routes.write().await.add_cidr("192.168.0.0/16".parse()?, RouteAction::Direct);
|
||||
//!
|
||||
//! // 2. Optionally resolve domains into host routes.
|
||||
//! let mut dns = AuraDns::new(Arc::clone(&routes)).await?;
|
||||
//! dns.resolve_and_register("example.com", RouteAction::Direct).await?;
|
||||
//!
|
||||
//! // 3. Create the TUN device (needs privileges).
|
||||
//! let tun = AuraTun::create("aura0", "10.7.0.2".parse()?, 24, 1420).await?;
|
||||
//!
|
||||
//! // 4. Build the router from the TUN, the table, and the connection, then run it.
|
||||
//! let router = AuraRouter::new(tun, routes, conn);
|
||||
//! router.run().await?;
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![cfg_attr(not(windows), forbid(unsafe_code))]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
pub mod dns;
|
||||
pub mod router;
|
||||
pub mod routes;
|
||||
pub mod tun;
|
||||
|
||||
pub use dns::AuraDns;
|
||||
pub use router::{dst_ip, AuraRouter};
|
||||
pub use routes::{RouteAction, RouteTable};
|
||||
pub use tun::{AuraTun, PacketIo};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
/// Errors produced by the tunnel data plane.
|
||||
///
|
||||
/// The router and DNS surfaces mostly return [`anyhow::Result`] (they compose I/O, the `tun`/`wintun`
|
||||
/// backends, hickory, and the [`aura_proto::PacketConnection`] contract, all of which already carry
|
||||
/// rich context). This enum names the tunnel-specific failure modes for callers that want to match
|
||||
/// on them, and converts cleanly from the underlying I/O and resolver errors.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum TunnelError {
|
||||
/// Creating or configuring the TUN/wintun device failed.
|
||||
#[error("TUN device error: {0}")]
|
||||
Device(String),
|
||||
|
||||
/// An I/O error while reading from or writing to the TUN device.
|
||||
#[error("TUN I/O error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
/// The requested TUN address/prefix was not a valid network.
|
||||
#[error("invalid TUN address or prefix: {0}")]
|
||||
InvalidAddress(#[from] ipnetwork::IpNetworkError),
|
||||
|
||||
/// DNS resolution failed.
|
||||
#[error("DNS resolution error: {0}")]
|
||||
Dns(#[from] hickory_resolver::error::ResolveError),
|
||||
|
||||
/// The underlying encrypted packet connection failed.
|
||||
#[error("packet connection error: {0}")]
|
||||
Connection(String),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user