aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2010-05-14 22:34:10 +0200
committerDaniel Stenberg <daniel@haxx.se>2010-05-14 22:35:08 +0200
commit77cfeadfa6405c5808273f1d3cc8e89eb17e5f08 (patch)
tree17334b90cd9a519fbb24ec642b62aee2cec40d68
parentea521cf6173a8140d2d8e22e8e4e2ecd9683d7a4 (diff)
OpenSSL: multi interface handshake could hang
John-Mark Bell filed bug #3000052 that identified a problem (with an associated patch) with the OpenSSL handshake state machine when the multi interface is used: Performing an https request using a curl multi handle and using select or epoll to wait for events results in a hang. It appears that the cause is the fix for bug #2958179, which makes ossl_connect_common unconditionally return from the step 2 loop when fetching from a multi handle. When ossl_connect_step2 has completed, it updates connssl->connecting_state to ssl_connect_3. ossl_connect_common will then return to the caller, as a multi handle is in use. Eventually, the client code will call curl_multi_fdset to obtain an updated fdset to select or epoll on. For https requests, curl_multi_fdset will cause https_getsock to be called. https_getsock will only return a socket handle if the connecting_state is ssl_connect_2_reading or ssl_connect_2_writing. Therefore, the client will never obtain a valid fdset, and thus not drive the multi handle, resulting in a hang. (http://curl.haxx.se/bug/view.cgi?id=3000052)
-rw-r--r--CHANGES21
-rw-r--r--RELEASE-NOTES3
-rw-r--r--lib/ssluse.c12
3 files changed, 34 insertions, 2 deletions
diff --git a/CHANGES b/CHANGES
index ecb36c437..d895ebeb6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,27 @@
Changelog
Daniel Stenberg (14 May 2010)
+- John-Mark Bell filed bug #3000052 that identified a problem (with an
+ associated patch) with the OpenSSL handshake state machine when the multi
+ interface is used:
+
+ Performing an https request using a curl multi handle and using select or
+ epoll to wait for events results in a hang. It appears that the cause is the
+ fix for bug #2958179, which makes ossl_connect_common unconditionally return
+ from the step 2 loop when fetching from a multi handle.
+
+ When ossl_connect_step2 has completed, it updates connssl->connecting_state
+ to ssl_connect_3. ossl_connect_common will then return to the caller, as a
+ multi handle is in use. Eventually, the client code will call
+ curl_multi_fdset to obtain an updated fdset to select or epoll on. For https
+ requests, curl_multi_fdset will cause https_getsock to be called.
+ https_getsock will only return a socket handle if the connecting_state is
+ ssl_connect_2_reading or ssl_connect_2_writing. Therefore, the client will
+ never obtain a valid fdset, and thus not drive the multi handle, resulting
+ in a hang.
+
+ (http://curl.haxx.se/bug/view.cgi?id=3000052)
+
- Sebastian V reported bug #3000056 identifying a problem with redirect
following. It showed that when curl followed redirects it didn't properly
ignore the response body of the 30X response if that response was using
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 83b682e98..37348f91f 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -29,6 +29,7 @@ This release includes the following bugfixes:
o multi interface missed storing connection time
o broken CRL support in libcurl-NSS
o ignore response-body on redirect even if compressed
+ o OpenSSL handshake state-machine for multi interface
This release includes the following known bugs:
@@ -39,6 +40,6 @@ advice from friends like these:
Rainer Canavan, Paul Howarth, Jerome Vouillon, Ruslan Gazizov, Yang Tse,
Kamil Dudka, Alex Bligh, Ben Greear, Hoi-Ho Chan, Howard Chu, Dirk Manske,
- Pavel Raiskup
+ Pavel Raiskup, John-Mark Bell
Thanks! (and sorry if I forgot to mention someone)
diff --git a/lib/ssluse.c b/lib/ssluse.c
index ce62605e8..01eba90db 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -2425,8 +2425,18 @@ ossl_connect_common(struct connectdata *conn,
/* socket is readable or writable */
}
+ /* Run transaction, and return to the caller if it failed or if
+ * this connection is part of a multi handle and this loop would
+ * execute again. This permits the owner of a multi handle to
+ * abort a connection attempt before step2 has completed while
+ * ensuring that a client using select() or epoll() will always
+ * have a valid fdset to wait on.
+ */
retcode = ossl_connect_step2(conn, sockindex);
- if(retcode || (data->state.used_interface == Curl_if_multi))
+ if(retcode || (data->state.used_interface == Curl_if_multi &&
+ (ssl_connect_2 == connssl->connecting_state ||
+ ssl_connect_2_reading == connssl->connecting_state ||
+ ssl_connect_2_writing == connssl->connecting_state)))
return retcode;
} /* repeat step2 until all transactions are done. */