Skip to content

fix: use dual-stack binding and proper error handling for IPv6 sockets#151

Draft
englishm-cloudflare wants to merge 1 commit intocloudflare:mainfrom
englishm-cloudflare:me/ipv6-dual-stack-binding
Draft

fix: use dual-stack binding and proper error handling for IPv6 sockets#151
englishm-cloudflare wants to merge 1 commit intocloudflare:mainfrom
englishm-cloudflare:me/ipv6-dual-stack-binding

Conversation

@englishm-cloudflare
Copy link
Contributor

Summary

  • Replace the default [::]:0 bind with socket2-based binding that explicitly sets IPV6_V6ONLY=false, enabling cross-platform dual-stack (IPv4 + IPv6) support on a single socket.
  • Config::new() now returns Result instead of panicking on bind failure. Args::load() falls back to 0.0.0.0:port with a warning if IPv6 binding fails.
  • Track actual dual-stack capability at bind time (instead of a compile-time cfg!(target_os = "linux") assumption) and thread is_dual_stack through ConfigEndpointClient so address_family() detection is accurate at connect time.

Motivation

On macOS and Windows, IPv6 sockets default to IPV6_V6ONLY=true, which means binding to [::] only accepts IPv6 connections. When a client on one of these platforms tries to connect to an IPv4-only host, the connection silently fails. Linux happens to default to dual-stack, so this went unnoticed there.

This change makes the behavior consistent across platforms by explicitly requesting dual-stack mode, with a graceful fallback to IPv4-only when the OS or network doesn't support it.

Replace the default [::]:0 bind behavior with socket2-based binding
that explicitly sets IPV6_V6ONLY=false for cross-platform dual-stack
support. On macOS/Windows, IPv6 sockets are IPv6-only by default,
causing connection failures when targeting IPv4-only hosts.

Changes:
- Add bind_smart() using socket2 to request dual-stack on IPv6 sockets
- Config::new() now returns Result instead of panicking on bind failure
- Args::load() falls back to 0.0.0.0:port with a warning if IPv6 fails
- Track actual dual-stack state at bind time instead of using
  compile-time cfg!(target_os = "linux") assumption
- Thread is_dual_stack through Config -> Endpoint -> Client for
  accurate address_family() detection at connect time
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.

2 participants