]> granicus.if.org Git - curl/commitdiff
refactorize interface of Curl_ssl_recv/Curl_ssl_send
authorKamil Dudka <kdudka@redhat.com>
Sun, 4 Apr 2010 21:37:18 +0000 (23:37 +0200)
committerKamil Dudka <kdudka@redhat.com>
Sun, 4 Apr 2010 21:37:18 +0000 (23:37 +0200)
CHANGES
lib/gtls.c
lib/gtls.h
lib/nss.c
lib/nssg.h
lib/sendf.c
lib/sslgen.c
lib/sslgen.h
lib/ssluse.c
lib/ssluse.h

diff --git a/CHANGES b/CHANGES
index 17a4d5991d7179d1a1b12bd5f309781d3c168f16..cd84cf358b94018fa1ad7a6dc1cf87255919d1a7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,8 @@
 Kamil Dudka (4 Apr 2010)
 - Eliminated a race condition in Curl_resolv_timeout().
 
+- Refactorized interface of Curl_ssl_recv()/Curl_ssl_send().
+
 Daniel Stenberg (1 Apr 2010)
 - Matt Wixson found and fixed a bug in the SCP/SFTP area where the code
   treated a 0 return code from libssh2 to be the same as EAGAIN while in
index 079c6b1b0bfb5ee8be15599dd127207377b5aeb9..b7fa3c9267354556a2a1ee1e50306b54bc8f9e3f 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -638,18 +638,21 @@ Curl_gtls_connect(struct connectdata *conn,
 }
 
 
-/* return number of sent (non-SSL) bytes */
+/* for documentation see Curl_ssl_send() in sslgen.h */
 ssize_t Curl_gtls_send(struct connectdata *conn,
                        int sockindex,
                        const void *mem,
-                       size_t len)
+                       size_t len,
+                       int *curlcode)
 {
   ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
 
   if(rc < 0 ) {
-    if(rc == GNUTLS_E_AGAIN)
-      return 0; /* EWOULDBLOCK equivalent */
-    rc = -1; /* generic error code for send failure */
+    *curlcode = (rc == GNUTLS_E_AGAIN)
+      ? /* EWOULDBLOCK */ -1
+      : CURLE_SEND_ERROR;
+
+    rc = -1;
   }
 
   return rc;
@@ -748,22 +751,18 @@ int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
   return retval;
 }
 
-/*
- * If the read would block we return -1 and set 'wouldblock' to TRUE.
- * Otherwise we return the amount of data read. Other errors should return -1
- * and set 'wouldblock' to FALSE.
- */
+/* for documentation see Curl_ssl_recv() in sslgen.h */
 ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
                        int num,                  /* socketindex */
                        char *buf,                /* store read data here */
                        size_t buffersize,        /* max amount to read */
-                       bool *wouldblock)
+                       int *curlcode)
 {
   ssize_t ret;
 
   ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
   if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
-    *wouldblock = TRUE;
+    *curlcode = -1;
     return -1;
   }
 
@@ -773,20 +772,22 @@ ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
     CURLcode rc = handshake(conn, conn->ssl[num].session, num, FALSE);
     if(rc)
       /* handshake() writes error message on its own */
-      return rc;
-    *wouldblock = TRUE; /* then return as if this was a wouldblock */
+      *curlcode = rc;
+    else
+      *curlcode = -1; /* then return as if this was a wouldblock */
     return -1;
   }
 
-  *wouldblock = FALSE;
   if(!ret) {
     failf(conn->data, "Peer closed the TLS connection");
+    *curlcode = CURLE_RECV_ERROR;
     return -1;
   }
 
   if(ret < 0) {
     failf(conn->data, "GnuTLS recv error (%d): %s",
           (int)ret, gnutls_strerror((int)ret));
+    *curlcode = CURLE_RECV_ERROR;
     return -1;
   }
 
index 0d3f3fa6e6770259263b539fb300a7d13c67bf7a..9fe618a329dfedbfb460b5fc59b5505a73c947f4 100644 (file)
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,14 +35,14 @@ void Curl_gtls_close_all(struct SessionHandle *data);
  /* close a SSL connection */
 void Curl_gtls_close(struct connectdata *conn, int sockindex);
 
-/* return number of sent (non-SSL) bytes */
+/* for documentation see Curl_ssl_send() in sslgen.h */
 ssize_t Curl_gtls_send(struct connectdata *conn, int sockindex,
-                       const void *mem, size_t len);
-ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
-                       int num,                  /* socketindex */
-                       char *buf,                /* store read data here */
-                       size_t buffersize,        /* max amount to read */
-                       bool *wouldblock);
+                       const void *mem, size_t len, int *curlcode);
+
+/* for documentation see Curl_ssl_recv() in sslgen.h */
+ssize_t Curl_gtls_recv(struct connectdata *conn, int num, char *buf,
+                       size_t buffersize, int *curlcode);
+
 void Curl_gtls_session_free(void *ptr);
 size_t Curl_gtls_version(char *buffer, size_t size);
 int Curl_gtls_shutdown(struct connectdata *conn, int sockindex);
