From d014bb114956c849438a69e20b1af60554682776 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Tue, 30 Dec 2025 17:57:23 +0300 Subject: [PATCH] Use SSL_connect / SSL_accept in non-blocking mode --- src/plugins/SSLPlugin/my_ssl.c | 81 ++++++++++++++++++---------------- src/plugins/SSLPlugin/my_ssl.h | 2 +- 2 files changed, 45 insertions(+), 38 deletions(-) diff --git a/src/plugins/SSLPlugin/my_ssl.c b/src/plugins/SSLPlugin/my_ssl.c index 546b97c..443d5b6 100644 --- a/src/plugins/SSLPlugin/my_ssl.c +++ b/src/plugins/SSLPlugin/my_ssl.c @@ -196,14 +196,6 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config, *errSSL = NULL; -/*FIXME: support SSL_ERROR_WANT_(READ|WRITE) */ -#ifdef _WIN32 - ul = 0; - ioctlsocket(s, FIONBIO, &ul); -#else - fcntl(s,F_SETFL,0); -#endif - conn = (ssl_conn *)malloc(sizeof(ssl_conn)); if ( conn == NULL ){ return NULL; @@ -227,8 +219,28 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config, return NULL; } if(hostname && *hostname)SSL_set_tlsext_host_name(conn->ssl, hostname); - err = SSL_connect(conn->ssl); - if ( err == -1 ) { + + + do { + struct pollfd fds[1] = {{}}; + int sslerr; + + err = SSL_connect(conn->ssl); + if (err != -1) break; + sslerr = SSL_get_error(conn->ssl, err); + if(sslerr == SSL_ERROR_WANT_READ){ + fds[0].fd = s; + fds[0].events = POLLIN; + } + else if(sslerr == SSL_ERROR_WANT_WRITE){ + fds[0].fd = s; + fds[0].events = POLLOUT; + } + else break; + if(sso._poll(sso.state, fds, 1, CONNECT_TO*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break; + } while (err == -1); + + if ( err != 1 ) { *errSSL = getSSLErr(); ssl_conn_free(conn); return NULL; @@ -245,12 +257,6 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config, *server_cert = cert; } -#ifdef _WIN32 - ul = 1; - ioctlsocket(s, FIONBIO, &ul); -#else - fcntl(s,F_SETFL,O_NONBLOCK); -#endif return conn; } @@ -261,15 +267,6 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert ssl_conn *conn; unsigned long ul; -/*FIXME: support SSL_ERROR_WANT_(READ|WRITE)*/ - -#ifdef _WIN32 - ul = 0; - ioctlsocket(s, FIONBIO, &ul); -#else - fcntl(s,F_SETFL,0); -#endif - *errSSL = NULL; @@ -296,28 +293,38 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert } SSL_set_fd(conn->ssl, s); - err = SSL_accept(conn->ssl); - if ( err <= 0 ) { + + do { + struct pollfd fds[1] = {{}}; + int sslerr; + + err = SSL_accept(conn->ssl); + if (err != -1) break; + sslerr = SSL_get_error(conn->ssl, err); + if(sslerr == SSL_ERROR_WANT_READ){ + fds[0].fd = s; + fds[0].events = POLLIN; + } + else if(sslerr == SSL_ERROR_WANT_WRITE){ + fds[0].fd = s; + fds[0].events = POLLOUT; + } + else break; + if(sso._poll(sso.state, fds, 1, CONNECT_TO*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break; + } while (err == -1); + + + if ( err != 1 ) { *errSSL = getSSLErr(); ssl_conn_free(conn); return NULL; } - // - // client certificate - // TODO: is it required? - // cert = SSL_get_peer_certificate(conn->ssl); if ( cert != NULL ) X509_free(cert); -#ifdef _WIN32 - ul = 1; - ioctlsocket(s, FIONBIO, &ul); -#else - fcntl(s,F_SETFL,O_NONBLOCK); -#endif return conn; } diff --git a/src/plugins/SSLPlugin/my_ssl.h b/src/plugins/SSLPlugin/my_ssl.h index b5da183..73d2cfe 100644 --- a/src/plugins/SSLPlugin/my_ssl.h +++ b/src/plugins/SSLPlugin/my_ssl.h @@ -77,5 +77,5 @@ void _ssl_cert_free(SSL_CERT cert); void ssl_init(void); char * getSSLErr(void); - +extern struct sockfuncs sso; #endif // __my_ssl_h__ \ No newline at end of file