diff options
| author | Nick Zitzmann <nick@chronosnet.com> | 2012-07-16 20:20:57 -0600 | 
|---|---|---|
| committer | Daniel Stenberg <daniel@haxx.se> | 2012-07-25 23:22:11 +0200 | 
| commit | f92779198d07abb18e8a5c4dd3a2e1b7c4c8726a (patch) | |
| tree | 258327de5670f3570e7a932ce7c94b9fe8d7a510 | |
| parent | 9ac5cdfc2f0a0fed15588b8a007c565fa711c9c3 (diff) | |
darwinssl: fixed freeze involving the multi interface
Previously the curl_multi interface would freeze if darwinssl was
enabled and at least one of the handles tried to connect to a Web site
using HTTPS. Removed the "wouldblock" state darwinssl was using because
I figured out a solution for our "would block but in which direction?"
dilemma.
| -rw-r--r-- | lib/curl_darwinssl.c | 38 | ||||
| -rw-r--r-- | lib/http.c | 7 | ||||
| -rw-r--r-- | lib/urldata.h | 4 | 
3 files changed, 25 insertions, 24 deletions
| diff --git a/lib/curl_darwinssl.c b/lib/curl_darwinssl.c index 893a6fc2a..c848be746 100644 --- a/lib/curl_darwinssl.c +++ b/lib/curl_darwinssl.c @@ -71,7 +71,9 @@ static OSStatus SocketRead(SSLConnectionRef connection,    UInt32 bytesToGo = *dataLength;    UInt32 initLen = bytesToGo;    UInt8 *currData = (UInt8 *)data; -  int sock = *(int *)connection; +  /*int sock = *(int *)connection;*/ +  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; +  int sock = connssl->ssl_sockfd;    OSStatus rtn = noErr;    UInt32 bytesRead;    int rrtn; @@ -100,6 +102,7 @@ static OSStatus SocketRead(SSLConnectionRef connection,              break;            case EAGAIN:              rtn = errSSLWouldBlock; +            connssl->ssl_direction = false;              break;            default:              rtn = ioErr; @@ -128,7 +131,9 @@ static OSStatus SocketWrite(SSLConnectionRef connection,                              size_t *dataLength)  /* IN/OUT */  {    UInt32 bytesSent = 0; -  int sock = *(int *)connection; +  /*int sock = *(int *)connection;*/ +  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; +  int sock = connssl->ssl_sockfd;    int length;    UInt32 dataLen = *dataLength;    const UInt8 *dataPtr = (UInt8 *)data; @@ -148,6 +153,7 @@ static OSStatus SocketWrite(SSLConnectionRef connection,      theErr = errno;      if(theErr == EAGAIN) {        ortn = errSSLWouldBlock; +      connssl->ssl_direction = true;      }      else {        ortn = ioErr; @@ -388,7 +394,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,  #else    struct in_addr addr;  #endif -  SSLConnectionRef ssl_connection; +  /*SSLConnectionRef ssl_connection;*/    OSStatus err = noErr;    if(connssl->ssl_ctx) @@ -467,8 +473,9 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,     * SSLSetConnection() will not copy that address. I've found that     * conn->sock[sockindex] may change on its own. */    connssl->ssl_sockfd = sockfd; -  ssl_connection = &(connssl->ssl_sockfd); -  err = SSLSetConnection(connssl->ssl_ctx, ssl_connection); +  /*ssl_connection = &(connssl->ssl_sockfd); +  err = SSLSetConnection(connssl->ssl_ctx, ssl_connection);*/ +  err = SSLSetConnection(connssl->ssl_ctx, connssl);    if(err != noErr) {      failf(data, "SSL: SSLSetConnection() failed: %d", err);      return CURLE_SSL_CONNECT_ERROR; @@ -488,8 +495,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)    DEBUGASSERT(ssl_connect_2 == connssl->connecting_state                || ssl_connect_2_reading == connssl->connecting_state -              || ssl_connect_2_writing == connssl->connecting_state -              || ssl_connect_2_wouldblock == connssl->connecting_state); +              || ssl_connect_2_writing == connssl->connecting_state);    /* Here goes nothing: */    err = SSLHandshake(connssl->ssl_ctx); @@ -497,7 +503,8 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)    if(err != noErr) {      switch (err) {        case errSSLWouldBlock:  /* they're not done with us yet */ -        connssl->connecting_state = ssl_connect_2_wouldblock; +        connssl->connecting_state = connssl->ssl_direction ? +            ssl_connect_2_writing : ssl_connect_2_reading;          return CURLE_OK;          break; @@ -609,8 +616,7 @@ darwinssl_connect_common(struct connectdata *conn,    while(ssl_connect_2 == connssl->connecting_state ||          ssl_connect_2_reading == connssl->connecting_state || -        ssl_connect_2_writing == connssl->connecting_state || -        ssl_connect_2_wouldblock == connssl->connecting_state) { +        ssl_connect_2_writing == connssl->connecting_state) {      /* check allowed time left */      timeout_ms = Curl_timeleft(data, NULL, TRUE); @@ -623,14 +629,11 @@ darwinssl_connect_common(struct connectdata *conn,      /* if ssl is expecting something, check if it's available. */      if(connssl->connecting_state == ssl_connect_2_reading -       || connssl->connecting_state == ssl_connect_2_writing -       || connssl->connecting_state == ssl_connect_2_wouldblock) { +       || connssl->connecting_state == ssl_connect_2_writing) { -      curl_socket_t writefd = ssl_connect_2_writing -      || ssl_connect_2_wouldblock == +      curl_socket_t writefd = ssl_connect_2_writing ==        connssl->connecting_state?sockfd:CURL_SOCKET_BAD; -      curl_socket_t readfd = ssl_connect_2_reading -      || ssl_connect_2_wouldblock == +      curl_socket_t readfd = ssl_connect_2_reading ==        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;        what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms); @@ -663,8 +666,7 @@ darwinssl_connect_common(struct connectdata *conn,      if(retcode || (nonblocking &&                     (ssl_connect_2 == connssl->connecting_state ||                      ssl_connect_2_reading == connssl->connecting_state || -                    ssl_connect_2_writing == connssl->connecting_state || -                    ssl_connect_2_wouldblock == connssl->connecting_state))) +                    ssl_connect_2_writing == connssl->connecting_state)))        return retcode;    } /* repeat step2 until all transactions are done. */ diff --git a/lib/http.c b/lib/http.c index 06bdf610c..0c12d1896 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1371,9 +1371,10 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)  }  #endif -#if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) -/* This function is for OpenSSL, GnuTLS and schannel only. It should be -   made to query the generic SSL layer instead. */ +#if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \ +    defined(USE_DARWINSSL) +/* This function is for OpenSSL, GnuTLS, darwinssl, and schannel only. +   It should be made to query the generic SSL layer instead. */  static int https_getsock(struct connectdata *conn,                           curl_socket_t *socks,                           int numsocks) diff --git a/lib/urldata.h b/lib/urldata.h index 5ad07c5f1..fddfc0d05 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -248,9 +248,6 @@ typedef enum {    ssl_connect_2,    ssl_connect_2_reading,    ssl_connect_2_writing, -#ifdef USE_DARWINSSL -  ssl_connect_2_wouldblock, -#endif /* USE_DARWINSSL */    ssl_connect_3,    ssl_connect_done  } ssl_connect_state; @@ -327,6 +324,7 @@ struct ssl_connect_data {    SSLContextRef ssl_ctx;    curl_socket_t ssl_sockfd;    ssl_connect_state connecting_state; +  bool ssl_direction; /* true if writing, false if reading */  #endif /* USE_DARWINSSL */  }; | 
