@@ -55,6 +55,11 @@ static PySocketModule_APIObject PySocketModule;
5555#include <sys/poll.h>
5656#endif
5757
58+ #ifndef MS_WINDOWS
59+ /* inet_pton */
60+ #include <arpa/inet.h>
61+ #endif
62+
5863/* Don't warn about deprecated functions */
5964#ifdef __GNUC__
6065#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@@ -667,8 +672,41 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
667672 SSL_set_mode (self -> ssl , mode );
668673
669674#if HAVE_SNI
670- if (server_hostname != NULL )
671- SSL_set_tlsext_host_name (self -> ssl , server_hostname );
675+ if (server_hostname != NULL ) {
676+ /* Don't send SNI for IP addresses. We cannot simply use inet_aton() and
677+ * inet_pton() here. inet_aton() may be linked weakly and inet_pton() isn't
678+ * available on all platforms. Use OpenSSL's IP address parser. It's
679+ * available since 1.0.2 and LibreSSL since at least 2.3.0. */
680+ int send_sni = 1 ;
681+ #if OPENSSL_VERSION_NUMBER >= 0x10200000L
682+ ASN1_OCTET_STRING * ip = a2i_IPADDRESS (server_hostname );
683+ if (ip == NULL ) {
684+ send_sni = 1 ;
685+ ERR_clear_error ();
686+ } else {
687+ send_sni = 0 ;
688+ ASN1_OCTET_STRING_free (ip );
689+ }
690+ #elif defined(HAVE_INET_PTON )
691+ #ifdef ENABLE_IPV6
692+ char packed [Py_MAX (sizeof (struct in_addr ), sizeof (struct in6_addr ))];
693+ #else
694+ char packed [sizeof (struct in_addr )];
695+ #endif /* ENABLE_IPV6 */
696+ if (inet_pton (AF_INET , server_hostname , packed )) {
697+ send_sni = 0 ;
698+ #ifdef ENABLE_IPV6
699+ } else if (inet_pton (AF_INET6 , server_hostname , packed )) {
700+ send_sni = 0 ;
701+ #endif /* ENABLE_IPV6 */
702+ } else {
703+ send_sni = 1 ;
704+ }
705+ #endif /* HAVE_INET_PTON */
706+ if (send_sni ) {
707+ SSL_set_tlsext_host_name (self -> ssl , server_hostname );
708+ }
709+ }
672710#endif
673711
674712 /* If the socket is in non-blocking mode or timeout mode, set the BIO
0 commit comments