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 */ }; |