Skip to content

fix(v2): parse AF_UNIX addresses; add criterion benches - #24

Open
pigri wants to merge 3 commits into
mainfrom
fix/v2-unix-address-parse
Open

fix(v2): parse AF_UNIX addresses; add criterion benches#24
pigri wants to merge 3 commits into
mainfrom
fix/v2-unix-address-parse

Conversation

@pigri

@pigri pigri commented Aug 15, 2026

Copy link
Copy Markdown

AF_UNIX v2 headers could never parse

version2::parse consumed the 216-byte address block twice — once in a
dedicated address_family == Unix pre-read, then again in the address
match. The second read could not be satisfied, so the
ensure!(remaining >= address_len) in front of it turned every AF_UNIX
v2 header into UnexpectedEof. The pre-read also skipped any TLVs that
followed a Unix address (an old TODO: Support TLVs).

The fix drops the pre-read. The length >= 216 check it carried is not
lost — the checked_sub below raises the identical
InsufficientLengthSpecified { given, needs: 216 } — and TLVs now flow
through the same extension loop as every other address family.

Tests added (each verified to fail with the bug re-introduced):

  • parse_tests::test_unix — a plain AF_UNIX header parses
  • parse_tests::test_unix_with_tlv — trailing TLVs are parsed, not skipped
  • parse_tests::test_unix_length_too_short — a length below 216 is refused
  • encode_tests::test_unix_roundtrip — encode → parse round-trip

Criterion benches

One parse per accepted connection and one encode per upstream connection,
so both are worth tracking. Covers v1 tcp4/tcp6/unknown, v2
inet/inet6/inet+TLVs, the non-PROXY rejection path, and a round-trip.

Reference numbers on the current code: v2 inet parse 59 ns, v1 tcp4 parse
131 ns, v2 inet encode 71 ns, non-PROXY rejection 12 ns.

pigri added 3 commits August 16, 2026 00:29
The address block was consumed twice: once by a dedicated
address_family == Unix pre-read, then again by the address match that
follows. The second read could never be satisfied, so the length guard
in front of it turned every AF_UNIX v2 header into UnexpectedEof. The
pre-read also skipped any TLVs following a Unix address.

Drop the pre-read. The length >= 216 check it carried is preserved by
the checked_sub below it, which raises the same
InsufficientLengthSpecified { given, needs: 216 }, and TLVs now go
through the same extension loop as every other address family.

Covered by parse tests for the plain, with-TLV and short-length cases,
plus an encode/parse round-trip.
One parse per accepted connection and one encode per upstream
connection, so both are worth tracking: parse and encode for v1 tcp4 /
tcp6 / unknown and v2 inet / inet6 / inet+TLVs, the non-PROXY rejection
path, and a round-trip.
clippy::byte_char_slices, new since this file was last linted, rejects
the char-array form. Same bytes, no behaviour change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant