Repository navigation
Description
Background
Surfaced in PR #212 review by @chatgpt-codex-connector (resolver.py:43 thread):
On a dual-stack host this new IPv6-capable service is still selected through
_pop_random_ip_host(), so most runs can hit one of the IPv4-only endpoints and store the IPv4 external address. SinceJudge.check()later accepts a judge only when that singlereal_ext_ipappears in the page, any judge reached over IPv6 will be rejected even though IPv6 works.
Why this needs its own ticket
Adding api64.ipify.org to _ip_hosts (PR #212) was a necessary first step — the resolver no longer rejects IPv6 responses. But _pop_random_ip_host() still picks uniformly at random, so on a dual-stack host you get IPv4 ext-IP about 80% of the time (4 of 5 default hosts are v4-only).
The right fix is a design choice with at least three reasonable options:
- Prefer api64.ipify.org first (deterministic). Try it; only fall back to others if it fails. Simplest, but loses load-balancing across services.
- Probe both v4 and v6 separately and store both
real_ext_ip_v4+real_ext_ip_v6.Judge.check()then accepts whichever appears on the page. Most correct for dual-stack hosts but requires plumbing two values through the comparison sites. - Happy Eyeballs at the IP-discovery layer (race the v4 and v6 probes in parallel, take the first to succeed). Mirrors the DNS layer behavior added in PR feat(ipv6): full IPv6 support across the stack (#201) #212.
Each has different trade-offs (latency, cost, code complexity, observability). PR #212's scope was 'IPv6 first-class across the stack' — this is a follow-up refinement.
Acceptance criteria
- A user on a dual-stack host running
Resolver().get_real_ext_ip()reliably gets an address whose family matches the network the broker will then connect to judges over. - If only one family is reachable, that one wins (no false-negative rejections in
Judge.check()). - Existing IPv4-only contracts preserved (caller passing
family=AF_INETor similar should be respected if/when introduced).
Activity
chore(release): 2.0.0b3
chore(resolver): remove dead _pop_random_ip_host + _temp_host
fix(ipv6): address PR #225 review - 8 inline items
Merge pull request #225 from bluet/feat/deterministic-ipv6-ext-ip-220
feat(resolver): deterministic IPv6 ext-IP discovery via per-family pr…