feat(engine): read and report the WinDivert queue a session runs behind - #62
Merged
Merged
Conversation
`pydivert.WinDivert(filt)` never received a set_param(), and the package had no get_param() at all, so the driver's own queue was invisible. With QUEUE_TIME at its default a packet may be held for up to two seconds - latency this tool adds while being blind to it - and nothing in a session artefact said what queue produced its numbers. Measured on the owner's machine before designing anything (elevated, real driver): QUEUE_LEN=4096, QUEUE_TIME=2000, QUEUE_SIZE=4 MiB. The size limit binds before the length one for full frames: 4 MiB / 1500 B = 2796 packets, not 4096. Deliberately NOT retuned. The trade is real both ways and both sides are invisible today - a large QUEUE_TIME is latency the tool hides, a small one is loss it cannot even count, because a packet the driver drops never reaches us. Choosing values before measuring the actual queue delay is machinery around the wrong primitive (convention 6). The measurement is part b. The three values are read after the handle opens, logged at START, and stored in the repro report as session.driver_queue. None - not zeroes - on the simulate path: "no driver" and "a queue of nothing" are different claims. The param numbers are spelled out rather than imported from pydivert.consts, because pydivert is win32-only: importing it here would make the read return None on the Linux half of the CI matrix while passing on Windows. A guard test compares them against the real enum wherever pydivert IS importable. --doctor deliberately does not read them: they need an open handle, and opening one loads the driver, falsifying the "windivert driver" check printed two lines above it in the same report. Three mutants, every one caught. No hot-path change - three calls per session. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Audit finding F10, part a - visibility. The measurement half (part b) follows separately,
because it touches the capture loop and this does not.
pydivert.WinDivert(filt)never received aset_param(), and the package contained noget_param()at all. So WinDivert's own queue - the one ahead of this tool's - was invisible:with
QUEUE_TIMEat its default a packet may be held for up to two seconds, which is latencythis tool adds while being blind to it, and no session artefact said what queue produced its
numbers.
Measured first, on the real driver
An elevated throwaway ICMP handle on the owner's machine (2026-07-28):
QUEUE_SIZEbinds beforeQUEUE_LENfor full frames - 4 MiB / 1500 B = 2796 packets - so at asaturated gigabit (83k pkt/s of 1500 B) a frozen capture thread has roughly 34 ms before the
driver starts discarding. And the 2000 ms is a ceiling, not a routine cost: on an idle machine the
queue adds 0.08 ms. Knowing which of those two a session was living in is exactly what part b is for.
Deliberately NOT retuned
The trade is real in both directions, and both sides are invisible today: a large
QUEUE_TIMEis latency the tool hides; a small one is loss the tool cannot even count, because a packet the
driver drops never reaches us, so no counter can see it. Picking values before measuring the actual
queue delay is machinery around the wrong primitive (convention 6). Measure first.
What changed
_read_driver_queue()reads the three params once the handle is open,session_info()carriesthem into the repro report as
session.driver_queue, and one line goes to the log at START.None- not zeroes - on the simulate path. "No driver" and "a queue of nothing" are differentclaims.
Reaching for
pydivert.consts.Paramhere would import a win32-only dependency: the read wouldreturn
Noneon the Linux half of the CI matrix while passing on Windows - the exact bug shapethat only shows up on the runner you did not run. A guard test compares the numbers against the
real enum wherever pydivert is importable, so they cannot drift in silence.
--doctorgains a line saying where the values live and why it does not read them itself: theyneed an open handle, and opening one loads the driver - which would falsify the "windivert driver"
check printed two lines above it, in the same report.
Verification
python -m pytest tests-> 703 passed, 0 failed (elevated shell).python smoke_gui.py-> OK.the pydivert cross-check catches with
queue_time is 1 in pydivert (engine says 2).Still owed: an end-to-end run on the real driver, to confirm the numbers actually reach the log
line and the repro report rather than just the unit test. Asked for separately.
🤖 Generated with Claude Code