为什么 libcurl 不为 IP 设置 SNI?

Why doesn't libcurl set SNI for IPs?

我刚刚注意到当我使用 IP 进行 HTTPS 调用时,libcurl 没有设置 SNI 字段。我发现了这个:

https://github.com/curl/curl/blame/master/lib/vtls/openssl.c

#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
  if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
#ifdef ENABLE_IPV6
     (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
#endif
     sni &&
     !SSL_set_tlsext_host_name(BACKEND->handle, hostname))
    infof(data, "WARNING: failed to configure server name indication (SNI) "
          "TLS extension\n");
#endif

根据 Curl_inet_pton 文档:

 * inet_pton(af, src, dst)
 *      convert from presentation format (which usually means ASCII printable)
 *      to network format (which is usually some kind of binary format).
 * return:
 *      1 if the address was valid for the specified address family
 *      0 if the address wasn't valid (`dst' is untouched in this case)
 *      -1 if some other error occurred (`dst' is untouched in this case, too)

正如预期的那样,它 returns 1 用于 IP 地址(例如 192.160.0.1),因此不会调用 SSL_set_tlsext_host_name.

为什么?

因为不允许。

RFC 3546“传输层安全性 (TLS) 扩展”section 3.1 说得很清楚:

Literal IPv4 and IPv6 addresses are not permitted in "HostName".