From 676e0c28e7f6c3565d500ed17c0605359595016e Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Thu, 5 Nov 2009 15:41:31 +0000
Subject: [PATCH] - Dropped misleading timeouts in libcurl-NSS and made sure
 the SSL socket works   in non-blocking mode.

---
 CHANGES   |  4 ++++
 lib/nss.c | 47 +++++++++++++----------------------------------
 2 files changed, 17 insertions(+), 34 deletions(-)

diff --git a/CHANGES b/CHANGES
index e3afa99d85..2d7b7ba62f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@
 
                                   Changelog
 
+Kamil Dudka (5 Nov 2009)
+- Dropped misleading timeouts in libcurl-NSS and made sure the SSL socket works
+  in non-blocking mode.
+
 Yang Tse (5 Nov 2009)
 - I removed leading 'curl' path on the 'curlbuild.h' include statement in
   curl.h, adjusting auto-makefiles include path, to enhance portability to
diff --git a/lib/nss.c b/lib/nss.c
index 7408585da7..10d07def82 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -83,8 +83,6 @@ PRLock * nss_initlock = NULL;
 
 volatile int initialized = 0;
 
-#define HANDSHAKE_TIMEOUT 30
-
 typedef struct {
   const char *name;
   int num;
@@ -970,6 +968,8 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
   char *certDir = NULL;
   int curlerr;
   const int *cipher_to_enable;
+  PRSocketOptionData sock_opt;
+  PRUint32 timeout;
 
   curlerr = CURLE_SSL_CONNECT_ERROR;
 
@@ -1063,6 +1063,12 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
     goto error;
   model = SSL_ImportFD(NULL, model);
 
+  /* make the socket nonblocking */
+  sock_opt.option = PR_SockOpt_Nonblocking;
+  sock_opt.value.non_blocking = PR_TRUE;
+  if(PR_SetSocketOption(model, &sock_opt) != SECSuccess)
+    goto error;
+
   if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess)
     goto error;
   if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess)
@@ -1234,9 +1240,8 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
   SSL_SetURL(connssl->handle, conn->host.name);
 
   /* Force the handshake now */
-  if(SSL_ForceHandshakeWithTimeout(connssl->handle,
-                                    PR_SecondsToInterval(HANDSHAKE_TIMEOUT))
-      != SECSuccess) {
+  timeout = PR_MillisecondsToInterval(Curl_timeleft(conn, NULL, TRUE));
+  if(SSL_ForceHandshakeWithTimeout(connssl->handle, timeout) != SECSuccess) {
     if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
       curlerr = CURLE_PEER_FAILED_VERIFICATION;
     else if(conn->data->set.ssl.certverifyresult!=0)
@@ -1288,27 +1293,12 @@ int Curl_nss_send(struct connectdata *conn,  /* connection data */
                   const void *mem,           /* send this data */
                   size_t len)                /* amount to write */
 {
-  PRInt32 err;
-  struct SessionHandle *data = conn->data;
-  PRInt32 timeout;
   int rc;
 
-  if(data->set.timeout)
-    timeout = PR_MillisecondsToInterval((PRUint32)data->set.timeout);
-  else
-    timeout = PR_MillisecondsToInterval(DEFAULT_CONNECT_TIMEOUT);
-
-  rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0, timeout);
+  rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0, -1);
 
   if(rc < 0) {
-    err = PR_GetError();
-
-    if(err == PR_IO_TIMEOUT_ERROR) {
-      failf(data, "SSL connection timeout");
-      return CURLE_OPERATION_TIMEDOUT;
-    }
-
-    failf(conn->data, "SSL write: error %d", err);
+    failf(conn->data, "SSL write: error %d", PR_GetError());
     return -1;
   }
   return rc; /* number of bytes */
@@ -1326,15 +1316,8 @@ ssize_t Curl_nss_recv(struct connectdata * conn, /* connection data */
                       bool * wouldblock)
 {
   ssize_t nread;
-  struct SessionHandle *data = conn->data;
-  PRInt32 timeout;
 
-  if(data->set.timeout)
-    timeout = PR_SecondsToInterval((PRUint32)data->set.timeout);
-  else
-    timeout = PR_MillisecondsToInterval(DEFAULT_CONNECT_TIMEOUT);
-
-  nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, timeout);
+  nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, -1);
   *wouldblock = FALSE;
   if(nread < 0) {
     /* failed SSL read */
@@ -1344,10 +1327,6 @@ ssize_t Curl_nss_recv(struct connectdata * conn, /* connection data */
       *wouldblock = TRUE;
       return -1; /* basically EWOULDBLOCK */
     }
-    if(err == PR_IO_TIMEOUT_ERROR) {
-      failf(data, "SSL connection timeout");
-      return CURLE_OPERATION_TIMEDOUT;
-    }
     failf(conn->data, "SSL read: errno %d", err);
     return -1;
   }
-- 
GitLab