@@ -223,8 +223,7 @@ static PyTypeObject PySSLMemoryBIO_Type;
223223
224224static PyObject * PySSL_SSLwrite (PySSLSocket * self , PyObject * args );
225225static PyObject * PySSL_SSLread (PySSLSocket * self , PyObject * args );
226- static int check_socket_and_wait_for_timeout (PySocketSockObject * s ,
227- int writing );
226+ static int PySSL_select (PySocketSockObject * s , int writing );
228227static PyObject * PySSL_peercert (PySSLSocket * self , PyObject * args );
229228static PyObject * PySSL_cipher (PySSLSocket * self );
230229
@@ -588,15 +587,18 @@ static PyObject *PySSL_SSLdo_handshake(PySSLSocket *self)
588587 ret = SSL_do_handshake (self -> ssl );
589588 err = SSL_get_error (self -> ssl , ret );
590589 PySSL_END_ALLOW_THREADS
590+
591591 if (PyErr_CheckSignals ())
592592 goto error ;
593+
593594 if (err == SSL_ERROR_WANT_READ ) {
594- sockstate = check_socket_and_wait_for_timeout (sock , 0 );
595+ sockstate = PySSL_select (sock , 0 );
595596 } else if (err == SSL_ERROR_WANT_WRITE ) {
596- sockstate = check_socket_and_wait_for_timeout (sock , 1 );
597+ sockstate = PySSL_select (sock , 1 );
597598 } else {
598599 sockstate = SOCKET_OPERATION_OK ;
599600 }
601+
600602 if (sockstate == SOCKET_HAS_TIMED_OUT ) {
601603 PyErr_SetString (PySocketModule .timeout_error ,
602604 ERRSTR ("The handshake operation timed out" ));
@@ -1609,11 +1611,17 @@ static void PySSL_dealloc(PySSLSocket *self)
16091611 */
16101612
16111613static int
1612- check_socket_and_wait_for_timeout (PySocketSockObject * s , int writing )
1614+ PySSL_select (PySocketSockObject * s , int writing )
16131615{
1616+ int rc ;
1617+ #ifdef HAVE_POLL
1618+ struct pollfd pollfd ;
1619+ _PyTime_t ms ;
1620+ #else
1621+ int nfds ;
16141622 fd_set fds ;
16151623 struct timeval tv ;
1616- int rc ;
1624+ #endif
16171625
16181626 /* Nothing to do unless we're in timeout mode (not non-blocking) */
16191627 if ((s == NULL ) || (s -> sock_timeout == 0 ))
@@ -1628,25 +1636,17 @@ check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing)
16281636 /* Prefer poll, if available, since you can poll() any fd
16291637 * which can't be done with select(). */
16301638#ifdef HAVE_POLL
1631- {
1632- struct pollfd pollfd ;
1633- int timeout ;
1634-
1635- pollfd .fd = s -> sock_fd ;
1636- pollfd .events = writing ? POLLOUT : POLLIN ;
1639+ pollfd .fd = s -> sock_fd ;
1640+ pollfd .events = writing ? POLLOUT : POLLIN ;
16371641
1638- /* s->sock_timeout is in seconds, timeout in ms */
1639- timeout = (int )_PyTime_AsMilliseconds (s -> sock_timeout ,
1640- _PyTime_ROUND_CEILING );
1641-
1642- PySSL_BEGIN_ALLOW_THREADS
1643- rc = poll (& pollfd , 1 , timeout );
1644- PySSL_END_ALLOW_THREADS
1645-
1646- goto normal_return ;
1647- }
1648- #endif
1642+ /* s->sock_timeout is in seconds, timeout in ms */
1643+ ms = (int )_PyTime_AsMilliseconds (s -> sock_timeout , _PyTime_ROUND_CEILING );
1644+ assert (ms <= INT_MAX );
16491645
1646+ PySSL_BEGIN_ALLOW_THREADS
1647+ rc = poll (& pollfd , 1 , (int )ms );
1648+ PySSL_END_ALLOW_THREADS
1649+ #else
16501650 /* Guard against socket too large for select*/
16511651 if (!_PyIsSelectable_fd (s -> sock_fd ))
16521652 return SOCKET_TOO_LARGE_FOR_SELECT ;
@@ -1656,19 +1656,16 @@ check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing)
16561656 FD_ZERO (& fds );
16571657 FD_SET (s -> sock_fd , & fds );
16581658
1659- /* See if the socket is ready */
1659+ /* Wait until the socket becomes ready */
16601660 PySSL_BEGIN_ALLOW_THREADS
1661+ nfds = Py_SAFE_DOWNCAST (s -> sock_fd + 1 , SOCKET_T , int );
16611662 if (writing )
1662- rc = select (Py_SAFE_DOWNCAST (s -> sock_fd + 1 , SOCKET_T , int ),
1663- NULL , & fds , NULL , & tv );
1663+ rc = select (nfds , NULL , & fds , NULL , & tv );
16641664 else
1665- rc = select (Py_SAFE_DOWNCAST (s -> sock_fd + 1 , SOCKET_T , int ),
1666- & fds , NULL , NULL , & tv );
1665+ rc = select (nfds , & fds , NULL , NULL , & tv );
16671666 PySSL_END_ALLOW_THREADS
1668-
1669- #ifdef HAVE_POLL
1670- normal_return :
16711667#endif
1668+
16721669 /* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise
16731670 (when we are able to write or when there's something to read) */
16741671 return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK ;
@@ -1710,7 +1707,7 @@ static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args)
17101707 BIO_set_nbio (SSL_get_wbio (self -> ssl ), nonblocking );
17111708 }
17121709
1713- sockstate = check_socket_and_wait_for_timeout (sock , 1 );
1710+ sockstate = PySSL_select (sock , 1 );
17141711 if (sockstate == SOCKET_HAS_TIMED_OUT ) {
17151712 PyErr_SetString (PySocketModule .timeout_error ,
17161713 "The write operation timed out" );
@@ -1724,21 +1721,24 @@ static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args)
17241721 "Underlying socket too large for select()." );
17251722 goto error ;
17261723 }
1724+
17271725 do {
17281726 PySSL_BEGIN_ALLOW_THREADS
17291727 len = SSL_write (self -> ssl , buf .buf , (int )buf .len );
17301728 err = SSL_get_error (self -> ssl , len );
17311729 PySSL_END_ALLOW_THREADS
1732- if (PyErr_CheckSignals ()) {
1730+
1731+ if (PyErr_CheckSignals ())
17331732 goto error ;
1734- }
1733+
17351734 if (err == SSL_ERROR_WANT_READ ) {
1736- sockstate = check_socket_and_wait_for_timeout (sock , 0 );
1735+ sockstate = PySSL_select (sock , 0 );
17371736 } else if (err == SSL_ERROR_WANT_WRITE ) {
1738- sockstate = check_socket_and_wait_for_timeout (sock , 1 );
1737+ sockstate = PySSL_select (sock , 1 );
17391738 } else {
17401739 sockstate = SOCKET_OPERATION_OK ;
17411740 }
1741+
17421742 if (sockstate == SOCKET_HAS_TIMED_OUT ) {
17431743 PyErr_SetString (PySocketModule .timeout_error ,
17441744 "The write operation timed out" );
@@ -1847,21 +1847,23 @@ static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args)
18471847 count = SSL_read (self -> ssl , mem , len );
18481848 err = SSL_get_error (self -> ssl , count );
18491849 PySSL_END_ALLOW_THREADS
1850+
18501851 if (PyErr_CheckSignals ())
18511852 goto error ;
1853+
18521854 if (err == SSL_ERROR_WANT_READ ) {
1853- sockstate = check_socket_and_wait_for_timeout (sock , 0 );
1855+ sockstate = PySSL_select (sock , 0 );
18541856 } else if (err == SSL_ERROR_WANT_WRITE ) {
1855- sockstate = check_socket_and_wait_for_timeout (sock , 1 );
1856- } else if ((err == SSL_ERROR_ZERO_RETURN ) &&
1857- (SSL_get_shutdown (self -> ssl ) ==
1858- SSL_RECEIVED_SHUTDOWN ))
1857+ sockstate = PySSL_select (sock , 1 );
1858+ } else if (err == SSL_ERROR_ZERO_RETURN &&
1859+ SSL_get_shutdown (self -> ssl ) == SSL_RECEIVED_SHUTDOWN )
18591860 {
18601861 count = 0 ;
18611862 goto done ;
1862- } else {
1863- sockstate = SOCKET_OPERATION_OK ;
18641863 }
1864+ else
1865+ sockstate = SOCKET_OPERATION_OK ;
1866+
18651867 if (sockstate == SOCKET_HAS_TIMED_OUT ) {
18661868 PyErr_SetString (PySocketModule .timeout_error ,
18671869 "The read operation timed out" );
@@ -1870,6 +1872,7 @@ static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args)
18701872 break ;
18711873 }
18721874 } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE );
1875+
18731876 if (count <= 0 ) {
18741877 PySSL_SetError (self , count , __FILE__ , __LINE__ );
18751878 goto error ;
@@ -1935,6 +1938,7 @@ static PyObject *PySSL_SSLshutdown(PySSLSocket *self)
19351938 SSL_set_read_ahead (self - > ssl , 0 );
19361939 err = SSL_shutdown (self -> ssl );
19371940 PySSL_END_ALLOW_THREADS
1941+
19381942 /* If err == 1, a secure shutdown with SSL_shutdown() is complete */
19391943 if (err > 0 )
19401944 break ;
@@ -1952,11 +1956,12 @@ static PyObject *PySSL_SSLshutdown(PySSLSocket *self)
19521956 /* Possibly retry shutdown until timeout or failure */
19531957 ssl_err = SSL_get_error (self -> ssl , err );
19541958 if (ssl_err == SSL_ERROR_WANT_READ )
1955- sockstate = check_socket_and_wait_for_timeout (sock , 0 );
1959+ sockstate = PySSL_select (sock , 0 );
19561960 else if (ssl_err == SSL_ERROR_WANT_WRITE )
1957- sockstate = check_socket_and_wait_for_timeout (sock , 1 );
1961+ sockstate = PySSL_select (sock , 1 );
19581962 else
19591963 break ;
1964+
19601965 if (sockstate == SOCKET_HAS_TIMED_OUT ) {
19611966 if (ssl_err == SSL_ERROR_WANT_READ )
19621967 PyErr_SetString (PySocketModule .timeout_error ,
0 commit comments