Skip to content

Kernel timestamps via SO_TIMESTAMPNS #59

Description

@EONRaider

Sub-issue of #36. Size: Small–Medium.

What

Capture timestamps currently come from a userspace time.time() call after recv returns (src/rootwire/capture.py), so they include scheduler and interpreter latency between the packet arriving and Python reading it. Switch to kernel timestamps: enable SO_TIMESTAMPNS on the socket and read the SCM_TIMESTAMPNS ancillary message that the kernel attaches to each datagram.

How

  • setsockopt(SOL_SOCKET, SO_TIMESTAMPNS, 1) on the raw socket.
  • Replace sock.recv(BUFFER_SIZE) with sock.recvmsg(BUFFER_SIZE, socket.CMSG_SPACE(16)) and parse the returned ancdata. SCM_TIMESTAMPNS carries a struct timespec (tv_sec, tv_nsec as two native longs) — struct.unpack it.
  • Fall back to time.time() when no timestamp cmsg is present (some interfaces/paths don't provide one), so a missing cmsg never crashes the loop.

Precision decision to make

DecodedFrame.timestamp is a float seconds-since-epoch, and the pcap writer already documents that float µs at 2026 epoch values is lossy (tests/test_pcap.py comments on exactly this). SO_TIMESTAMPNS gives nanoseconds. Decide whether to:

  • keep the float field and accept the precision loss (smallest change), or
  • carry an integer ns timestamp end-to-end (touches frame.py, the pcap record writer, and NDJSON) for lossless capture.

I lean toward the second for a tool aiming at forensic-grade captures, but it widens the change — worth settling before implementation.

Testability (follow the #57 seam)

The cmsg-parsing logic is a pure function — extract it (_parse_timestamp(ancdata) -> float) and unit-test it with synthetic ancdata tuples, no socket required. The recvmsg wiring is exercised the same way #57 tests recv: monkeypatch the module-global socket with a fake whose recvmsg returns canned (data, ancdata, flags, addr). A real SCM_TIMESTAMPNS round trip needs a live socket and belongs in the privilege-gated integration test.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions