@@ -55,6 +55,11 @@ static PySocketModule_APIObject PySocketModule;
55
55
#include <sys/poll.h>
56
56
#endif
57
57
58
+ #ifndef MS_WINDOWS
59
+ /* inet_pton */
60
+ #include <arpa/inet.h>
61
+ #endif
62
+
58
63
/* Don't warn about deprecated functions */
59
64
#ifdef __GNUC__
60
65
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@@ -667,8 +672,41 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
667
672
SSL_set_mode (self -> ssl , mode );
668
673
669
674
#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
+ }
672
710
#endif
673
711
674
712
/* If the socket is in non-blocking mode or timeout mode, set the BIO
0 commit comments