1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-23 08:38:49 -05:00

ngtcp2: do QUIC connections happy-eyeballs friendly

This commit is contained in:
Daniel Stenberg 2019-08-12 16:28:28 +02:00
parent 1d85e09ccd
commit f2cc26456b
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
6 changed files with 262 additions and 230 deletions

View File

@ -166,7 +166,7 @@ tcpkeepalive(struct Curl_easy *data,
static CURLcode
singleipconnect(struct connectdata *conn,
const Curl_addrinfo *ai, /* start connecting to this */
curl_socket_t *sock);
int sockindex); /* 0 or 1 among the temp ones */
/*
* Curl_timeleft() returns the amount of milliseconds left allowed for the
@ -596,7 +596,7 @@ static CURLcode trynextip(struct connectdata *conn,
}
if(ai) {
result = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
result = singleipconnect(conn, ai, tempindex);
if(result == CURLE_COULDNT_CONNECT) {
ai = ai->ai_next;
continue;
@ -778,6 +778,23 @@ CURLcode Curl_is_connected(struct connectdata *conn,
if(conn->tempsock[i] == CURL_SOCKET_BAD)
continue;
#ifdef ENABLE_QUIC
if(conn->transport == TRNSPRT_QUIC) {
result = Curl_quic_is_connected(conn, i, connected);
if(result) {
error = SOCKERRNO;
goto error;
}
if(*connected) {
/* use this socket from now on */
conn->sock[sockindex] = conn->tempsock[i];
conn->ip_addr = conn->tempaddr[i];
conn->tempsock[i] = CURL_SOCKET_BAD;
}
return result;
}
#endif
#ifdef mpeix
/* Call this function once now, and ignore the results. We do this to
"clear" the error state on the socket so that we can later read it
@ -841,6 +858,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
else if(rc & CURL_CSELECT_ERR)
(void)verifyconnect(conn->tempsock[i], &error);
error:
/*
* The connection failed here, we should attempt to connect to the "next
* address" for the given host. But first remember the latest error.
@ -1001,7 +1019,7 @@ void Curl_sndbufset(curl_socket_t sockfd)
*/
static CURLcode singleipconnect(struct connectdata *conn,
const Curl_addrinfo *ai,
curl_socket_t *sockp)
int sockindex)
{
struct Curl_sockaddr_ex addr;
int rc = -1;
@ -1017,7 +1035,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
int optval = 1;
#endif
char buffer[STRERROR_LEN];
curl_socket_t *sockp = &conn->tempsock[sockindex];
*sockp = CURL_SOCKET_BAD;
result = Curl_socket(conn, ai, &addr, &sockfd);
@ -1143,21 +1161,22 @@ static CURLcode singleipconnect(struct connectdata *conn,
if(-1 == rc)
error = SOCKERRNO;
#ifdef ENABLE_QUIC
else if(conn->transport == TRNSPRT_QUIC) {
/* pass in 'sockfd' separately since it hasn't been put into the
tempsock array at this point */
result = Curl_quic_connect(conn, sockfd, sockindex,
&addr.sa_addr, addr.addrlen);
if(result)
error = SOCKERRNO;
}
#endif
}
else {
*sockp = sockfd;
return CURLE_OK;
}
#ifdef ENABLE_QUIC
if(!isconnected && (conn->transport == TRNSPRT_QUIC)) {
result = Curl_quic_connect(conn, sockfd, &addr.sa_addr, addr.addrlen);
if(result)
return result;
rc = 0; /* connect success */
}
#endif
if(-1 == rc) {
switch(error) {
case EINPROGRESS:
@ -1225,7 +1244,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
/* start connecting to first IP */
while(conn->tempaddr[0]) {
result = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
result = singleipconnect(conn, conn->tempaddr[0], 0);
if(!result)
break;
conn->tempaddr[0] = conn->tempaddr[0]->ai_next;

View File

@ -1565,10 +1565,8 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
#ifdef ENABLE_QUIC
if(conn->transport == TRNSPRT_QUIC) {
result = Curl_quic_is_connected(conn, FIRSTSOCKET, done);
if(result)
connclose(conn, "Failed HTTPS connection (over QUIC)");
return result;
*done = TRUE;
return CURLE_OK;
}
#endif

View File

@ -37,10 +37,12 @@
/* functions provided by the specific backends */
CURLcode Curl_quic_connect(struct connectdata *conn,
curl_socket_t sockfd,
int sockindex,
const struct sockaddr *addr,
socklen_t addrlen);
CURLcode Curl_quic_is_connected(struct connectdata *conn, int sockindex,
bool *done);
CURLcode Curl_quic_is_connected(struct connectdata *conn,
curl_socket_t sockfd,
bool *connected);
int Curl_quic_ver(char *p, size_t len);
#endif

View File

@ -836,7 +836,8 @@ struct connectdata {
} transport;
#ifdef ENABLE_QUIC
struct quicsocket quic;
struct quicsocket hequic[2]; /* two, for happy eyeballs! */
struct quicsocket *quic;
#endif
struct hostname host;

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,8 @@ struct quic_handshake {
};
struct quicsocket {
ngtcp2_conn *conn;
struct connectdata *conn; /* point back to the connection */
ngtcp2_conn *qconn;
ngtcp2_cid dcid;
ngtcp2_cid scid;
uint32_t version;
@ -64,11 +65,6 @@ struct quicsocket {
#include "urldata.h"
CURLcode Curl_quic_connect(struct connectdata *conn,
curl_socket_t sockfd,
const struct sockaddr *addr,
socklen_t addrlen);
int Curl_quic_ver(char *p, size_t len);
#endif
#endif /* HEADER_CURL_VQUIC_NGTCP2_H */