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)
This commit is contained in:
parent
ea521cf617
commit
77cfeadfa6
21
CHANGES
21
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
|
||||
|
@ -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)
|
||||
|
12
lib/ssluse.c
12
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. */
|
||||
|
Loading…
Reference in New Issue
Block a user