The egress answers a site's UDP connect with a socket of the site socket's own family. Before, a site's AF_INET6 UDP socket that asked for an IPv4 address got an AF_INET socket back; glibc's address sorting then read the 16-byte sockaddr_in as IPv6 (::, not v4-mapped), its IN6_IS_ADDR_V4MAPPED assertion fired and the site process aborted, for any name with both A and AAAA records. lichen_sandbox::egress::socket_kind now reads the UDP socket's SO_DOMAIN, so Kind::Datagram becomes Kind::Datagram { inet6 }, and the front's Egress::connect connects an IPv4 address as ::ffff:a.b.c.d on an AF_INET6 socket, after the IP rule judged the requested address. No allow or deny decision changes.
OCTOBER-REVIEW-REVISIONS, subunit 8d. Plan: https://tangled.org/notplants-bot.bsky.social/lichen-orchestrator/blob/main/machine-docs/plans/OCTOBER-REVIEW-REVISIONS-2026-10-28.md
This is a reading copy: only this subunit's product changes, applied in order on its base. Nothing here is to be merged.
Source PRs on lichen.page.review (product), in order, with their original descriptions #
- #3429
s/799-orr-u8d-egress-socket-family— ORR 8d: the egress answers a UDP connect with a socket of the site socket's family (a getaddrinfo abort)ORR fix-up 8d, product: the egress answers a site's UDP
connectwith a socket of the site socket's own family.This is a pre-existing crash, reproduced at the ORR base 65a6666b (notify-9aff0ded), and the closing standard can flake on it in
test_publish_settings_and_dns.-
The crash:
- A site's AF_INET6 UDP socket that asked for an IPv4 address got an AF_INET socket back.
- glibc's address sorting then read the 16-byte
sockaddr_infromgetsocknameas IPv6. That address is::, which is not v4-mapped, so glibc'sIN6_IS_ADDR_V4MAPPEDassertion aborted the site process. - Any name with both A and AAAA records triggers it (codeberg.org in the test). The red run printed
ANSWERED SO_DOMAIN=2 getsockname family=2 length=16 address=::.
-
The fix:
lichen_sandbox::egress::socket_kindreads a UDP socket'sSO_DOMAINbesideSO_TYPE, soKind::DatagrambecomesKind::Datagram { inet6 }(egress.rs:231, :505-519).- The front's
Egress::connect(site_process_supervisor.rs:279-285) connects an IPv4 address as::ffff:a.b.c.don an AF_INET6 socket. It does so after the IP rule has judged the address the site asked for, and the nameserver redirect is handled the same way.
-
What did not change:
- no allow or deny decision;
- TCP's behaviour;
- the guard's grants (empty diff).
The deny lists already judged
::ffff:addresses as the IPv4 address they map to, and the tests PR pins that. -
Left as it was, a design call for review: an AF_INET socket asking for a non-mapped IPv6 address is still answered with an AF_INET6 socket, where the kernel would refuse. glibc and correct clients never ask this.
-
Commits #
- 5686d0d23 ORR 8d: orr-u8d-egress-socket-family (#3429)
Count and shas #
count-product-code-lines 565f6c51794f..5686d0d23bae: NET +26 · counted +32 -6 · moved out of the counted set +0 · comment-only deletions flagged 4 · macros flagged 0 · tests-folder code flagged 0
Base 565f6c51794f75136cb57cca5c7f56cb33752734 (tip of s/798-orr-u8c-standard-fixups-tests). Head 5686d0d23bae83cf2bc3fd84b9de5895aed58869. 6 files changed.
Check #
Every changed file is a file one of the product PRs changed, and each is identical at the head to the same file at the last product branch s/799-orr-u8d-egress-socket-family.
Files that differ from the subunit's top branch s/800-orr-u8d-egress-socket-family-tests: crates/lichen-sandbox/src/tests/egress.rs, crates/lichen-sandbox/src/tests/egress_twins.rs, crates/lichen-server/src/tests/site_process_supervisor.rs.