1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-23 16:48: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 static CURLcode
singleipconnect(struct connectdata *conn, singleipconnect(struct connectdata *conn,
const Curl_addrinfo *ai, /* start connecting to this */ 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 * Curl_timeleft() returns the amount of milliseconds left allowed for the
@ -596,7 +596,7 @@ static CURLcode trynextip(struct connectdata *conn,
} }
if(ai) { if(ai) {
result = singleipconnect(conn, ai, &conn->tempsock[tempindex]); result = singleipconnect(conn, ai, tempindex);
if(result == CURLE_COULDNT_CONNECT) { if(result == CURLE_COULDNT_CONNECT) {
ai = ai->ai_next; ai = ai->ai_next;
continue; continue;
@ -778,6 +778,23 @@ CURLcode Curl_is_connected(struct connectdata *conn,
if(conn->tempsock[i] == CURL_SOCKET_BAD) if(conn->tempsock[i] == CURL_SOCKET_BAD)
continue; 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 #ifdef mpeix
/* Call this function once now, and ignore the results. We do this to /* 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 "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) else if(rc & CURL_CSELECT_ERR)
(void)verifyconnect(conn->tempsock[i], &error); (void)verifyconnect(conn->tempsock[i], &error);
error:
/* /*
* The connection failed here, we should attempt to connect to the "next * The connection failed here, we should attempt to connect to the "next
* address" for the given host. But first remember the latest error. * 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, static CURLcode singleipconnect(struct connectdata *conn,
const Curl_addrinfo *ai, const Curl_addrinfo *ai,
curl_socket_t *sockp) int sockindex)
{ {
struct Curl_sockaddr_ex addr; struct Curl_sockaddr_ex addr;
int rc = -1; int rc = -1;
@ -1017,7 +1035,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
int optval = 1; int optval = 1;
#endif #endif
char buffer[STRERROR_LEN]; char buffer[STRERROR_LEN];
curl_socket_t *sockp = &conn->tempsock[sockindex];
*sockp = CURL_SOCKET_BAD; *sockp = CURL_SOCKET_BAD;
result = Curl_socket(conn, ai, &addr, &sockfd); result = Curl_socket(conn, ai, &addr, &sockfd);
@ -1143,21 +1161,22 @@ static CURLcode singleipconnect(struct connectdata *conn,
if(-1 == rc) if(-1 == rc)
error = SOCKERRNO; 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 { else {
*sockp = sockfd; *sockp = sockfd;
return CURLE_OK; 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) { if(-1 == rc) {
switch(error) { switch(error) {
case EINPROGRESS: case EINPROGRESS:
@ -1225,7 +1244,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
/* start connecting to first IP */ /* start connecting to first IP */
while(conn->tempaddr[0]) { while(conn->tempaddr[0]) {
result = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0])); result = singleipconnect(conn, conn->tempaddr[0], 0);
if(!result) if(!result)
break; break;
conn->tempaddr[0] = conn->tempaddr[0]->ai_next; 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 #ifdef ENABLE_QUIC
if(conn->transport == TRNSPRT_QUIC) { if(conn->transport == TRNSPRT_QUIC) {
result = Curl_quic_is_connected(conn, FIRSTSOCKET, done); *done = TRUE;
if(result) return CURLE_OK;
connclose(conn, "Failed HTTPS connection (over QUIC)");
return result;
} }
#endif #endif

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,8 @@ struct quic_handshake {
}; };
struct quicsocket { struct quicsocket {
ngtcp2_conn *conn; struct connectdata *conn; /* point back to the connection */
ngtcp2_conn *qconn;
ngtcp2_cid dcid; ngtcp2_cid dcid;
ngtcp2_cid scid; ngtcp2_cid scid;
uint32_t version; uint32_t version;
@ -64,11 +65,6 @@ struct quicsocket {
#include "urldata.h" #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
#endif /* HEADER_CURL_VQUIC_NGTCP2_H */ #endif /* HEADER_CURL_VQUIC_NGTCP2_H */