Skip to main content

Module transaction_sequence

Module transaction_sequence 

Source
Expand description

Structured event sequences for the transaction layer, and the invariants they are checked against.

sipx-sip has four fuzz targets and all of them stop at the parser. That covers the half of the north star about adversarial input; the half about adversarial timing — what happens when messages, application calls and fired timers interleave in an order nobody wrote a test for — had nothing. This module is that instrument.

§Programs, not bytes

The fuzzer’s bytes are decoded into a Program: a sequence of Events over a small vocabulary, each of which the harness turns into a well-formed SIP message or a call on TransactionLayer. Reinterpreting the bytes as SIP instead would spend the whole budget producing messages that do not parse, which is S-4’s fuzz targets again with extra steps. Nothing here parses: messages are built, so every event reaches a state machine.

The encoding is four bytes per event — opcode, target, and two operands — because libFuzzer mutates bytes and a fixed-width record keeps a byte flip to a single field instead of desynchronising the rest of the program. Every opcode byte is valid (it is taken modulo the opcode count), so no input is wasted on a decode failure.

§The oracle

A panic-only oracle finds almost nothing in a state machine: the machines are total, so almost any sequence “succeeds”. What can go wrong is silent, so it is asserted explicitly — see Invariant. Violations are returned as data rather than panicked on, so the same code serves the fuzz target (which panics) and the regression tests (which assert).

§Sans-IO

No clock, no socket, no runtime, in keeping with AGENTS.md’s second non-negotiable. Time enters only as Event::FireTimer, which is precisely what makes the timing half fuzzable.

Structs§

Program
A decoded sequence of events.
Run
What driving a program produced.
Seed
A named seed program, committed to the corpus as the bytes it encodes to.
Violation
One invariant broken, and where.

Enums§

Event
One step of a decoded program.
Invariant
The properties a transaction layer can break without panicking.
Known
A defect the campaign knows about and steps over.

Constants§

CORPUS_PATH
Where the committed seed corpus lives, relative to the repository root.
FIRST_LEGACY_SLOT
Slots at or above this index use a branch with no RFC 3261 magic cookie, so they exercise the RFC 2543 matching fallback of TransactionKey::Legacy.
KNOWN_DEFECTS
Every defect run steps over.
MAX_LIVE_TRANSACTIONS
The most transactions that can be in flight at once, whatever the program does.
SLOTS
How many conversations the vocabulary can name.
STATUSES
Status codes the vocabulary can produce: provisional, 2xx, and non-2xx finals across the ranges the state tables branch on.
TAGS
To-tags the vocabulary can produce. Three, because two are needed for a fork answering twice and the third distinguishes a legacy key.
TIMERS
Every timer of RFC 3261 §17 Table 4, plus the unlettered 200 ms one.

Functions§

corpus_dir
The committed seed corpus directory.
run
Drive a program and check it, stepping over KNOWN_DEFECTS.
run_strict
Drive a program and check it, suppressing nothing.
run_with
Drive a program and check it, suppressing the named defects.
seeds
The programs the corpus is seeded from.
write_corpus
Write seeds to corpus_dir, one file per seed.