fix(net): resolve hostnames with AF_UNSPEC — IPv6-only hosts fail today #44
Copy link
Copy link
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
背景
uvscope 的 HTTP / TCP / WebSocket / SOCKS5 出站都建立在 uvcpp_tcp_client 上。当前域名的两条解析路径都把地址族写死成 AF_INET:
- 异步:
src/net/uvcpp_tcp_client.cpp的connect_transport()(约 870 行,hints.ai_family = AF_INET) - 同步:
src/net/uvcpp_tcp_client.cpp的resolve_host_sync()(约 1641 行,同样AF_INET)
数字 IPv4 / IPv6 字面量有快速路径,但域名永远只拿 A 记录。直接后果:
- IPv6-only 主机无法通过域名连接;
- 双栈主机只会走 A,没有回退或竞速;
- SOCKS5 服务端 CONNECT 的域名目标(
src/net/uvcpp_socks5_server.cpp的begin_connect(),约 607 行)复用同一条connect(),同样受影响。
建议
- 异步和同步两条路径都改为
AF_UNSPEC,按getaddrinfo返回顺序逐个尝试。异步路径每次尝试需要新建uv_tcp_t—— 同一个 handle 在 connect 失败后重连的行为跨 libuv 版本不一致,不能假设可复用。 - 可选第二步再做 250 ms 的 Happy Eyeballs(RFC 8305);没有第 1 步的逐个尝试,不建议直接开
AF_UNSPEC。 - SNI / 证书校验仍使用目标域名,不随地址族变化。
- SOCKS5 服务端的域名 CONNECT 会自然受益,不需要单独改。
验收
- 本地 AAAA-only 服务端可以通过域名连接;
- 双栈环境下 IPv4-only 目标仍可连接;
- 失败时返回最后一次尝试的真实错误,而不是笼统的
EAI_NONAME; - 现有 TCP / HTTP / SOCKS5 用例保持全绿。
建议进入 1.8.2。
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
fix(net): 代理已应答后的失败不再换地址重试(多地址连接)
fix(net): 握手层的失败不触发多地址重试(含 TLS)
version(1.8.2): 发布态 —— uvscope 批次(#44–#54、#50–#53)