diff options
Diffstat (limited to 'libs/libcurl/src/connect.c')
-rw-r--r-- | libs/libcurl/src/connect.c | 124 |
1 files changed, 69 insertions, 55 deletions
diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c index 421f904159..29293f0874 100644 --- a/libs/libcurl/src/connect.c +++ b/libs/libcurl/src/connect.c @@ -166,7 +166,7 @@ tcpkeepalive(struct Curl_easy *data, static CURLcode singleipconnect(struct connectdata *conn, - const Curl_addrinfo *ai, /* start connecting to this */ + const struct Curl_addrinfo *ai, /* start connecting to this */ int tempindex); /* 0 or 1 among the temp ones */ /* @@ -558,11 +558,11 @@ static bool verifyconnect(curl_socket_t sockfd, int *error) /* update tempaddr[tempindex] (to the next entry), makes sure to stick to the correct family */ -static Curl_addrinfo *ainext(struct connectdata *conn, - int tempindex, - bool next) /* use current or next entry */ +static struct Curl_addrinfo *ainext(struct connectdata *conn, + int tempindex, + bool next) /* use next entry? */ { - Curl_addrinfo *ai = conn->tempaddr[tempindex]; + struct Curl_addrinfo *ai = conn->tempaddr[tempindex]; if(ai && next) ai = ai->ai_next; while(ai && (ai->ai_family != conn->tempfamily[tempindex])) @@ -571,7 +571,7 @@ static Curl_addrinfo *ainext(struct connectdata *conn, return ai; } -/* Used within the multi interface. Try next IP address, return TRUE if no +/* Used within the multi interface. Try next IP address, returns error if no more address exists or error */ static CURLcode trynextip(struct connectdata *conn, int sockindex, @@ -587,7 +587,7 @@ static CURLcode trynextip(struct connectdata *conn, conn->tempsock[tempindex] = CURL_SOCKET_BAD; if(sockindex == FIRSTSOCKET) { - Curl_addrinfo *ai = conn->tempaddr[tempindex]; + struct Curl_addrinfo *ai = conn->tempaddr[tempindex]; while(ai) { if(ai) { @@ -747,8 +747,8 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex, { CURLcode result = CURLE_OK; - if(conn->bits.socksproxy) { #ifndef CURL_DISABLE_PROXY + if(conn->bits.socksproxy) { /* for the secondary socket (FTP), use the "connect to host" * but ignore the "connect to port" (use the secondary port) */ @@ -781,11 +781,12 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex, failf(conn->data, "unknown proxytype option given"); result = CURLE_COULDNT_CONNECT; } /* switch proxytype */ -#else - (void)sockindex; -#endif /* CURL_DISABLE_PROXY */ } else +#else + (void)conn; + (void)sockindex; +#endif /* CURL_DISABLE_PROXY */ *done = TRUE; /* no SOCKS proxy, so consider us connected */ return result; @@ -822,8 +823,8 @@ CURLcode Curl_is_connected(struct connectdata *conn, timediff_t allow; int error = 0; struct curltime now; - int rc; - int i; + int rc = 0; + unsigned int i; DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET); @@ -858,49 +859,50 @@ CURLcode Curl_is_connected(struct connectdata *conn, const int other = i ^ 1; if(conn->tempsock[i] == CURL_SOCKET_BAD) continue; - + error = 0; #ifdef ENABLE_QUIC if(conn->transport == TRNSPRT_QUIC) { result = Curl_quic_is_connected(conn, i, connected); - if(result) { - error = SOCKERRNO; - goto error; - } - if(*connected) { + if(!result && *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; post_SOCKS(conn, sockindex, connected); connkeep(conn, "HTTP/3 default"); + return CURLE_OK; } - return result; + if(result) + error = SOCKERRNO; } + else #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 - reliably. This is reported necessary on the MPE/iX operating system. */ - (void)verifyconnect(conn->tempsock[i], NULL); + /* 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 + reliably. This is reported necessary on the MPE/iX operating + system. */ + (void)verifyconnect(conn->tempsock[i], NULL); #endif - /* check socket for connect */ - rc = SOCKET_WRITABLE(conn->tempsock[i], 0); + /* check socket for connect */ + rc = SOCKET_WRITABLE(conn->tempsock[i], 0); + } if(rc == 0) { /* no connection yet */ - error = 0; - if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr) { + if(Curl_timediff(now, conn->connecttime) >= + conn->timeoutms_per_addr[i]) { infof(data, "After %" CURL_FORMAT_TIMEDIFF_T - "ms connect time, move on!\n", conn->timeoutms_per_addr); + "ms connect time, move on!\n", conn->timeoutms_per_addr[i]); error = ETIMEDOUT; } /* should we try another protocol family? */ - if(i == 0 && !conn->parallel_connect && + if(i == 0 && !conn->bits.parallel_connect && (Curl_timediff(now, conn->connecttime) >= data->set.happy_eyeballs_timeout)) { - conn->parallel_connect = TRUE; /* starting now */ + conn->bits.parallel_connect = TRUE; /* starting now */ trynextip(conn, sockindex, 1); } } @@ -937,9 +939,6 @@ CURLcode Curl_is_connected(struct connectdata *conn, else if(rc & CURL_CSELECT_ERR) (void)verifyconnect(conn->tempsock[i], &error); -#ifdef ENABLE_QUIC - error: -#endif /* * The connection failed here, we should attempt to connect to the "next * address" for the given host. But first remember the latest error. @@ -952,13 +951,14 @@ CURLcode Curl_is_connected(struct connectdata *conn, #ifndef CURL_DISABLE_VERBOSE_STRINGS char ipaddress[MAX_IPADR_LEN]; char buffer[STRERROR_LEN]; - Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN); -#endif + Curl_printable_address(conn->tempaddr[i], ipaddress, + sizeof(ipaddress)); infof(data, "connect to %s port %ld failed: %s\n", ipaddress, conn->port, Curl_strerror(error, buffer, sizeof(buffer))); +#endif - conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ? + conn->timeoutms_per_addr[i] = conn->tempaddr[i]->ai_next == NULL ? allow : allow / 2; ainext(conn, i, TRUE); status = trynextip(conn, sockindex, i); @@ -970,25 +970,28 @@ CURLcode Curl_is_connected(struct connectdata *conn, } } - if(result) { + if(result && + (conn->tempsock[0] == CURL_SOCKET_BAD) && + (conn->tempsock[1] == CURL_SOCKET_BAD)) { /* no more addresses to try */ const char *hostname; char buffer[STRERROR_LEN]; - /* if the first address family runs out of addresses to try before - the happy eyeball timeout, go ahead and try the next family now */ - { - result = trynextip(conn, sockindex, 1); - if(!result) - return result; - } + /* if the first address family runs out of addresses to try before the + happy eyeball timeout, go ahead and try the next family now */ + result = trynextip(conn, sockindex, 1); + if(!result) + return result; +#ifndef CURL_DISABLE_PROXY if(conn->bits.socksproxy) hostname = conn->socks_proxy.host.name; else if(conn->bits.httpproxy) hostname = conn->http_proxy.host.name; - else if(conn->bits.conn_to_host) - hostname = conn->conn_to_host.name; + else +#endif + if(conn->bits.conn_to_host) + hostname = conn->conn_to_host.name; else hostname = conn->host.name; @@ -996,6 +999,9 @@ CURLcode Curl_is_connected(struct connectdata *conn, hostname, conn->port, Curl_strerror(error, buffer, sizeof(buffer))); + Curl_quic_disconnect(conn, 0); + Curl_quic_disconnect(conn, 1); + #ifdef WSAETIMEDOUT if(WSAETIMEDOUT == data->state.os_errno) result = CURLE_OPERATION_TIMEDOUT; @@ -1004,6 +1010,8 @@ CURLcode Curl_is_connected(struct connectdata *conn, result = CURLE_OPERATION_TIMEDOUT; #endif } + else + result = CURLE_OK; /* still trying */ return result; } @@ -1105,7 +1113,7 @@ void Curl_sndbufset(curl_socket_t sockfd) * having connected. */ static CURLcode singleipconnect(struct connectdata *conn, - const Curl_addrinfo *ai, + const struct Curl_addrinfo *ai, int tempindex) { struct Curl_sockaddr_ex addr; @@ -1195,8 +1203,10 @@ static CURLcode singleipconnect(struct connectdata *conn, (void)curlx_nonblock(sockfd, TRUE); conn->connecttime = Curl_now(); - if(conn->num_addr > 1) - Curl_expire(data, conn->timeoutms_per_addr, EXPIRE_DNS_PER_NAME); + if(conn->num_addr > 1) { + Curl_expire(data, conn->timeoutms_per_addr[0], EXPIRE_DNS_PER_NAME); + Curl_expire(data, conn->timeoutms_per_addr[1], EXPIRE_DNS_PER_NAME2); + } /* Connect TCP and QUIC sockets */ if(!isconnected && (conn->transport != TRNSPRT_UDP)) { @@ -1319,8 +1329,10 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ conn->tempsock[0] = conn->tempsock[1] = CURL_SOCKET_BAD; /* Max time for the next connection attempt */ - conn->timeoutms_per_addr = + conn->timeoutms_per_addr[0] = conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2; + conn->timeoutms_per_addr[1] = + conn->tempaddr[1]->ai_next == NULL ? timeout_ms : timeout_ms / 2; conn->tempfamily[0] = conn->tempaddr[0]? conn->tempaddr[0]->ai_family:0; @@ -1443,11 +1455,11 @@ int Curl_closesocket(struct connectdata *conn, curl_socket_t sock) { if(conn && conn->fclosesocket) { - if((sock == conn->sock[SECONDARYSOCKET]) && conn->sock_accepted) + if((sock == conn->sock[SECONDARYSOCKET]) && conn->bits.sock_accepted) /* if this socket matches the second socket, and that was created with accept, then we MUST NOT call the callback but clear the accepted status */ - conn->sock_accepted = FALSE; + conn->bits.sock_accepted = FALSE; else { int rc; Curl_multi_closed(conn->data, sock); @@ -1477,7 +1489,7 @@ int Curl_closesocket(struct connectdata *conn, * */ CURLcode Curl_socket(struct connectdata *conn, - const Curl_addrinfo *ai, + const struct Curl_addrinfo *ai, struct Curl_sockaddr_ex *addr, curl_socket_t *sockfd) { @@ -1559,6 +1571,7 @@ void Curl_conncontrol(struct connectdata *conn, /* close if a connection, or a stream that isn't multiplexed */ bool closeit = (ctrl == CONNCTRL_CONNECTION) || ((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM)); + DEBUGASSERT(conn); if((ctrl == CONNCTRL_STREAM) && (conn->handler->flags & PROTOPT_STREAM)) DEBUGF(infof(conn->data, "Kill stream: %s\n", reason)); @@ -1574,6 +1587,7 @@ void Curl_conncontrol(struct connectdata *conn, bool Curl_conn_data_pending(struct connectdata *conn, int sockindex) { int readable; + DEBUGASSERT(conn); if(Curl_ssl_data_pending(conn, sockindex) || Curl_recv_has_postponed_data(conn, sockindex)) |