Warning
🚧 EXPERIMENTAL / EDUCATIONAL ONLY 🚧
Project Aether is a learning experiment, not a production network stack.
Unlike mature user-space stacks (e.g., smoltcp, VPP, or lwIP) or the standard Linux kernel, Aether prioritizes code simplicity and raw throughput over correctness, reliability, and standards compliance. It is not suitable for general internet use.
Project Aether is a custom, no_std-compatible TCP/IP implementation written from scratch in Rust. It bypasses the Linux kernel networking stack (netfilter, routing tables, etc.) to communicate directly with a TAP interface via raw Ethernet frames.
The goal of this project was to explore the mechanics of the TCP 3-way handshake, zero-copy packet processing, and custom concurrency models without the overhead of an operating system's full network subsystem.
If you are looking for a usable TCP/IP stack for your Rust OS or embedded project, this is probably not it. Aether takes significant shortcuts to achieve high "benchmark" numbers on local connections:
Aether is strictly IPv4-only. In an era where IPv6 is mandatory for general compliance, this stack is stuck in the past.
To keep the engine extremely fast, we stripped out the safety features that make TCP "reliable":
- No Retransmission: If a packet is dropped, the connection stalls and eventually times out. Aether never resends data.
- No Out-of-Order Handling: Packets must arrive in perfect sequence. If packet 5 arrives before packet 4, packet 5 is dropped.
- No Fragmentation: IP packets larger than the MTU (1514 bytes) are dropped.
- No Flow Control: It sends data as fast as the wire allows. There is no "Slow Start," "Congestion Avoidance," or dynamic Window Scaling.
- Fixed Window: The TCP Window size is hardcoded.
- While it implements SYN Cookies to prevent basic flood attacks, it lacks randomness in sequence number generation (predictable ISNs) and does not support TLS/SSL.
Aether abandons generic async runtimes (Tokio/Async-std) for a custom, purpose-built event loop designed for specific CPU topologies.
At startup, Aether detects the available CPU cores:
- Single-Threaded Mode: On single-core VMs or legacy hardware, it runs a zero-copy spin-loop. This eliminates context switching and synchronization overhead.
- Sharded Multi-Threaded Mode: On multi-core systems, it spawns worker threads and distributes traffic using a 2-tuple hash
(SrcIP, SrcPort) % workers.
To prevent the stack from burning 100% CPU while waiting for packets (a common issue in naive DPDK/kernel-bypass apps), the main loop implements a state machine:
- Spin: Nanosecond polling for high-load bursts.
- Yield: Relinquishes CPU time slice.
- Sleep: Micro-sleep (50µs) during total silence.
Despite its limitations, Aether successfully implements enough of the protocol suite to serve a basic webpage and negotiate an IP address.
| Layer | Protocol | Status | Notes |
|---|---|---|---|
| L2 | Ethernet | ✅ | Frame parsing, broadcast handling |
| L2 | ARP | ✅ | Request & Reply (Hardware Address Resolution) |
| L3 | IPv4 | Header validation only (No frag, options, or TTL processing) | |
| L3 | ICMP | ✅ | Echo Request/Reply (Ping) |
| L4 | TCP | 3-Way Handshake, PSH, FIN, RST (No Re-Tx, SACK, Window Scale) | |
| L4 | UDP | ✅ | Basic datagram parsing |
| L7 | DHCP | ✅ | DORA Sequence (Discover, Offer, Request, Ack) |
| L7 | DNS | ❌ | Parsing stub only (No resolution logic) |
| L7 | HTTP | Static HTML responder (GET / only) |
Running on a single-core Intel Celeron 900 (2.2GHz, 2009) context:
| Metric | Result | Context |
|---|---|---|
| Throughput | 3,109 Req/Sec | Local TAP interface, HTTP Keep-Alive disabled |
| Latency | < 1ms | Local loopback equivalent |
| Concurrency | 100 Concurrent | Validated with Python stress script |
Note: These numbers represent raw packet processing speed in a controlled environment. Real-world performance over a physical NIC would be significantly lower due to the lack of congestion control.
- Linux Kernel (Required for
TAPdevice creation) - Rust (Cargo)
- Root/Sudo privileges (to configure the network interface)
-
Build the Project:
cargo build --release
-
Setup the TAP Interface: You need to create a persistent TAP device and assign it an IP.
sudo ip tuntap add mode tap user $USER name aether0 sudo ip link set aether0 up sudo ip addr add 192.168.1.1/24 dev aether0
-
Run Aether:
# Must run with access to the TAP device ./target/release/aether -
Test Connectivity:
# Ping the stack ping 192.168.1.2 # HTTP Request curl http://192.168.1.2/
Built with 🦀 and ☕ by Seuriin