index 2babfdf1d717415a92c9df91352ef5bc0ea69020..560154dd1d76d7e44c0624db67f95200dc678561 100644 (file)
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1340,47 +1340,50 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
   return curlerr;
 }
 
-/* return number of sent (non-SSL) bytes */
+/* for documentation see Curl_ssl_send() in sslgen.h */
 int Curl_nss_send(struct connectdata *conn,  /* connection data */
                   int sockindex,             /* socketindex */
                   const void *mem,           /* send this data */
-                  size_t len)                /* amount to write */
+                  size_t len,                /* amount to write */
+                  int *curlcode)
 {
   int rc;
 
   rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0, -1);
 
   if(rc < 0) {
-    failf(conn->data, "SSL write: error %d", PR_GetError());
+    PRInt32 err = PR_GetError();
+    if(err == PR_WOULD_BLOCK_ERROR)
+      *curlcode = -1; /* EWOULDBLOCK */
+    else {
+      failf(conn->data, "SSL write: error %d", err);
+      *curlcode = CURLE_SEND_ERROR;
+    }
     return -1;
   }
   return rc; /* number of bytes */
 }
 
-/*
- * If the read would block we return -1 and set 'wouldblock' to TRUE.
- * Otherwise we return the amount of data read. Other errors should return -1
- * and set 'wouldblock' to FALSE.
- */
+/* for documentation see Curl_ssl_recv() in sslgen.h */
 ssize_t Curl_nss_recv(struct connectdata * conn, /* connection data */
                       int num,                   /* socketindex */
                       char *buf,                 /* store read data here */
                       size_t buffersize,         /* max amount to read */
-                      bool * wouldblock)
+                      int *curlcode)
 {
   ssize_t nread;
 
   nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, -1);
-  *wouldblock = FALSE;
   if(nread < 0) {
     /* failed SSL read */
     PRInt32 err = PR_GetError();
 
-    if(err == PR_WOULD_BLOCK_ERROR) {
-      *wouldblock = TRUE;
-      return -1; /* basically EWOULDBLOCK */
+    if(err == PR_WOULD_BLOCK_ERROR)
+      *curlcode = -1; /* EWOULDBLOCK */
+    else {
+      failf(conn->data, "SSL read: errno %d", err);
+      *curlcode = CURLE_RECV_ERROR;
     }
-    failf(conn->data, "SSL read: errno %d", err);
     return -1;
   }
   return nread;
index 6486e62758d623821295b70e222f17115f20b683..309c3d6d8a8fc0b9740b4c23b7d3c9361943301d 100644 (file)
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -42,15 +42,19 @@ int Curl_nss_close_all(struct SessionHandle *data);
 int Curl_nss_init(void);
 void Curl_nss_cleanup(void);
 
+/* for documentation see Curl_ssl_send() in sslgen.h */
 int Curl_nss_send(struct connectdata *conn,
                   int sockindex,
                   const void *mem,
-                  size_t len);
+                  size_t len,
+                  int *curlcode);
+
+/* for documentation see Curl_ssl_recv() in sslgen.h */
 ssize_t Curl_nss_recv(struct connectdata *conn, /* connection data */
                       int num,                  /* socketindex */
                       char *buf,                /* store read data here */
                       size_t buffersize,        /* max amount to read */
-                      bool *wouldblock);
+                      int *curlcode);
 
 size_t Curl_nss_version(char *buffer, size_t size);
 int Curl_nss_check_cxn(struct connectdata *cxn);
