Skip to content

Networking Design & TCP Reassembly: Aegis Packet Engine

1. Zero-Copy Protocol Parsing

Aegis decodes network protocol headers sequentially by reading directly from the raw memory buffer. The parser does not copy fields; instead, it casts memory segments to struct pointers or references.

Raw Packet Buffer:
[ Ethernet Header (14B) ][ IPv4 Header (20B) ][ TCP Header (20B) ][ Payload (Variable) ]
^                        ^                     ^                  ^
|                        |                     |                  |
+-- eth_offset           +-- ip_offset         +-- tcp_offset     +-- payload_offset

Parser Casts:

  • Ethernet: const EthernetHeader* eth = reinterpret_cast<const EthernetHeader*>(data);
  • IPv4: const IPv4Header* ip = reinterpret_cast<const IPv4Header*>(data + eth_offset);
  • TCP: const TCPHeader* tcp = reinterpret_cast<const TCPHeader*>(data + ip_offset + (ip->version_ihl & 0x0F) * 4);

All byte order adjustments (Big-Endian to Host-Endian) are performed in-place using fast macros or compiler builtins (e.g. __builtin_bswap16, __builtin_bswap32 or ntohs/ntohl).


2. Stateful TCP Flow State Machine

Aegis tracks the standard TCP lifecycle to correctly handle flow creation, payload inspection, and reclamation.

       [NEW] (SYN Packet)
   [ESTABLISHED] (SYN-ACK / ACK)
         ├───────────────────────────┐
         ▼                           ▼
  [INSPECT PAYLOAD]           [TERMINATING] (FIN / RST Packet)
         │                           │
         ▼                           ▼
  [CLASSIFIED] (SNI Found)        [CLOSED]

Flow Lifetime Rules:

  1. Creation: A new connection entry is created when a SYN packet is detected.
  2. Promotion: Promoted to ESTABLISHED once the handshake completes (SYN-ACK or payload seen).
  3. Classification: Promoted to CLASSIFIED once the application type (HTTP, TLS, DNS) is identified.
  4. Cleanup: Closed when a FIN or RST is processed, or when the inactivity timer expires (default: 300 seconds).

3. TCP Segment Reassembly for Handshake Detection

Sometimes, the TLS Client Hello or HTTP request is split across multiple TCP segments due to TCP window fragmentation or path MTU limitations. If the engine inspects only individual packets, it will fail to classify these flows.

In-Buffer Reassembly Mechanism:

  • Connection Reassembly Buffer: Each Flow entry has a small pre-allocated scratch buffer (e.g. 4096 bytes).
  • Out-of-Order Queue: A fixed-size array inside the Flow tracks segments out of sequence.
  • Process:
  • If a packet contains a portion of the TLS handshake but not the complete extensions block, the payload is appended to the scratch buffer.
  • The parser tracks the expected sequence number (expected_seq).
  • If the next segment matches expected_seq, it is appended.
  • Once the buffer contains enough contiguous bytes to parse the TLS Client Hello (e.g., matching the TLS length field in the TLS record header), the SNIExtractor parses the combined scratch buffer.
  • Once classified, the scratch buffer is cleared to save memory.