Skip to content

fix(net): resolve hostnames with AF_UNSPEC — IPv6-only hosts fail today #44

Closed

Description

@Antruly

背景

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(),同样受影响。

建议

  1. 异步和同步两条路径都改为 AF_UNSPEC,按 getaddrinfo 返回顺序逐个尝试。异步路径每次尝试需要新建 uv_tcp_t —— 同一个 handle 在 connect 失败后重连的行为跨 libuv 版本不一致,不能假设可复用。
  2. 可选第二步再做 250 ms 的 Happy Eyeballs(RFC 8305);没有第 1 步的逐个尝试,不建议直接开 AF_UNSPEC。
  3. SNI / 证书校验仍使用目标域名,不随地址族变化。
  4. SOCKS5 服务端的域名 CONNECT 会自然受益,不需要单独改。

验收

  • 本地 AAAA-only 服务端可以通过域名连接;
  • 双栈环境下 IPv4-only 目标仍可连接;
  • 失败时返回最后一次尝试的真实错误,而不是笼统的 EAI_NONAME;
  • 现有 TCP / HTTP / SOCKS5 用例保持全绿。

建议进入 1.8.2。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions