@@ -45,6 +45,11 @@ static PySocketModule_APIObject PySocketModule;
4545#include <sys/poll.h>
4646#endif
4747
48+ #ifndef MS_WINDOWS
49+ /* inet_pton */
50+ #include <arpa/inet.h>
51+ #endif
52+
4853/* Don't warn about deprecated functions */
4954#ifdef __GNUC__
5055#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@@ -755,8 +760,41 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
755760 SSL_set_mode (self -> ssl , mode );
756761
757762#if HAVE_SNI
758- if (server_hostname != NULL )
759- SSL_set_tlsext_host_name (self -> ssl , server_hostname );
763+ if (server_hostname != NULL ) {
764+ /* Don't send SNI for IP addresses. We cannot simply use inet_aton() and
765+ * inet_pton() here. inet_aton() may be linked weakly and inet_pton() isn't
766+ * available on all platforms. Use OpenSSL's IP address parser. It's
767+ * available since 1.0.2 and LibreSSL since at least 2.3.0. */
768+ int send_sni = 1 ;
769+ #if OPENSSL_VERSION_NUMBER >= 0x10200000L
770+ ASN1_OCTET_STRING * ip = a2i_IPADDRESS (server_hostname );
771+ if (ip == NULL ) {
772+ send_sni = 1 ;
773+ ERR_clear_error ();
774+ } else {
775+ send_sni = 0 ;
776+ ASN1_OCTET_STRING_free (ip );
777+ }
778+ #elif defined(HAVE_INET_PTON )
779+ #ifdef ENABLE_IPV6
780+ char packed [Py_MAX (sizeof (struct in_addr ), sizeof (struct in6_addr ))];
781+ #else
782+ char packed [sizeof (struct in_addr )];
783+ #endif /* ENABLE_IPV6 */
784+ if (inet_pton (AF_INET , server_hostname , packed )) {
785+ send_sni = 0 ;
786+ #ifdef ENABLE_IPV6
787+ } else if (inet_pton (AF_INET6 , server_hostname , packed )) {
788+ send_sni = 0 ;
789+ #endif /* ENABLE_IPV6 */
790+ } else {
791+ send_sni = 1 ;
792+ }
793+ #endif /* HAVE_INET_PTON */
794+ if (send_sni ) {
795+ SSL_set_tlsext_host_name (self -> ssl , server_hostname );
796+ }
797+ }
760798#endif
761799 /* If the socket is in non-blocking mode or timeout mode, set the BIO
762800 * to non-blocking mode (blocking is the default)
0 commit comments