From: Bug reproduction widener (TEST ONLY — do not ship) Subject: [PATCH] af-packet: add env-gated ring-setup delay for race reproduction This patch adds a deterministic window widener to AFPSetupRing() gated behind the SURICATA_RING_SETUP_DELAY_US environment variable. It does NOT create the bug — the startup race already exists in Suricata 8 due to AFPPeersListReachedInc() being called before AFPSwitchState(AFP_STATE_UP). The widener only holds the existing race window open long enough for thread scheduling to consistently land inside it, making the bug reproducible at ~100% instead of relying on timing luck. With this patch and WIDEN_WINDOW=1 in reproduce.sh (which sets SURICATA_RING_SETUP_DELAY_US=500000), the ENOTSOCK signature fires on essentially every cold restart with 6 interface pairs. This patch is TEST-ONLY. It ships as a no-op (env var unset = zero delay). It should never be merged into a production build. --- a/src/source-af-packet.c +++ b/src/source-af-packet.c @@ -1744,6 +1744,20 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname) { int val; + /* TEST-ONLY: deterministic window widener for race reproduction. + * + * The startup race window is the interval between AFPPeersListReachedInc() + * (called right after bind(), before this function) and + * AFPSwitchState(AFP_STATE_UP) (called after this function returns). + * On a normal build with no memory pressure this window is very narrow + * and thread scheduling may not land inside it. + * + * Setting SURICATA_RING_SETUP_DELAY_US=N holds this window open for N + * microseconds, making the race fire deterministically. + * + * This is a NO-OP unless the env var is set. Never enable in production. + */ + const char *delay_env = getenv("SURICATA_RING_SETUP_DELAY_US"); + if (delay_env != NULL) { + unsigned long delay_us = strtoul(delay_env, NULL, 10); + if (delay_us > 0) { + usleep((useconds_t)delay_us); + } + } + if (ptv->flags & AFP_TPACKET_V3) {