Everything the multi-threaded DPI engine can do — and how to use it.
The engine runs a multi-stage pipeline: PCAP Reader → Load Balancers → Fast Path Workers → Output Writer, each as a separate thread. This means packet reading, inspection, and output writing all happen concurrently.
# Default: 2 LBs × 2 FPs each = 4 worker threads ./dpi_engine input.pcap output.pcap # Scale up: 4 LBs × 4 FPs = 16 worker threads ./dpi_engine input.pcap output.pcap --lbs 4 --fps 4
Load balancers use FiveTupleHash (src IP, dst IP, src port, dst port, protocol) to route all packets from the same connection to the same Fast Path worker. This guarantees flow affinity without any shared state between workers.
Each inter-thread queue (TSQueue<T>) uses mutex + condition variables with a
configurable max size (default: 10,000). When a queue is full, the producer blocks until space
is available — preventing memory blowup under heavy load.
All counters (total packets, forwarded, dropped, TCP/UDP counts) use std::atomic<uint64_t>
for lock-free thread-safe updates. Per-app stats use a separate mutex-protected map.
Parses TLS ClientHello messages to extract the Server Name Indication (SNI) field — the plaintext hostname sent before encryption starts. This is how the engine identifies HTTPS traffic without decryption. Works on port 443.
QUIC (HTTP/3) uses UDP:443 instead of TCP. The engine parses QUIC Initial packets which contain the TLS ClientHello inside CRYPTO frames, extracting SNI in the same way. This catches traffic from Chrome, YouTube, and Google services that default to QUIC.
For unencrypted HTTP (port 80), the engine reads the Host: header from the HTTP request
to identify the destination website. Combined with SNI extraction, this covers both HTTP and HTTPS traffic.
Extracts queried domain names from DNS request packets (port 53). This provides an additional classification signal — even before the actual connection is established, the engine knows what domain the client is trying to reach.
Block all traffic from a specific source IP address. The IP is parsed into a uint32_t
and checked in an unordered_set for O(1) lookup speed.
./dpi_engine input.pcap output.pcap --block-ip 192.168.1.50 --block-ip 10.0.0.5
Block entire applications by name. The engine first classifies the traffic using SNI/Host/DNS, then applies the blocking rule. Supported apps include: YouTube, Facebook, Netflix, Google, GitHub, TikTok, Twitter, Instagram, LinkedIn, Spotify, and more.
./dpi_engine input.pcap output.pcap --block-app YouTube --block-app Netflix
Block domains with substring matching and wildcard support.
*.facebook.com blocks all Facebook subdomains including
m.facebook.com, static.facebook.com, etc.
./dpi_engine input.pcap output.pcap --block-domain facebook.com --block-domain tiktok
Block all traffic to specific destination ports. For example, block port 8080 to prevent proxy access, or block port 22 to prevent SSH tunneling.
When a packet is blocked, the engine records exactly why — was it an IP rule, an app rule,
a domain rule, or a port rule? The BlockReason struct contains the type and a human-readable
detail string.
Save your blocking rules to a file with saveRules() and reload them later with
loadRules(). Deploy the same ruleset across multiple instances or environments.
Each Fast Path worker maintains its own unordered_map<FiveTuple, FlowEntry>.
Because flow affinity guarantees all packets from the same connection go to the same worker,
these tables are thread-local — no locks needed for flow lookup or update.
The engine tracks TCP connection state transitions: NEW → SYN_SENT → ESTABLISHED → FIN_WAIT → CLOSED. This enables accurate connection counting and detection of incomplete handshakes (potential port scans).
The PcapReader reads packets one at a time from disk — never loading the entire file
into memory. This means you can process multi-gigabyte capture files with constant
memory usage.
Forwarded packets are written to a new PCAP file in real time. The output file contains only the "clean" traffic — blocked packets are physically absent. You can then open this file in Wireshark or feed it into another tool.
| Flag | Description | Example |
|---|---|---|
--live <device> |
Capture from live interface (use 'default' for default interface). Requires dpi_live executable. | --live default |
--block-ip <ip> |
Block source IP (can be repeated) | --block-ip 192.168.1.50 |
--block-app <app> |
Block application by name | --block-app YouTube |
--block-domain <dom> |
Block domain (substring match) | --block-domain tiktok.com |
--lbs <n> |
Number of Load Balancer threads (default: 2) | --lbs 4 |
--fps <n> |
Fast Path threads per LB (default: 2) | --fps 4 |