Skip to content

Let miners reach the pool over IPv6, behind a config gate - #73

Merged
rsantacroce merged 1 commit into
LayerTwo-Labs:mainfrom
Wired4ncer:up/ipv6-dual-stack
Sep 1, 2026
Merged

Let miners reach the pool over IPv6, behind a config gate#73
rsantacroce merged 1 commit into
LayerTwo-Labs:mainfrom
Wired4ncer:up/ipv6-dual-stack

Conversation

@Wired4ncer

Copy link
Copy Markdown
Contributor

A pool whose hostname publishes an AAAA record looks healthy over IPv6 while stratum, bound IPv4-only, refuses the connection. A miner whose client prefers AAAA — the RFC 6724 default — never starts mining, and unlike a browser most mining firmware has no Happy Eyeballs fallback to recover with. It is invisible from the pool side: a refused connection never reaches the process.

listen_addr now selects the family:

"" or "0.0.0.0"  -> IPv4 only, exactly as before
"::"             -> dual-stack, IPv6 and IPv4 both reach the pool
IPv4 literal     -> that IPv4 address only
IPv6 literal     -> that IPv6 address only

0.0.0.0 deliberately does not become dual-stack, even though overloading it would deliver the fix to every existing deployment for free. Installing a new binary shouldn't change listening behaviour nobody asked it to change. Set listen_addr = :: to turn it on; the revert is one config line, no rebuild.

IPV6_V6ONLY is set explicitly in both directions rather than inherited from net.ipv6.bindv6only, so listening behaviour doesn't depend on a host sysctl nobody records with the deployment.

accept() now writes into a sockaddr_storage. It was a sockaddr_in, which can't hold the sockaddr_in6 an IPv6 listener produces — the kernel truncates silently, and since the connection is still accepted nothing would ever look wrong.

Three tests over real sockets, because connections made through the test helpers never go through accept(): an IPv6 client is accepted on a dual-stack listener, an IPv4 client still is, and 0.0.0.0 still refuses IPv6. That last one is the gate — without it, two accepted-everywhere results would be equally consistent with the config check being ignored and every deployment silently becoming dual-stack. Mutation-checked: disabling the dual-stack branch fails the suite.

A pool whose hostname publishes an AAAA record looks healthy over IPv6 while
stratum, bound IPv4-only, refuses the connection. A miner whose client prefers
AAAA -- the RFC 6724 default -- never starts mining, and unlike a browser most
mining firmware has no Happy Eyeballs fallback to recover with. The failure is
invisible from the pool side: a refused connection never reaches the process.

listen_addr now selects the address family:

  "" or "0.0.0.0"  -> IPv4 only, exactly as before
  "::"             -> dual-stack, IPv6 and IPv4 both reach the pool
  IPv4 literal     -> that IPv4 address only
  IPv6 literal     -> that IPv6 address only

"0.0.0.0" deliberately does NOT become dual-stack, even though overloading it
would deliver the fix to every existing deployment for free. Installing a new
binary must not change listening behaviour nobody asked it to change. Setting
listen_addr = :: turns it on and the revert is one config line, no rebuild.

IPV6_V6ONLY is set explicitly in both directions rather than inherited from
net.ipv6.bindv6only, so the pool's listening behaviour does not depend on a
host sysctl nobody records alongside the deployment.

accept() now writes into a sockaddr_storage. It was a sockaddr_in, which
cannot hold the sockaddr_in6 an IPv6 listener produces -- the kernel would
truncate the address silently, and since the connection is still accepted
nothing would ever look wrong.

Three tests over real sockets, because connections made through the test
helpers never go through accept() at all: an IPv6 client is accepted on a
dual-stack listener, an IPv4 client still is, and 0.0.0.0 still refuses IPv6.
That last one is the gate -- without it, two accepted-everywhere results would
be equally consistent with the config check being ignored and every deployment
silently becoming dual-stack. Mutation-checked: disabling the dual-stack
branch fails the suite.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@rsantacroce
rsantacroce merged commit 2777caa into LayerTwo-Labs:main Sep 1, 2026
7 checks passed
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