index 7f7c2cb9d9ec192dbc0f0e4b543c16380a65b8a6..90c527558f1161f057a98328210f0016972b5b96 100644 (file)
@@ -268,6 +268,9 @@ static ssize_t send_plain(struct connectdata *conn,
 /*
  * Curl_write() is an internal write function that sends data to the
  * server. Works with plain sockets, SCP, SSL or kerberos.
+ *
+ * If the write would block (EWOULDBLOCK), we return CURLE_OK and
+ * (*written == 0). Otherwise we return regular CURLcode value.
  */
 CURLcode Curl_write(struct connectdata *conn,
                     curl_socket_t sockfd,
@@ -276,11 +279,11 @@ CURLcode Curl_write(struct connectdata *conn,
                     ssize_t *written)
 {
   ssize_t bytes_written;
-  CURLcode retcode;
+  int curlcode = CURLE_OK;
   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
 
   if(conn->ssl[num].state == ssl_connection_complete)
-    bytes_written = Curl_ssl_send(conn, num, mem, len);
+    bytes_written = Curl_ssl_send(conn, num, mem, len, &curlcode);
   else if(Curl_ssh_enabled(conn, PROT_SCP))
     bytes_written = Curl_scp_send(conn, num, mem, len);
   else if(Curl_ssh_enabled(conn, PROT_SFTP))
@@ -291,9 +294,24 @@ CURLcode Curl_write(struct connectdata *conn,
     bytes_written = send_plain(conn, num, mem, len);
 
   *written = bytes_written;
-  retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
+  if(-1 != bytes_written)
+    /* we completely ignore the curlcode value when -1 is not returned */
+    return CURLE_OK;
 
-  return retcode;
+  /* handle EWOULDBLOCK or a send failure */
+  switch(curlcode) {
+  case /* EWOULDBLOCK */ -1:
+    *written = /* EWOULDBLOCK */ 0;
+    return CURLE_OK;
+
+  case CURLE_OK:
+    /* general send failure */
+    return CURLE_SEND_ERROR;
+
+  default:
+    /* we got a specific curlcode, forward it */
+    return (CURLcode)curlcode;
+  }
 }
 
 /*
@@ -535,13 +553,11 @@ int Curl_read(struct connectdata *conn, /* connection data */
   }
 
   if(conn->ssl[num].state == ssl_connection_complete) {
-    nread = Curl_ssl_recv(conn, num, buffertofill, bytesfromsocket);
+    int curlcode;
+    nread = Curl_ssl_recv(conn, num, buffertofill, bytesfromsocket, &curlcode);
 
     if(nread == -1)
-      return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
-    else if(nread == -2)
-      /* -2 from Curl_ssl_recv() means a true error, not EWOULDBLOCK */
-      return CURLE_RECV_ERROR;
+      return curlcode;
   }
   else if(Curl_ssh_enabled(conn, (PROT_SCP|PROT_SFTP))) {
     if(conn->protocol & PROT_SCP)
index a050f109499a7c3c9c1595bd8e591f2b45f52a84..df2a4075aeff9d3553f42cac13bf52781c560d64 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -408,38 +408,22 @@ struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data)
   return curlssl_engines_list(data);
 }
 
-/* return number of sent (non-SSL) bytes; -1 on error */
 ssize_t Curl_ssl_send(struct connectdata *conn,
                       int sockindex,
                       const void *mem,
-                      size_t len)
+                      size_t len,
+                      int *curlcode)
 {
-  return curlssl_send(conn, sockindex, mem, len);
+  return curlssl_send(conn, sockindex, mem, len, curlcode);
 }
 
-/* return number of received (decrypted) bytes */
-
-/*
- * If the read would block (EWOULDBLOCK) we return -1. If an error occurs during
- * the read, we return -2. Otherwise we return the count of bytes transfered.
- */
-ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
-                      int sockindex,            /* socketindex */
-                      char *mem,                /* store read data here */
-                      size_t len)               /* max amount to read */
+ssize_t Curl_ssl_recv(struct connectdata *conn,
+                      int sockindex,
+                      char *mem,
+                      size_t len,
+                      int *curlcode)
 {
-  ssize_t nread;
-  bool block = FALSE;
-
-  nread = curlssl_recv(conn, sockindex, mem, len, &block);
-  if(nread == -1) {
-    if(!block)
-      return -2; /* this is a true error, not EWOULDBLOCK */
-    else
-      return -1; /* EWOULDBLOCK */
-  }
-
-  return nread;
+  return curlssl_recv(conn, sockindex, mem, len, curlcode);
 }
 
 
index 820f532f04c501aa4f25ef0b78c90ffa411797db..18858af15cbdb4660d7883ff4a97430725e7f3fe 100644 (file)
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2008, 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -44,14 +44,29 @@ CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine);
 /* Sets engine as default for all SSL operations */
 CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data);
 struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data);
-ssize_t Curl_ssl_send(struct connectdata *conn,
-                      int sockindex,
-                      const void *mem,
-                      size_t len);
+
+/* If the write would block (EWOULDBLOCK) or fail, we we return -1.
+ * The error or -1 (for EWOULDBLOCK) is then stored in *curlcode.
+ * Otherwise we return the count of (non-SSL) bytes transfered.
+ */
+ssize_t Curl_ssl_send(struct connectdata *conn, /* connection data */
+                      int sockindex,            /* socketindex */
+                      const void *mem,          /* data to write */
+                      size_t len,               /* max amount to write */
+                      int *curlcode);           /* error to return,
+                                                   -1 means EWOULDBLOCK */
+
+/* If the read would block (EWOULDBLOCK) or fail, we we return -1.
+ * The error or -1 (for EWOULDBLOCK) is then stored in *curlcode.
+ * Otherwise we return the count of (non-SSL) bytes transfered.
+ */
 ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
                       int sockindex,            /* socketindex */
                       char *mem,                /* store read data here */
