flowscope 0.22.0

Passive flow & session tracking for packet capture (runtime-free, cross-platform)
Documentation
name: Rust

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

env:
  CARGO_TERM_COLOR: always

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: Format check
      run: cargo fmt --all -- --check
    - name: Build
      run: cargo build --all-features --verbose
    - name: Clippy
      run: cargo clippy --all-features --all-targets -- -D warnings
    - name: Run tests
      run: cargo test --all-features --verbose
    - name: Doc build
      run: cargo doc --all-features --no-deps
      env:
        RUSTDOCFLAGS: -D warnings

  feature-matrix:
    # Library-only build + clippy across a small matrix of partial-
    # feature combinations so latent cfg-gate dead-code issues in
    # `src/` fail at PR time, not when a user enables an unusual
    # combo. Test code is intentionally not included: it assumes
    # `--all-features` and is covered by the `build` job above.
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        features:
          - ""                  # default features only
          - "pcap"              # offline source, no L7
          - "dns"               # gate for obs::trace_session_message
          - "http,tls"
          - "metrics,tracing"
          - "icmp"              # standalone ICMP parser
          - "l7,pcap"           # `l7` now includes icmp
          - "serde"             # 0.8: serde on core types
          - "serde,l7,pcap"     # 0.8: serde on L7 messages
          - "chrono"            # 0.12: chrono interop on Timestamp
          - "emit"              # 0.10: bare CSV + Zeek writers (no serde) — distinct cfg path
          - "aggregate"         # 0.10: Histogram + Percentile (t-digest) standalone
          - "emit-eve"          # 0.12: Suricata EVE JSON writer
          - "tls-fingerprints"  # 0.12: collapses former ja3 + ja4 sub-features
          - "ja4plus"           # 0.16: FoxIO-licensed JA4S (opt-in, off by default)
          - "ja4plus,http"      # 0.18: JA4H FoxIO HTTP fingerprint (issue #10)
          - "file-hash"         # 0.12: streaming hash sinks + MIME magic
          - "ndp"               # 0.18: IPv6 Neighbor Discovery parser (issue #6)
          - "dhcp"              # 0.18: DHCP parser + Fingerbank fingerprint (issue #11)
          - "lldp"              # 0.18: LLDP L2 discovery parser (issue #23)
          - "cdp"               # 0.18: CDP Cisco Discovery Protocol parser (issue #25)
          - "tcp_fingerprint"   # 0.18: p0f-style passive TCP/IP fingerprint (issue #9)
          - "ssh"               # 0.18: SSH parser + HASSH fingerprint (issue #7)
          - "ipfix"             # 0.18: IPFIX IE vocabulary module (scoped piece of #16)
          - "ntp"               # 0.18: NTP parser + amplification detection (issue #14 sub-piece)
          - "ssdp"              # 0.18: SSDP parser + IoT asset discovery (issue #14 sub-piece)
          - "tftp"              # 0.18: TFTP parser + device-config-theft detection (issue #14 sub-piece)
          - "asset"             # 0.19: self-sufficient — pulls its discovery parsers (issue #87)
          - "asset,arp,ndp,dhcp,lldp,cdp,ssdp"  # 0.18: explicit-parser combo (now redundant but kept)
          - "mdns"              # 0.18: mDNS module (issue #14 sub-piece)
          - "asset,mdns"        # 0.18: mDNS asset adapter
          - "ml-features"       # 0.18: CICFlowMeter ml-features subset (issue #15 sub-piece)
          - "netbios-ns"        # 0.18: NetBIOS-NS parser (issue #14 sub-piece)
          - "asset,netbios-ns"  # 0.18: NetBIOS-NS asset adapter
          - "ftp"               # 0.18: FTP control-channel parser (issue #14 sub-piece)
          - "smtp"              # 0.18: SMTP control-channel parser (issue #14 sub-piece)
          - "wireguard"         # 0.18: WireGuard handshake detection (issue #14 sub-piece)
          - "modbus"            # 0.18: Modbus/TCP parser (issue #14 sub-piece)
          - "stun"              # 0.18: STUN datagram parser (issue #14 sub-piece)
          - "rdp"               # 0.18: RDP X.224 negotiation parser (issue #14 sub-piece)
          - "ipfix-export"      # 0.18: IPFIX binary wire encoder (issue #28)
          - "snmp"              # 0.18: SNMP v1/v2c parser (issue #14 sub-piece)
          - "radius"            # 0.18: RADIUS parser (issue #14 sub-piece)
          - "dnp3"              # 0.18: DNP3 metadata-only parser (issue #29)
          - "ml-features-nprint" # 0.18: nPrint per-packet ternary header-bit matrix (issue #30)
          - "kerberos"          # 0.18: Kerberos parser (issue #13)
          - "ldap"              # 0.18: LDAP parser (issue #13)
          - "smb"               # 0.18: SMB2/3 parser M1 (issue #12)
          - "quic"              # 0.18: QUIC Initial parser (issue #3)
          - "tls-fingerprints,quic"  # 0.20: JA4-QUIC client fingerprint (issue #82)
          - "community-id"      # 0.19: Corelight Community ID v1 flow hashing (issue #76)
          - "community-id,emit-eve"  # 0.19: community_id in the EVE writer
          - "ja4plus"           # 0.19: JA4L latency fingerprint (issue #77)
          - "ja4plus,tcp_fingerprint"  # 0.19: JA4T/JA4TS TCP fingerprint (issue #77)
          - "ja4plus,ssh"       # 0.19: JA4SSH session fingerprint (issue #77)
          - "analysis"          # 0.19: analysis layer, no parser observe_* gated in (issue #83)
          - "analysis,tls,dns"  # 0.19: analysis layer with the gated observe_* adapters (issue #83)
          - "l7"                # 0.19: L7 umbrella builds on its own (issue #87)
          - "full"              # 0.19: `full` ⊇ `l7` + all license-clean caps (issue #87)
          # 0.20: the high-level `*_from_pcap` typed helpers need the offline
          # engine (session+reassembler). These combos pin that the
          # per-parser feature pulls reassembler so `<parser>,pcap` compiles.
          - "quic,pcap"         # datagram helper (initials_from_pcap)
          - "dns,pcap"          # datagram + TCP helpers (messages/exchanges_from_pcap)
          - "kerberos,pcap"     # datagram + TCP helpers (messages_from_pcap)
          - "smb,pcap"          # session helper (messages_from_pcap)
          - "ldap,pcap"         # session helper (messages_from_pcap)
          - "tls,pcap"          # session helper (client_hellos/handshakes_from_pcap)
          - "parsers-core"      # 0.19: tier — http/tls/dns/icmp (issue #87)
          - "parsers-l2l3"      # 0.19: tier — arp/ndp/lldp/cdp/dhcp (issue #87)
          - "parsers-tier2"     # 0.19: tier — the 19 Tier-2 parsers (issue #87)
          - "nsm"               # 0.19: tier — fingerprint+tls-fingerprints+analysis (issue #87)
          - "ml"                # 0.19: tier — ml-features + ml-features-nprint (issue #87)
          - "export"            # 0.19: tier — ipfix(+export) + emit writers (issue #87)
    steps:
      - uses: actions/checkout@v4
      - name: Build (--no-default-features --features "${{ matrix.features }}")
        run: cargo build --no-default-features --features "${{ matrix.features }}"
      - name: Clippy (--no-default-features --features "${{ matrix.features }}")
        run: cargo clippy --no-default-features --features "${{ matrix.features }}" -- -D warnings

  semver:
    # Pre-1.0 API-stability gate (issue #78). Catches *accidental*
    # breaking changes against the last crates.io release. Intentional
    # breaks are fine — bump the version + label the PR `breaking`;
    # cargo-semver-checks keys off the version, so a major/minor bump
    # that matches the change passes.
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: cargo-semver-checks
        uses: obi1kenobi/cargo-semver-checks-action@v2
        with:
          feature-group: all-features