Skip to content

fix(tls): send SNI for DNS host names - #38

Closed
Antruly wants to merge 1 commit into
masterfrom
fix/tls-sni
Closed

Antruly wants to merge 1 commit into
masterfrom
fix/tls-sni

Conversation

@Antruly

@Antruly Antruly commented Oct 19, 2026

Copy link
Copy Markdown
Owner

问题

现代 HTTPS 虚拟主机依赖 TLS SNI。v1.8.0 的 uvcpp_ssl 没有暴露/调用 SSL_set_tlsext_host_name(),两条客户端路径都不发送 server_name:

  • 异步 memory-BIO 路径:src/net/uvcpp_tcp_client.cpp 的 apply_tls_hostname();
  • 同步阻塞路径:src/web/uvcpp_http_client.cpp 的 do_ssl_handshake()。

同步路径自己 new uvcpp_ssl(ctx, fd),不经过 uvcpp_tcp_client::connect(),所以两条路必须各接一次。

实际表现是握手失败,或者拿到该 IP 的默认证书后主机名校验失败。

修改

  • 新增 uvcpp_ssl::set_server_name(const char*, size_t),内部调用 SSL_set_tlsext_host_name()。
  • 异步与同步路径都在握手前调用。
  • 按 RFC 6066 §3,IP 字面量不发送 SNI(用 uv_ip4_addr / uv_ip6_addr 判定);证书主机名校验保持原样。

复现与验证(Linux x64)

本地 TLS 服务端用 SSLContext.sni_callback 记录 server_name:

客户端路径 目标 服务端观察到的 SNI
异步 connect() localhost localhost
异步 connect() 127.0.0.1 None
同步 connect_wait() localhost localhost
同步 connect_wait() 127.0.0.1 None

两条路径在开启 SNI 后都完成握手并拿到正常响应。

兼容性

  • 新增公开 API,纯增量。
  • 对 IP 目标的行为变化是“不再发送 RFC 6066 禁止的 SNI”,证书校验不受影响。
  • Linux x64 已验证;Windows/macOS 需要 CI 矩阵确认。

Modern virtual hosts need the server_name extension; without it OpenSSL
completes against the default certificate (or the server aborts). Set it in
both the async memory-BIO path and the blocking *_wait path, and skip it for
IP literals as RFC 6066 requires.
Antruly added a commit to Antruly/uvscope that referenced this pull request Oct 19, 2026
Apply patches/upstream/*.patch in name order and fail closed when a patch
neither applies nor is already present. Record the reproduction, root cause
and verification for each fix in docs/LIBUVCPP_UPSTREAM.zh-CN.md.

Submitted upstream as Antruly/libuvcpp#38, #39 and #40.
Antruly added a commit that referenced this pull request Oct 19, 2026
uvcpp_ssl 没有暴露 SSL_set_tlsext_host_name,异步 memory-BIO 与同步阻塞两条
客户端路径都不发 server_name:现代虚拟主机会在握手阶段失败,或者返回该 IP 的
默认证书、随后在主机名校验上失败(uvp#274 / upstream #38)。

- uvcpp_ssl::set_server_name():纯增量 API,调用 SSL_set_tlsext_host_name();
- apply_tls_hostname() 与 do_ssl_handshake() 都在握手前调用它;
- 按 RFC 6066 §3,IP 字面量不发 SNI(判据复用 uv_ip4_addr / uv_ip6_addr 快路径)。
@Antruly

Antruly commented Oct 20, 2026

Copy link
Copy Markdown
Owner Author

Content merged via #40. Closing to avoid duplicate merges.

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.

1 participant