DNS Resolution & IPv6 Support
Relevant source files
The following files were used as context for generating this wiki page:
DNS resolution and IPv6 support in ProxyBroker2 provide the foundation for discovering and validating proxies across modern network stacks. The system implements "Happy Eyeballs" (RFC 8305) for parallel A and AAAA DNS queries and enforces RFC 5952 canonicalization for IP representations. These features allow the project to operate seamlessly on IPv4-only, IPv6-only, and dual-stack networks.
The core logic resides in the Resolver class, which handles asynchronous DNS lookups via aiodns and manages external IP discovery. Sources: proxybroker/resolver.py:32-35, CLAUDE.md:121-125
Architecture and Core Logic
The system prioritizes asynchronous operations and RFC compliance to ensure unambiguous IP handling. It treats IPv6 as a first-class citizen alongside IPv4.
Happy Eyeballs DNS Resolution
When a user requests a hostname resolution without specifying a protocol family, the Resolver initiates parallel queries for both A (IPv4) and AAAA (IPv6) records. The first successful non-empty response determines the result, while the slower task is cancelled. This prevents latency issues on networks where one protocol might be misconfigured or blackholed. Sources: proxybroker/resolver.py:417-440, CHANGELOG.md:46-49
IP Canonicalization
The project uses the RFC 5952 canonical form as the single in-process representation for IP addresses. This involves converting IPv6 addresses to lowercase, stripping leading zeros, and compressing the longest run of zeros into ::. This ensures that different textual encodings of the same address are recognized as identical during anonymity checks. Sources: proxybroker/utils.py:102-111, CHANGELOG.md:27-30
External IP Discovery
ProxyBroker2 identifies the host's real external IP addresses to detect leaks during proxy validation. It probes multiple external services (e.g., api64.ipify.org) using both address families if local routes exist. Sources: proxybroker/resolver.py:146-170, proxybroker/resolver.py:236-248
The diagram shows the parallel discovery process for external IPv4 and IPv6 addresses, including local route pre-checks to avoid unnecessary timeouts. Sources: proxybroker/resolver.py:236-302
Key Components
Resolver Class
The Resolver class manages the DNS lifecycle and IP metadata. It utilizes aiodns for non-blocking name resolution and maxminddb for GeoIP lookups. Sources: proxybroker/resolver.py:32-60
| Function/Method | Action | Source |
|---|---|---|
resolve() | Executes parallel A/AAAA queries (Happy Eyeballs). | resolver.py:417 |
host_is_ip() | Validates if a string is a valid IPv4/IPv6 literal. | resolver.py:73 |
get_ip_info() | Retrieves GeoData (Country, City, Region) from MMDB. | resolver.py:101 |
get_real_ext_ips() | Discovers external IPv4 and IPv6 addresses of the host. | resolver.py:236 |
Utility Helpers
Specific utilities handle the parsing and normalization of IP data across the stack. Sources: proxybroker/utils.py
canonicalize_ip(s): Uses theipaddressmodule to return the RFC 5952 string orNoneif invalid. Sources: proxybroker/utils.py:102-111find_proxy_pairs(text): Extractsip:portand[ipv6]:portpairs from raw text using tokenization and validation. Sources: proxybroker/utils.py:133-145get_all_ip(page): Extracts all valid IP literals from a string, ensuring IPv6 addresses are canonicalized. Sources: proxybroker/utils.py:64-99
Protocol-Specific IPv6 Handling
The project implements specific formatting and protocol changes to support IPv6 across different layers.
URI and Authority Bracketing
Per RFC 3986, IPv6 addresses in URI authority components must be bracketed (e.g., [2001:db8::1]:8080). ProxyBroker2 enforces this in the Proxy class string representations and in HTTP CONNECT requests. Sources: proxybroker/proxy.py:23-33, CHANGELOG.md:43-45
SOCKS Support
- SOCKS5: Supports IPv6 destinations by emitting
ATYP=0x04and the 16-byte address. Sources: CHANGELOG.md:52-54 - SOCKS4: Remains IPv4-only by protocol specification; ProxyBroker2 raises a
BadResponseErrorif an IPv6 destination is requested via SOCKS4. Sources: CHANGELOG.md:55-58
This diagram illustrates the divergence in SOCKS version handling for IPv6 destinations. Sources: CHANGELOG.md:52-58, proxybroker/proxy.py:465-470
Anonymity Detection with IPv6
The Checker component identifies proxy anonymity by comparing the host's real IPs against the content returned by judge servers.
When validating anonymity, the system performs set-membership checks using canonicalized IP strings. This prevents false negatives caused by different textual representations (e.g., uppercase vs. compressed zeros) of the same IPv6 address. If the judge response contains any of the host's discovered external IPs (IPv4 or IPv6), the proxy is classified as "Transparent". Sources: proxybroker/checker.py:110-145, CHANGELOG.md:40-42
Anonymity Levels
| Level | Condition |
|---|---|
| Transparent | The real host IP is visible in the response body. |
| Anonymous | The real IP is hidden, but proxy headers (e.g., Via) are present. |
| High | The real IP is hidden and no proxy-related headers are detected. |
| Sources: README.md:144-147, proxybroker/checker.py:120-140 |
Summary
ProxyBroker2 implements a modern DNS and IP handling strategy that treats IPv6 as a first-class citizen. By utilizing parallel "Happy Eyeballs" resolution, strict RFC 5952 canonicalization, and bracketed URI authority formatting, the system ensures reliable proxy discovery and validation across diverse network environments. This architecture effectively mitigates common IPv6-related failures such as address encoding mismatches and protocol blackholing.