-                      size_t len);              /* max amount to read */
+                      size_t len,               /* max amount to read */
+                      int *curlcode);           /* error to return,
+                                                   -1 means EWOULDBLOCK */
+
 /* init the SSL session ID cache */
 CURLcode Curl_ssl_initsessions(struct SessionHandle *, long);
 size_t Curl_ssl_version(char *buffer, size_t size);
index bc354322a4def8a783d24d87d091eb1c04f1a1d7..d9cf382907f36629aebc943ce9089cef91b1f37b 100644 (file)
@@ -2482,11 +2482,12 @@ bool Curl_ossl_data_pending(const struct connectdata *conn,
     return FALSE;
 }
 
-/* return number of sent (non-SSL) bytes */
+/* for documentation see Curl_ssl_send() in sslgen.h */
 ssize_t Curl_ossl_send(struct connectdata *conn,
                        int sockindex,
                        const void *mem,
-                       size_t len)
+                       size_t len,
+                       int *curlcode)
 {
   /* SSL_write() is said to return 'int' while write() and send() returns
      'size_t' */
@@ -2509,10 +2510,12 @@ ssize_t Curl_ossl_send(struct connectdata *conn,
       /* The operation did not complete; the same TLS/SSL I/O function
          should be called again later. This is basicly an EWOULDBLOCK
          equivalent. */
-      return 0;
+      *curlcode = /* EWOULDBLOCK */ -1;
+      return -1;
     case SSL_ERROR_SYSCALL:
       failf(conn->data, "SSL_write() returned SYSCALL, errno = %d",
             SOCKERRNO);
+      *curlcode = CURLE_SEND_ERROR;
       return -1;
     case SSL_ERROR_SSL:
       /*  A failure in the SSL library occurred, usually a protocol error.
@@ -2520,25 +2523,23 @@ ssize_t Curl_ossl_send(struct connectdata *conn,
       sslerror = ERR_get_error();
       failf(conn->data, "SSL_write() error: %s",
             ERR_error_string(sslerror, error_buffer));
+      *curlcode = CURLE_SEND_ERROR;
       return -1;
     }
     /* a true error */
     failf(conn->data, "SSL_write() return error %d", err);
+    *curlcode = CURLE_SEND_ERROR;
     return -1;
   }
   return (ssize_t)rc; /* number of bytes */
 }
 
-/*
- * If the read would block we return -1 and set 'wouldblock' to TRUE.
- * Otherwise we return the amount of data read. Other errors should return -1
- * and set 'wouldblock' to FALSE.
- */
+/* for documentation see Curl_ssl_recv() in sslgen.h */
 ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */
                        int num,                  /* socketindex */
                        char *buf,                /* store read data here */
                        size_t buffersize,        /* max amount to read */
-                       bool *wouldblock)
+                       int *curlcode)
 {
   char error_buffer[120]; /* OpenSSL documents that this must be at
                              least 120 bytes long. */
@@ -2548,7 +2549,6 @@ ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */
 
   buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
   nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, buffsize);
-  *wouldblock = FALSE;
   if(nread < 0) {
     /* failed SSL_read */
     int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
@@ -2560,14 +2560,15 @@ ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */
     case SSL_ERROR_WANT_READ:
     case SSL_ERROR_WANT_WRITE:
       /* there's data pending, re-invoke SSL_read() */
-      *wouldblock = TRUE;
-      return -1; /* basically EWOULDBLOCK */
+      *curlcode = -1;  /* EWOULDBLOCK */
+      return -1;
     default:
       /* openssl/ssl.h says "look at error stack/return value/errno" */
       sslerror = ERR_get_error();
       failf(conn->data, "SSL read: %s, errno %d",
             ERR_error_string(sslerror, error_buffer),
             SOCKERRNO);
+      *curlcode = CURLE_RECV_ERROR;
       return -1;
     }
   }
index 9e58d204ba382bb49fe8a62f6fba57e6bb97d916..00357afc5f3caa52e8e57408eb593772f6756261 100644 (file)
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -56,15 +56,19 @@ struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data);
 int Curl_ossl_init(void);
 void Curl_ossl_cleanup(void);
 
+/* for documentation see Curl_ssl_send() in sslgen.h */
 ssize_t Curl_ossl_send(struct connectdata *conn,
                        int sockindex,
                        const void *mem,
-                       size_t len);
+                       size_t len,
+                       int *curlcode);
+
+/* for documentation see Curl_ssl_recv() in sslgen.h */
 ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */
                        int num,                  /* socketindex */
                        char *buf,                /* store read data here */
                        size_t buffersize,        /* max amount to read */
-                       bool *wouldblock);
+                       int *curlcode);
 
 size_t Curl_ossl_version(char *buffer, size_t size);
 int Curl_ossl_check_cxn(struct connectdata *cxn);