diff --git a/src/unlocker/proxy.cpp b/src/unlocker/proxy.cpp index 61d1f3c..1e5aa40 100644 --- a/src/unlocker/proxy.cpp +++ b/src/unlocker/proxy.cpp @@ -267,14 +267,36 @@ void Proxy::handleClient(SOCKET clientSocket) SSL_CTX* hostCtx = _certManager.createHostContext(host); if (!hostCtx) return; + auto sslHandshake = [](SSL* ssl, bool isAccept, SOCKET s) -> bool { + while (true) + { + int ret = isAccept ? SSL_accept(ssl) : SSL_connect(ssl); + if (ret > 0) return true; + int err = SSL_get_error(ssl, ret); + if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) + { + fd_set fds; + FD_ZERO(&fds); + FD_SET(s, &fds); + struct timeval tv = {1, 0}; + if (err == SSL_ERROR_WANT_READ) + select(0, &fds, NULL, NULL, &tv); + else + select(0, NULL, &fds, NULL, &tv); + continue; + } + return false; + } + }; + SSL_ptr clientSSL(SSL_new(hostCtx)); SSL_set_fd(clientSSL.get(), (int)clientGuard); - if (SSL_accept(clientSSL.get()) <= 0) return; + if (!sslHandshake(clientSSL.get(), true, clientGuard)) return; SSL_ptr remoteSSL(SSL_new(_clientCtx)); SSL_set_fd(remoteSSL.get(), (int)remoteGuard); SSL_set_tlsext_host_name(remoteSSL.get(), host.c_str()); - if (SSL_connect(remoteSSL.get()) <= 0) return; + if (!sslHandshake(remoteSSL.get(), false, remoteGuard)) return; /* traffic handler