Files
mfahampshire 43a1bd38e8 Max/smolmix wasm (#6784)
* Mod gitignore + license trimming + comment trimming

* Big rewrite

* SURB inputs + DNS button in internal-dev

* Make ipr addr optional

* Accidentatly omitted files from rewrite commit

* Makefile + readme

* Comment rewrite

* Optimisation comment

* Replace manual waker map with
      smoltcp built-ins + adaptive poll

* Comments

* Extract socket creation helpers into stream.rs

* Cleanup comments

* Comment

* Comment notes and restrict ciphersuites wrt rustls-rustcrypto

* Dep. hack fix for demo + add clearnet fetch() for contrast

* Stripped down devtester

* Fix Clippy arg (fatfingered deletion)

* CodeRabbit catches

* Cargofmt

* Review nits: bridge logs, fetch early-return, static port counter, copyright years, README + Cargo + headless.js tidying

* PHONY + taskset override, switch internal-dev/tests to pnpm, fix wasm-pack out-dir

* Gate codec tests behind the codec feature for no-default-features builds

* IPv6 addr/route on smoltcp iface + configurable DNS resolvers via TunnelOpts

* DNS GUI inputs, close stale WS on reconnect, worker init guards + ws-send warning, Playwright listener cleanup, pnpm-lock in internal-dev

* Fix lp -> lp-data after rebase

* Revert nym-lp/nym-lp-data feature-gating left over from rebase

* Lift getrandom wasm_js cfg to workspace .cargo/config.toml so cargo check -p smolmix-wasm works from any CWD

* temp will amend git message

* Auto-discover IPR when none specified + 'Use random IPR' checkbox in internal-dev

* smolmix_tracker + State machine + ready_tunnel gate + getTunnelState JS surface

* Mirror red display() entries to console.error

* Add left out package-lock

* Reactor clock + yield_now + atomic seq + gateway-storage errors

* setupMixTunnel gate + MTU 1980 + http::Uri cleanup

* Review pass + fix test + clippy

* restore axum 0.8 bump from borked earlier merge

* Feature gating (dns/fetch/socket) + TunnelOptsBuilder + pnpm bypass

* Cont. with review comments

* tokio Nofity reactor wakes + cancellation + setup polishing

* Notify wakes + inner pattern + close_notify + util

* Tunable tunnelopts

* Fix tired commit

* CI prep

* Lint + Clippy

* coderabbit u32 fix

* nits + runtime debugging + expose in internal-dev

* remove redudant default-features

* Remove more redundant default-features
2026-05-28 15:57:10 +00:00
..
2026-05-28 15:57:10 +00:00
2026-05-13 11:19:44 +00:00

smolmix

TCP/UDP tunnel over the Nym mixnet. Uses a userspace network stack (smoltcp) to provide real TcpStream and UdpSocket types that work with the async Rust ecosystem: tokio-rustls, hyper, tokio-tungstenite, libp2p, and anything else built on AsyncRead + AsyncWrite.

Why IP, not messages

The Nym SDK works at the message layer: you send and receive Vec<u8> payloads through the mixnet. Every protocol has to be hand-adapted, with custom framing, ordering, connection state, and flow control.

smolmix operates at the IP layer. A userspace smoltcp stack manages real TCP state machines (retransmits, windowing, port allocation) and UDP datagram delivery, and the mixnet becomes the transport underneath. Any protocol that works over TCP or UDP works over smolmix without adaptation.

┌──────────────────────────────────────────────────────────────────┐
│  Application protocols that "just work" over smolmix             │
│                                                                  │
│  ┌──────────┐ ┌──────────┐ ┌──────────────┐ ┌────────────────┐   │
│  │ TLS      │ │ HTTP/1.1 │ │ WebSocket    │ │ libp2p         │   │
│  │ (rustls) │ │ (hyper)  │ │ (tungstenite)│ │ (noise+yamux)  │   │
│  └────┬─────┘ └────┬─────┘ └──────┬───────┘ └───────┬────────┘   │
│       │             │              │                 │           │
│       └─────────────┴──────────────┴─────────────────┘           │
│                             │                                    │
│                   tokio_smoltcp::TcpStream                       │
│               (AsyncRead + AsyncWrite, Send, Unpin)              │
├──────────────────────────────────────────────────────────────────┤
│                     smolmix Tunnel                               │
│                   (smoltcp → mixnet → IPR)                       │
└──────────────────────────────────────────────────────────────────┘

Quick start

use smolmix::Tunnel;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

let tunnel = Tunnel::new().await?;

// Raw TCP, works with any protocol
let mut tcp = tunnel.tcp_connect("1.1.1.1:80".parse()?).await?;
tcp.write_all(b"GET / HTTP/1.1\r\nHost: 1.1.1.1\r\nConnection: close\r\n\r\n").await?;

// Raw UDP, datagrams over the mixnet
let udp = tunnel.udp_socket().await?;
udp.send_to(&packet, "1.1.1.1:53".parse()?).await?;

Examples

cargo run -p smolmix --example tcp         # HTTPS via hyper
cargo run -p smolmix --example udp         # DNS via hickory-proto
cargo run -p smolmix --example websocket   # WebSocket via tungstenite

Architecture

See core/src/ARCHITECTURE.md for the internal stack (smoltcp, device adapter, bridge, mixnet client).