diff --git a/lib/pingpong.c b/lib/pingpong.c index c753103984..a661a0285b 100644 --- a/lib/pingpong.c +++ b/lib/pingpong.c @@ -116,11 +116,15 @@ CURLcode Curl_pp_statemach(struct Curl_easy *data, else if(!pp->sendleft && Curl_conn_data_pending(data, FIRSTSOCKET)) /* We are receiving and there is data ready in the SSL library */ rc = 1; - else + else { + DEBUGF(infof(data, "pp_statematch, select, timeout=%" FMT_TIMEDIFF_T + ", sendleft=%zu", + timeout_ms, pp->sendleft)); rc = Curl_socket_check(pp->sendleft ? CURL_SOCKET_BAD : sock, /* reading */ CURL_SOCKET_BAD, pp->sendleft ? sock : CURL_SOCKET_BAD, /* writing */ interval_ms); + } if(block) { /* if we did not wait, we do not have to spend time on this now */ diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index 9a805589a2..69cde17c2c 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -769,8 +769,11 @@ static int ossl_bio_cf_in_read(BIO *bio, char *buf, int blen) if(CURLE_AGAIN == result) BIO_set_retry_read(bio); } - else if(nread == 0) { - connssl->peer_closed = TRUE; + else { + /* feeding data to OpenSSL means SSL_read() might succeed */ + connssl->input_pending = TRUE; + if(nread == 0) + connssl->peer_closed = TRUE; } /* Before returning server replies to the SSL instance, we need @@ -5216,13 +5219,8 @@ static bool ossl_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data) { struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - (void)data; - DEBUGASSERT(connssl && octx); - if(octx->ssl && SSL_pending(octx->ssl)) - return TRUE; - return FALSE; + return connssl->input_pending; } static ssize_t ossl_send(struct Curl_cfilter *cf, @@ -5415,6 +5413,15 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf, } out: + if(!nread || ((nread < 0) && (*curlcode == CURLE_AGAIN))) { + /* This happens when: + * - we read an EOF + * - OpenSSLs buffers are empty, there is no more data + * - OpenSSL read is blocked on writing something first + * - an incomplete TLS packet is buffered that cannot be read + * until more data arrives */ + connssl->input_pending = FALSE; + } return nread; } diff --git a/lib/vtls/vtls_int.h b/lib/vtls/vtls_int.h index c01a44864e..6cd2ae4d26 100644 --- a/lib/vtls/vtls_int.h +++ b/lib/vtls/vtls_int.h @@ -127,6 +127,7 @@ struct ssl_connect_data { BIT(use_alpn); /* if ALPN shall be used in handshake */ BIT(peer_closed); /* peer has closed connection */ BIT(prefs_checked); /* SSL preferences have been checked */ + BIT(input_pending); /* data for SSL_read() may be available */ };