Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4e3cfa4

Browse files
committed
Issue #23853: Cleanup _ssl.c
* Rename check_socket_and_wait_for_timeout() to PySSL_select() * PySSL_select() is now clearly splitted betwen poll() and select() * Add empty lines for readability
1 parent 10550cd commit 4e3cfa4

1 file changed

Lines changed: 50 additions & 45 deletions

File tree

Modules/_ssl.c

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,7 @@ static PyTypeObject PySSLMemoryBIO_Type;
223223

224224
static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args);
225225
static 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);
228227
static PyObject *PySSL_peercert(PySSLSocket *self, PyObject *args);
229228
static 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

16111613
static 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

Comments
 (0)