summaryrefslogtreecommitdiff
path: root/lib/vquic
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2020-06-15 16:17:55 +0200
committerDaniel Stenberg <daniel@haxx.se>2020-06-16 10:35:05 +0200
commitb3e8f2e0f49a15a63d50584ae2092fde618d09a4 (patch)
tree5f1eb4169e900bc9cc4363542e2ecd04dd3ff42d /lib/vquic
parent6b2390ce6549ab3f7d8d129481fa5a2f6009e35b (diff)
downloadcurl-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.c42
-rw-r--r--lib/vquic/quiche.c8
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(
- &params, NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS,
- data, data_size) != 0)
+ &params, NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS,
+ data, data_size) != 0)
return -1;
if(ngtcp2_conn_set_remote_transport_params(qs->qconn, &params) != 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)
{