Protocol x-ray
Every octet, named by the code that read it
The DNS codec is 1,341 lines over encoding/binary and net/netip, with name compression in both directions and a fuzz target over the decoder that has run 38.4 million executions clean. It found two compression bugs that code review and twenty hand-written malformed cases had both missed.
ID (Transaction ID)
Octets
85 ea
Decoded
0x85ea generated with crypto/rand to prevent off-path answer forgery.
Every span comes from the decoder the resolver itself runs, so this column records what the parser did rather than a second reading of the bytes.
The counts are not trusted
A header claiming 65,535 answers in 40 octets is a message that fails with a typed error rather than one that allocates. Each count bounds a loop; none of them sizes a buffer, and every read is bounded by the octets actually present.
Pointers must go strictly backwards
The first compression pointer must target an offset below its own position, and each one after it below the previous target. Targets therefore strictly decrease, so the walk terminates by construction — no visited set, no jump budget. Comparing against the previous target rather than the read position is what makes it sound.
An unknown type still round-trips
A record this codec does not model keeps its octets verbatim under RFC 3597 and re-encodes unchanged, because a resolver that rejects an unfamiliar type is broken. Nine types are parsed into fields; everything else stays opaque and intact.
The annotation comes from the parser
wire.Annotate walks a message with the same decoder the resolver uses and records a span per field. The spans are contiguous and cover every octet, asserted against captured fixtures, so a region nobody can name fails a test rather than being skipped over.
The same reply, as printed
One row per field rather than per fixed-width line, so a field and its meaning stay together and nothing is split across two rows.
$ hollow inspect example.com;; 72 octets from [2803:f800:50::6ca2:c0a2]:53 over udp in 21.438ms0000 85 ea ID 0x85ea0002 84 00 flags QR=1 opcode=0 AA=1 TC=0 RD=0 RA=0 AD=0 CD=0 rcode=00004 00 01 QDCOUNT 10006 00 02 ANCOUNT 20008 00 00 NSCOUNT 0000a 00 01 ARCOUNT 1000c 07 65 78 61 6d 70 6c 65 QNAME example.com. = "example" "com"0014 03 63 6f 6d 000019 00 01 QTYPE A (1)001b 00 01 QCLASS IN (1)001d c0 0c NAME example.com. = pointer to 0x000c001f 00 01 TYPE A (1)0021 00 01 CLASS IN (1)0023 00 00 01 2c TTL 300 seconds0027 00 04 RDLENGTH 40029 ac 42 93 f3 RDATA address 172.66.147.243002d c0 0c NAME example.com. = pointer to 0x000c002f 00 01 TYPE A (1)0031 00 01 CLASS IN (1)0033 00 00 01 2c TTL 300 seconds0037 00 04 RDLENGTH 40039 68 14 17 9a RDATA address 104.20.23.154003d 00 NAME . = root, one zero octet003e 00 29 TYPE OPT (41)0040 04 d0 UDP size 1232 octets the sender will accept0042 00 00 00 00 extended rcode and flags version 0, DO=00046 00 00 RDLENGTH 0