fix(wind-base): bind direct UDP relay dual-stack for IPv6 targets#48
Merged
Conversation
The direct UDP relay bound its socket to `0.0.0.0:0` (IPv4 only), so any
packet whose target resolved to an IPv6 address failed `send_to` with
EAFNOSUPPORT ("Address family not supported by protocol") and was dropped
— logged only as a warning. IPv4 targets worked; IPv6 targets silently
never reached.
Bind the relay socket dual-stack instead (IPv6 with IPV6_V6ONLY=false,
falling back to IPv4-only on hosts without IPv6), mirroring wind-socks'
`udp_bind_random_port`. Since a single association can target both
families over the one socket, also:
- map IPv4 targets to their IPv4-mapped form (::ffff:a.b.c.d) before
send_to — a bare V4 address on a dual-stack socket hits the same
EAFNOSUPPORT inverted; and
- unmap IPv4-mapped sources on the receive path so replies carry the
responder's real address family (TargetAddr::from does not
canonicalize), letting the client match replies to the target it sent.
Adds unit tests for the mapping helpers and end-to-end integration tests
(tests/udp_relay.rs) driving handle_udp against real loopback echo servers
over IPv4, IPv6, and both families on a single association.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Merging this PR will not alter performance
Comparing Footnotes
|
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptom
The direct UDP relay logs this for every IPv6 target, dropping the packet:
IPv4 destinations work; every IPv6 destination is silently dropped (logged only).
Root cause
relay_udp_directbound its socket to0.0.0.0:0— an IPv4-only (AF_INET) socket — sosend_toan IPv6 address returnsEAFNOSUPPORT. The TCP path right next to it already selects the family per target; only the UDP relay was hard-wired to IPv4.Fix
Bind the relay socket dual-stack (
IPV6_V6ONLY=false, with an IPv4-only fallback for hosts without IPv6), mirroringwind-socks'sudp_bind_random_port. A single UDP association can target both families over the one socket, so additionally:::ffff:a.b.c.d) — a bareSocketAddr::V4on a dual-stack socket hits the sameEAFNOSUPPORTinverted, which would otherwise trade the IPv6 failure for an IPv4 regression;TargetAddr::fromdoes not canonicalize), letting the client match a reply to the target it sent to.Tests
map_target_for_socket/unmap_sourcehelpers.tests/udp_relay.rs— end-to-end through the publichandle_udpagainst real loopback echo servers: IPv4, IPv6, and both families on one association.Verified these actually catch the bug: temporarily reverting the socket to IPv4-only makes the IPv6 tests fail by timeout (send dropped) while the IPv4 test still passes.
🤖 Generated with Claude Code