diff options
author | Daniel Stenberg <daniel@haxx.se> | 2020-06-15 16:17:55 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2020-06-16 10:35:05 +0200 |
commit | b3e8f2e0f49a15a63d50584ae2092fde618d09a4 (patch) | |
tree | 5f1eb4169e900bc9cc4363542e2ecd04dd3ff42d /lib/vquic | |
parent | 6b2390ce6549ab3f7d8d129481fa5a2f6009e35b (diff) | |
download | curl-bagder/quic-connects.tar.gz |
connect: improve happy eyeballs handlingbagder/quic-connects
For QUIC but also for regular TCP when the second family runs out of IPs
with a failure while the first family is still trying to connect.
Separated the timeout handling for IPv4 and IPv6 connections when they
both have a number of addresses to iterate over.
Diffstat (limited to 'lib/vquic')
-rw-r--r-- | lib/vquic/ngtcp2.c | 42 | ||||
-rw-r--r-- | lib/vquic/quiche.c | 8 |
2 files changed, 35 insertions, 15 deletions
diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c index b973a7333..e5528231c 100644 --- a/lib/vquic/ngtcp2.c +++ b/lib/vquic/ngtcp2.c @@ -256,11 +256,11 @@ static int quic_set_encryption_secrets(SSL *ssl, int level = quic_from_ossl_level(ossl_level); if(ngtcp2_crypto_derive_and_install_rx_key( - qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0) + qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0) return 0; if(ngtcp2_crypto_derive_and_install_tx_key( - qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0) + qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0) return 0; if(level == NGTCP2_CRYPTO_LEVEL_APP) { @@ -341,9 +341,7 @@ static int quic_init_ssl(struct quicsocket *qs) /* this will need some attention when HTTPS proxy over QUIC get fixed */ const char * const hostname = qs->conn->host.name; - if(qs->ssl) - SSL_free(qs->ssl); - + DEBUGASSERT(!qs->ssl); qs->ssl = SSL_new(qs->sslctx); SSL_set_app_data(qs->ssl, qs); @@ -375,11 +373,11 @@ static int secret_func(gnutls_session_t ssl, if(level != NGTCP2_CRYPTO_LEVEL_EARLY && ngtcp2_crypto_derive_and_install_rx_key( - qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0) + qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0) return 0; if(ngtcp2_crypto_derive_and_install_tx_key( - qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0) + qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0) return 0; if(level == NGTCP2_CRYPTO_LEVEL_APP) { @@ -429,8 +427,8 @@ static int tp_recv_func(gnutls_session_t ssl, const uint8_t *data, ngtcp2_transport_params params; if(ngtcp2_decode_transport_params( - ¶ms, NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS, - data, data_size) != 0) + ¶ms, NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS, + data, data_size) != 0) return -1; if(ngtcp2_conn_set_remote_transport_params(qs->qconn, ¶ms) != 0) @@ -471,8 +469,7 @@ static int quic_init_ssl(struct quicsocket *qs) const char * const hostname = qs->conn->host.name; int rc; - if(qs->ssl) - gnutls_deinit(qs->ssl); + DEBUGASSERT(!qs->ssl); gnutls_init(&qs->ssl, GNUTLS_CLIENT); gnutls_session_set_ptr(qs->ssl, qs); @@ -782,6 +779,8 @@ CURLcode Curl_quic_connect(struct connectdata *conn, long port; int qfd; + if(qs->conn) + Curl_quic_disconnect(conn, sockindex); qs->conn = conn; /* extract the used address as a string */ @@ -880,11 +879,16 @@ static int ng_perform_getsock(const struct connectdata *conn, return ng_getsock((struct connectdata *)conn, socks); } -static CURLcode qs_disconnect(struct quicsocket *qs) +static void qs_disconnect(struct quicsocket *qs) { int i; - if(qs->qlogfd != -1) + if(!qs->conn) /* already closed */ + return; + qs->conn = NULL; + if(qs->qlogfd != -1) { close(qs->qlogfd); + qs->qlogfd = -1; + } if(qs->ssl) #ifdef USE_OPENSSL SSL_free(qs->ssl); @@ -903,14 +907,22 @@ static CURLcode qs_disconnect(struct quicsocket *qs) #ifdef USE_OPENSSL SSL_CTX_free(qs->sslctx); #endif - return CURLE_OK; +} + +void Curl_quic_disconnect(struct connectdata *conn, + int tempindex) +{ + if(conn->transport == TRNSPRT_QUIC) + qs_disconnect(&conn->hequic[tempindex]); } static CURLcode ng_disconnect(struct connectdata *conn, bool dead_connection) { (void)dead_connection; - return qs_disconnect(&conn->hequic[0]); + Curl_quic_disconnect(conn, 0); + Curl_quic_disconnect(conn, 1); + return CURLE_OK; } static unsigned int ng_conncheck(struct connectdata *conn, diff --git a/lib/vquic/quiche.c b/lib/vquic/quiche.c index 9af2d894f..be6f15c19 100644 --- a/lib/vquic/quiche.c +++ b/lib/vquic/quiche.c @@ -107,6 +107,14 @@ static CURLcode quiche_disconnect(struct connectdata *conn, (void)dead_connection; return qs_disconnect(qs); } + +void Curl_quic_disconnect(struct connectdata *conn, + int tempindex) +{ + if(conn->transport == TRNSPRT_QUIC) + qs_disconnect(&conn->hequic[tempindex]); +} + static unsigned int quiche_conncheck(struct connectdata *conn, unsigned int checks_to_perform) { |