15 KiB
Architecture
This document describes the technical architecture and implementation details of RustNet.
Table of Contents
- Multi-threaded Architecture
- Key Components
- Platform-Specific Implementations
- Performance Considerations
- Dependencies
- Security
Multi-threaded Architecture
RustNet uses a multi-threaded architecture for efficient packet processing:
┌─────────────────┐
│ Packet Capture │ ──packets──> Crossbeam Channel
│ (libpcap) │ │
└─────────────────┘ │
├──> ┌──────────────────┐
├──> │ Packet Processor │ ──> DashMap
├──> │ (Thread 0) │ │
└──> │ (Thread N) │ │
└──────────────────┘ │
│
┌─────────────────┐ │
│Process Enrichment│ ────────────────────────────────────────────> DashMap
│ (Platform API) │ │
└─────────────────┘ │
│
┌─────────────────┐ │
│Snapshot Provider│ <─────────────────────────────────────────── DashMap
└─────────────────┘ │
│ │
└──> RwLock<Vec<Connection>> (for UI) │
│
┌─────────────────┐ │
│ Cleanup Thread │ <─────────────────────────────────────────── DashMap
└─────────────────┘
Key Components
1. Packet Capture Thread
Uses libpcap to capture raw packets from the network interface. This thread runs independently and feeds packets into a Crossbeam channel for processing.
Responsibilities:
- Open network interface for packet capture (non-promiscuous, read-only mode)
- Apply BPF filters if needed
- Capture raw packets
- Send packets to processing queue
2. Packet Processors
Multiple worker threads (up to 4 by default, based on CPU cores) that parse packets and perform Deep Packet Inspection (DPI) analysis.
Responsibilities:
- Parse Ethernet, IP, TCP, UDP, ICMP, ARP headers
- Extract connection 5-tuple (protocol, src IP, src port, dst IP, dst port)
- Perform DPI to detect application protocols:
- HTTP with host information
- HTTPS/TLS with SNI (Server Name Indication)
- DNS queries and responses
- SSH connections with version detection
- QUIC protocol with CONNECTION_CLOSE frame detection
- NTP with version, mode, and stratum
- mDNS and LLMNR for local name resolution
- DHCP with message types and hostnames
- SNMP (v1, v2c, v3) with PDU types
- SSDP for UPnP device discovery
- NetBIOS Name Service and Datagram Service
- Track connection states and lifecycle
- Update connection metadata in DashMap
- Calculate bandwidth metrics
3. Process Enrichment
Platform-specific APIs to associate network connections with running processes. This component runs periodically to enrich connection data with process information.
Responsibilities:
- Map socket inodes to process IDs
- Resolve process names and command lines
- Update connection records with process information
- Handle permission-related fallbacks
See Platform-Specific Implementations for details on each platform.
4. Snapshot Provider
Creates consistent snapshots of connection data for the UI at regular intervals (default: 1 second). This ensures the UI has a stable view of connections without race conditions.
Responsibilities:
- Read from DashMap at configured intervals
- Apply filtering based on user criteria (localhost, etc.)
- Sort connections based on user-selected column
- Create immutable snapshot for UI rendering
- Provide RwLock-protected Vec for UI thread
5. Cleanup Thread
Removes inactive connections using smart, protocol-aware timeouts. This prevents memory leaks and keeps the connection list relevant.
Timeout Strategy:
TCP Connections
- HTTP/HTTPS (detected via DPI): 10 minutes - supports HTTP keep-alive
- SSH (detected via DPI): 30 minutes - accommodates long interactive sessions
- Active established (< 1 min idle): 10 minutes
- Idle established (> 1 min idle): 5 minutes
- TIME_WAIT: 30 seconds - standard TCP timeout
- CLOSED: 5 seconds - rapid cleanup
- SYN_SENT, FIN_WAIT, etc.: 30-60 seconds
UDP Connections
- HTTP/3 (QUIC with HTTP): 10 minutes - connection reuse
- HTTPS/3 (QUIC with HTTPS): 10 minutes - connection reuse
- SSH over UDP: 30 minutes - long-lived sessions
- DNS: 30 seconds - short-lived queries
- Regular UDP: 60 seconds - standard timeout
QUIC Connections (Detected State)
- Connected (active) (< 1 min idle): 10 minutes
- Connected (idle) (> 1 min idle): 5 minutes
- With CONNECTION_CLOSE frame: 1-10 seconds (based on close type)
- Initial/Handshaking: 60 seconds - allow connection establishment
- Draining: 10 seconds - RFC 9000 draining period
Visual Staleness Indicators:
Connections change color based on proximity to timeout:
- White (default): < 75% of timeout
- Yellow: 75-90% of timeout (warning)
- Red: > 90% of timeout (critical)
6. Rate Refresh Thread
Updates bandwidth calculations every second with gentle decay. This provides smooth bandwidth visualization without abrupt changes.
Responsibilities:
- Calculate bytes/second for download and upload
- Apply exponential decay to older measurements
- Update visual bandwidth indicators
- Maintain rolling window of packet rates
7. DashMap
Concurrent hashmap (DashMap<ConnectionKey, Connection>) for storing connection state. This lock-free data structure enables efficient concurrent access from multiple threads.
Key Features:
- Fine-grained locking (per-shard)
- No global lock contention
- Safe concurrent reads and writes
- High performance under concurrent load
Platform-Specific Implementations
Process Lookup
RustNet uses platform-specific APIs to associate network connections with processes:
Linux
Standard Mode (procfs):
- Parses
/proc/net/tcpand/proc/net/udpto get socket inodes - Iterates through
/proc/<pid>/fd/to find socket file descriptors - Maps inodes to process IDs and resolves process names from
/proc/<pid>/cmdline
eBPF Mode (Default on Linux):
- Uses kernel eBPF programs attached to socket syscalls
- Captures socket creation events with process context
- Provides lower overhead than procfs scanning
- Limitations:
- Process names limited to 16 characters (kernel
commfield) - May show thread names instead of full executable names
- Multi-threaded applications show internal thread names
- Process names limited to 16 characters (kernel
- Capability requirements:
- Modern Linux (5.8+):
CAP_NET_RAW(packet capture),CAP_BPF,CAP_PERFMON(eBPF) - Legacy Linux (pre-5.8):
CAP_NET_RAW(packet capture),CAP_SYS_ADMIN(eBPF) - Note: CAP_NET_ADMIN is NOT required (uses read-only, non-promiscuous packet capture)
- Modern Linux (5.8+):
Fallback Behavior:
- If eBPF fails to load (permissions, kernel compatibility), automatically falls back to procfs mode
- TUI Statistics panel shows active detection method
macOS
PKTAP Mode (with sudo):
- Uses PKTAP (Packet Tap) kernel interface
- Extracts process information directly from packet metadata
- Requires root privileges (privileged kernel interface)
- Faster and more accurate than lsof
lsof Mode (without sudo or fallback):
- Uses
lsof -i -n -Pto list network connections - Parses output to associate sockets with processes
- Higher CPU overhead but works without root
- Used automatically when PKTAP is unavailable
Detection:
- TUI Statistics panel shows "pktap" or "lsof" based on active method
- Automatically selects best available method
Windows
IP Helper API:
- Uses
GetExtendedTcpTableandGetExtendedUdpTablefrom Windows IP Helper API - Retrieves connection tables with process IDs
- Supports both IPv4 and IPv6 connections
- Resolves process names using
OpenProcessandQueryFullProcessImageNameW
Requirements:
- May require Administrator privileges depending on system configuration
- Requires Npcap or WinPcap for packet capture
Network Interfaces
The tool automatically detects and lists available network interfaces using platform-specific methods:
- Linux: Uses
netlinkor falls back to/sys/class/net/ - macOS: Uses
getifaddrs()system call - Windows: Uses
GetAdaptersInfo()from IP Helper API - All platforms: Falls back to pcap's
pcap_findalldevs()when native methods fail
Performance Considerations
Multi-threaded Processing
Packet processing is distributed across multiple threads (up to 4 by default, based on CPU cores). This enables:
- Parallel packet parsing and DPI analysis
- Better utilization of multi-core systems
- Reduced latency for high packet rates
Concurrent Data Structures
DashMap provides lock-free concurrent access with:
- Per-shard locking (16 shards by default)
- No global lock contention
- Read-heavy workload optimization
- Safe concurrent modifications
Batch Processing
Packets are processed in batches to improve cache efficiency:
- Multiple packets processed before context switching
- Reduced system call overhead
- Better CPU cache utilization
Selective DPI
Deep packet inspection can be disabled with --no-dpi for lower overhead:
- Reduces CPU usage by 20-40% on high-traffic networks
- Still tracks basic connection information
- Useful for performance-constrained environments
Configurable Intervals
Adjust refresh rates based on your needs:
- UI refresh: Default 1000ms (adjustable with
--refresh-interval) - Process enrichment: Every 2 seconds
- Cleanup check: Every 5 seconds
- Rate calculation: Every 1 second
Memory Management
Connection cleanup prevents unbounded memory growth:
- Protocol-aware timeouts remove stale connections
- Visual staleness warnings before removal
- Configurable timeout thresholds
Snapshot isolation prevents UI blocking:
- UI reads from immutable snapshots
- Background threads update DashMap concurrently
- No lock contention between UI and packet processing
Dependencies
RustNet is built with the following key dependencies:
Core Dependencies
- ratatui - Terminal user interface framework with full widget support
- crossterm - Cross-platform terminal manipulation
- pcap - Packet capture library bindings for libpcap/Npcap
- pnet_datalink - Network interface enumeration and low-level networking
Concurrency & Threading
- dashmap - Concurrent hashmap with fine-grained locking
- crossbeam - Multi-threading utilities and lock-free channels
- parking_lot - Efficient synchronization primitives (RwLock, Mutex)
Networking & Protocols
- dns-lookup - DNS resolution capabilities
- etherparse - Ethernet, IP, TCP, UDP packet parsing
- trust-dns-proto - DNS protocol parsing (for DPI)
Command-line & Logging
- clap - Command-line argument parsing with derive features
- simplelog - Flexible logging framework
- log - Logging facade
- anyhow - Error handling and context
Platform-Specific
- procfs (Linux) - Process information from /proc filesystem (runtime fallback)
- libbpf-rs (Linux) - eBPF program loading and management
- libbpf-sys (Linux) - Low-level libbpf bindings for eBPF
- windows-sys (Windows) - Windows API bindings for IP Helper API
Utilities
- arboard - Clipboard access for copying addresses
- num_cpus - CPU core detection for threading
- chrono - Date and time handling
- ring - Cryptographic operations (for TLS/SNI parsing)
- aes - AES encryption support (for protocol detection)
Security
For security documentation including Landlock sandboxing, privilege requirements, and threat model, see SECURITY.md.
Comparison with Similar Tools
RustNet draws inspiration from several network monitoring tools. Here's how it compares:
| Feature | RustNet | bandwhich | sniffnet | iftop | netstat | ss | tcpdump/wireshark |
|---|---|---|---|---|---|---|---|
| Language | Rust | Rust | Rust | C | C | C | C |
| Interface | TUI | TUI | GUI | TUI | CLI | CLI | CLI/GUI |
| Real-time monitoring | Yes | Yes | Yes | Yes | Snapshot | Snapshot | Yes |
| Process identification | Yes | Yes | No | No | Yes | Yes | No |
| Deep Packet Inspection | Yes | No | No | No | No | No | Yes |
| SNI/Host extraction | Yes | No | No | No | No | No | Yes |
| Protocol state tracking | Yes | No | Partial | No | Yes | Yes | Yes |
| Bandwidth per connection | Yes | Yes | Yes | Yes | No | No | No |
| Connection filtering | Yes | No | Yes | Yes | No | Yes | Yes (BPF) |
| DNS reverse lookup | Yes | Yes | Yes | Yes | No | No | Yes |
| GeoIP lookup | No | No | Yes | No | No | No | Yes |
| Notifications | No | No | Yes | No | No | No | No |
| i18n (translations) | No | No | Yes | No | No | No | No |
| Cross-platform | Linux, macOS, Windows, FreeBSD | Linux, macOS | Linux, macOS, Windows | Linux, macOS, BSD | All | Linux | All |
| eBPF support | Yes (Linux) | No | No | No | No | Yes | No |
| Landlock sandboxing | Yes (Linux) | No | No | No | No | No | No |
| JSON event logging | Yes | No | No | No | No | No | Yes |
| Packet capture | libpcap | Raw sockets | libpcap | libpcap | Kernel | Kernel | libpcap |
Tool Focus Areas
- RustNet: Real-time connection monitoring with DPI, protocol state tracking, and process identification in a TUI
- bandwhich: Bandwidth utilization by process/connection with minimal overhead
- sniffnet: Network traffic analysis with a graphical interface and notifications
- iftop: Interface bandwidth monitoring with per-host traffic display
- netstat/ss: System socket and connection state inspection (ss is the modern replacement for netstat on Linux)
- tcpdump/wireshark/tshark: Full packet capture and protocol analysis for deep debugging