diff options
author | Daniel Stenberg <daniel@haxx.se> | 2010-05-14 22:34:10 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2010-05-14 22:35:08 +0200 |
commit | 77cfeadfa6405c5808273f1d3cc8e89eb17e5f08 (patch) | |
tree | 17334b90cd9a519fbb24ec642b62aee2cec40d68 /lib | |
parent | ea521cf6173a8140d2d8e22e8e4e2ecd9683d7a4 (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)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ssluse.c | 12 |
1 files changed, 11 insertions, 1 deletions
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. */ |