netune
An owned, observable, and intervention-capable network stack in Rust.
netune owns every layer from DNS to the HTTP/1.1 message — no third-party HTTP implementation in the production dependency graph — and makes the transport itself an object you can inspect, fingerprint, and change:
| Crate | What it is |
|---|---|
netune-trace |
The trace model and pure derivations. Every timing a surface shows is a pure function of a recorded trace. Also: TLS ClientHello parsing and JA3/JA4 fingerprints. |
netune-http1 |
The HTTP/1.1 codec. Differential-tested against hyper (dev-dependency only) over recorded byte streams. |
netune-http2 |
HTTP/2 wire protocol placeholder and design reservation (ADR-0003). Reserved at 0.0.1; no I/O implementation. |
netune-ws |
Pure RFC 6455 WebSocket codec: role-enforced masking, fragmented-message reassembly, SHA-1 handshake keys. No I/O runtime. |
netune |
The transport: DNS, TCP, TLS (rustls), the syscall tap (TimedIo), connection pool (Pool), TLS fingerprint presets and routing (TlsProfile, Preset), proxies (HTTP CONNECT & SOCKS5), redirects, decompression, client WebSocket upgrade (connect_ws), stale-socket absorption — and FaultIo, the chaos twin that injects delays, splits, truncations, and resets. |
netune-probe |
The L2 probe: pure Ethernet/IPv4/TCP parse and build (forge) plus an opt-in inject feature for frame transmission. |
Capability surface
Observe — a three-level tap with graceful degradation:
- L0 protocol events, portable, always on
- L1 syscall boundaries (
TimedIo) +TCP_INFOsampling (RTT, retransmits, cwnd) - L2 per-segment capture (Linux,
CAP_NET_RAW, opt-in)
Fingerprint — inspect and configure TLS identity:
- Pure wire parser:
netune-trace::ja4parses ClientHello bytes and computes the JA4 fingerprint, cross-tool anchored against FoxIO's published test vectors. - Profile presets: named presets (
netune-default,codex-reqwest,codex-network-proxy) configure ALPN, protocol versions, ciphers, and key-exchange groups. - Per-request selection:
Target::with_tls_profilepicks the identity at request time; unknown profile names fail loudly. - Pool isolation: connection pool keys on
authority#profile, preventing connection reuse across disparate TLS identities.
Intervene — change behaviour at two privilege levels:
- In-process, zero privileges (
netune::FaultIo): script delays, split reads, truncations, and connection resets against any stream to test retry policies and streaming pipelines hermetically. - On the wire, feature-gated (
netune-probewith--features inject): build arbitrary TCP frames (forged seq/ack, RSTs, window games) with pure, fully tested functions; transmit them only when the feature is compiled in andCAP_NET_RAWis held. The default build has no transmit path at all.
Resilience — culled keep-alive absorption:
- Shortened idle pool bound (20 s) prevents handing out connections about to be culled by intermediate gateways.
- Transparent single retry on stale pooled sockets before receiving a response head (
INV-TRANSPORT-01), eliminating spurious keep-alive failures without request replay hazard. - Precise error classification (
HttpError::Incomplete) distinguishing peer socket closure from protocol smuggling or violations.
The privilege boundary is structural
default build --features inject + CAP_NET_RAW
parse/build ✅ present ✅ present (pure, tested)
transmit ❌ not compiled ✅ present (socket)
Injection changes the network rather than measuring it; it is never a default capability of anything long-running.
Quick Start
Build and Test
# Run unit and integration tests across all workspace crates
# Run tests with nextest
Basic Request & Trace Inspection
use Method;
use ;
use ;
use ;
async
Documentation Map
- Tutorials: Getting Started
- How-To Guides:
- Reference:
- Explanation:
- Architecture Decisions: ADR Registry
- Contributing: Contributor Guide
Status
Pre-1.0. Every workspace crate is lockstep-versioned at 0.0.1, except
netune-http2, which ships at 0.0.2 because the registry's 0.0.1 slot is
held by its earlier name-reservation stub.
MSRV: 1.95. License: MIT.