Overview

  • Protocol Processing Overview

    Introduction

    The protocol processing infrastructure powers both jNetPcap and jNetWorks, providing high-performance packet dissection, reassembly, and analysis. The architecture is designed for extreme throughput (up to 800Gbps) while maintaining flexibility for diverse use cases from simple packet inspection to complex protocol analysis.

    Design Principles

    • Packet-centric push model with dual return paths (processPacket and processProtocol)

    • Zero-allocation fast path – Header instances are reused and rebound via hasHeader()

    • Single-threaded per ProcessorTree – No internal locks, parallelism via multiple trees

    • Specification lifecycle – All configurable components follow Spec → ResolvedSpec → RuntimeSpec pattern

    • Layered configuration – Protocol settings extend Settings with resolution from code, files, system properties, and environment

    • Depth support for tunneled/encapsulated protocols (IP-in-IP, GRE, VLAN stacking)

    • Decap pattern to simplify processing of nested encapsulations

    • Token emission – Analysis results delivered via user callbacks, token streams, or attached to packets

    • Bitmask pruning – Analyzers disabled at zero cost when no subscribers

    Three-Tier Architecture

    ┌─────────────────┐      resolve()      ┌─────────────────┐      build()      ┌─────────────────┐
    │  ProtocolStack  │ ──────────────────► │  ProtocolTree   │ ────────────────► │  ProcessorTree  │
    │                 │                     │                 │                   │                 │
    │  User config    │                     │   Validated     │                   │  Runtime        │
    │  Mutable        │                     │   Immutable     │                   │  Per-stream     │
    │  Fluent API     │                     │  Backend-aware  │                   │  Stateful       │
    └─────────────────┘                     └─────────────────┘                   └─────────────────┘
    Tier
    Purpose
    Characteristics

    ProtocolStack

    User configuration

    Mutable, fluent API, protocol settings

    ProtocolTree

    Validated template

    Immutable, backend constraints applied

    ProcessorTree

    Runtime execution

    Per-stream instance, owns state tables

    Processing Model

    The processor tree supports two entry methods to accommodate different output requirements:

    Method
    Returns
    Used By

    processPacket(Packet, ctx)

    Packet

    jNetPcap, jNetWorks PacketStreams

    processProtocol(ctx)

    ProtocolObject

    jNetWorks ProtocolStreams, DataStreams

    Processors form a tree with routing branches based on protocol fields:

    Raw ──► EthProcessor ──► IpProcessor ──┬──► TcpProcessor ──┬──► HttpProcessor
                                           │                   └──► TlsProcessor
                                           └──► UdpProcessor ──┬──► DnsProcessor
                                                               └──► QuicProcessor

    Token Emission

    Analyzers and processors emit tokens containing analysis results, flow events, and metadata. Tokens can be delivered through multiple channels:

    Delivery Method
    Use Case

    User callback

    jNetPcap – tokens delivered via registered consumer

    TokenStream

    jNetWorks – dedicated stream for token processing

    Packet attachment

    Tokens travel with packet through pipeline

    ProtocolObject attachment

    Tokens attached to reassembled protocol output

    Token types include:

    • Flow boundary markers (SYN, FIN, RST)

    • Reassembly status (complete, timeout, overlap)

    • IDS/IPS alerts

    • Anomaly detection results

    • Index beacons for sparse/dense indexing

    • Custom user-defined tokens

    PacketPolicy

    PacketPolicy controls how packets are acquired, bound, and released:

    Policy
    Description
    Use Case

    ZeroCopy

    Bind directly to native memory

    High-speed capture

    MemoryCopy

    Copy to pre-allocated pool

    Packet persistence, queuing

    FactoryCopy

    Custom allocation strategy

    Arena-based allocation

    All policies pre-allocate packet structures to eliminate hot-path allocation.

    Configuration Example

    ProtocolStack stack = new ProtocolStack();
    
    // Configure protocols
    stack.setProtocol(new IpProtocol())
         .enableReassembly(true)
         .fragmentTimeout(30);
    
    stack.setProtocol(new TcpProtocol())
         .enableReassembly(true);
    
    // Configure packet handling
    stack.setPacketPolicy(PacketPolicy.zeroCopy())
         .usePacketPool(new PacketPoolSettings()
             .capacity(100_000));
    
    // Subscribe to tokens
    stack.subscribeTokens(TCP_LAYER, TcpTokens.FLOW_BOUNDARY);

    Parallelism Model

    • Each stream gets its own ProcessorTree instance

    • No shared state between trees (except optional shared fragment table)

    • Hash distribution ensures related packets (same flow) go to same stream

    • Linear scaling with stream/CPU count

    PacketStream[0] ──► ProcessorTree[0] ──► Output
    PacketStream[1] ──► ProcessorTree[1] ──► Output
    PacketStream[2] ──► ProcessorTree[2] ──► Output
    PacketStream[N] ──► ProcessorTree[N] ──► Output

    Module Organization

    Module
    Description

    sdk-protocol-core

    Core interfaces: Protocol, Processor, Router, Analyzer

    sdk-protocol-tcpip

    IP reassembly, TCP reassembly, state tracking

    sdk-protocol-web

    TLS decryption, QUIC, HTTP/1.x, HTTP/2, HTTP/3

    sdk-protocol-infrastructure

    Bridge, routing, discovery protocols

    sdk-protocol-telco

    Telecommunications (GTP, SCCP, PFCP)

Last updated