make outgoing SSL_connect() non-blocking
[freeradius.git] / src / main / tls_listen.c
index 2644a4e..785b243 100644 (file)
@@ -479,6 +479,34 @@ int dual_tls_send(rad_listen_t *listener, REQUEST *request)
        return 0;
 }
 
+static int try_connect(tls_session_t *ssn)
+{
+       int ret;
+       ret = SSL_connect(ssn->ssl);
+       if (ret < 0) {
+               switch (SSL_get_error(ssn->ssl, ret)) {
+                       default:
+                               break;
+
+
+
+               case SSL_ERROR_WANT_READ:
+               case SSL_ERROR_WANT_WRITE:
+                       ssn->connected = false;
+                       return 0;
+               }
+       }
+
+       if (ret <= 0) {
+               tls_error_io_log(NULL, ssn, ret, "Failed in " STRINGIFY(__FUNCTION__) " (SSL_connect)");
+               talloc_free(ssn);
+
+               return -1;
+       }
+
+       return 1;
+}
+
 
 #ifdef WITH_PROXY
 /*
@@ -500,6 +528,18 @@ static ssize_t proxy_tls_read(rad_listen_t *listener)
        uint8_t *data;
        listen_socket_t *sock = listener->data;
 
+       if (!sock->ssn->connected) {
+               rcode = try_connect(sock->ssn);
+               if (rcode == 0) return 0;
+
+               if (rcode < 0) {
+                       SSL_shutdown(sock->ssn->ssl);
+                       return -1;
+               }
+
+               sock->ssn->connected = true;
+       }
+
        /*
         *      Get the maximum size of data to receive.
         */
@@ -693,6 +733,20 @@ int proxy_tls_send(rad_listen_t *listener, REQUEST *request)
                                                request);
        }
 
+       if (!sock->ssn->connected) {
+               PTHREAD_MUTEX_LOCK(&sock->mutex);
+               rcode = try_connect(sock->ssn);
+               PTHREAD_MUTEX_LOCK(&sock->mutex);
+               if (rcode == 0) return 0;
+
+               if (rcode < 0) {
+                       SSL_shutdown(sock->ssn->ssl);
+                       return -1;
+               }
+
+               sock->ssn->connected = true;
+       }
+
        DEBUG3("Proxy is writing %u bytes to SSL",
               (unsigned int) request->proxy->data_len);
        PTHREAD_MUTEX_LOCK(&sock->mutex);