diff options
Diffstat (limited to 'Utilities/cmcurl/lib/connect.c')
-rw-r--r-- | Utilities/cmcurl/lib/connect.c | 129 |
1 files changed, 72 insertions, 57 deletions
diff --git a/Utilities/cmcurl/lib/connect.c b/Utilities/cmcurl/lib/connect.c index baab184..d9317f3 100644 --- a/Utilities/cmcurl/lib/connect.c +++ b/Utilities/cmcurl/lib/connect.c @@ -171,65 +171,63 @@ singleipconnect(struct Curl_easy *data, * infinite time left). If the value is negative, the timeout time has already * elapsed. * - * The start time is stored in progress.t_startsingle - as set with - * Curl_pgrsTime(..., TIMER_STARTSINGLE); - * * If 'nowp' is non-NULL, it points to the current time. * 'duringconnect' is FALSE if not during a connect, as then of course the * connect timeout is not taken into account! * * @unittest: 1303 */ + +#define TIMEOUT_CONNECT 1 +#define TIMEOUT_MAXTIME 2 + timediff_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect) { - int timeout_set = 0; - timediff_t timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0; + unsigned int timeout_set = 0; + timediff_t connect_timeout_ms = 0; + timediff_t maxtime_timeout_ms = 0; + timediff_t timeout_ms = 0; struct curltime now; - /* if a timeout is set, use the most restrictive one */ - - if(data->set.timeout > 0) - timeout_set |= 1; - if(duringconnect && (data->set.connecttimeout > 0)) - timeout_set |= 2; - - switch(timeout_set) { - case 1: - timeout_ms = data->set.timeout; - break; - case 2: - timeout_ms = data->set.connecttimeout; - break; - case 3: - if(data->set.timeout < data->set.connecttimeout) - timeout_ms = data->set.timeout; - else - timeout_ms = data->set.connecttimeout; - break; - default: - /* use the default */ - if(!duringconnect) - /* if we're not during connect, there's no default timeout so if we're - at zero we better just return zero and not make it a negative number - by the math below */ - return 0; - break; + /* The duration of a connect and the total transfer are calculated from two + different time-stamps. It can end up with the total timeout being reached + before the connect timeout expires and we must acknowledge whichever + timeout that is reached first. The total timeout is set per entire + operation, while the connect timeout is set per connect. */ + + if(data->set.timeout > 0) { + timeout_set = TIMEOUT_MAXTIME; + maxtime_timeout_ms = data->set.timeout; + } + if(duringconnect) { + timeout_set |= TIMEOUT_CONNECT; + connect_timeout_ms = (data->set.connecttimeout > 0) ? + data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT; } + if(!timeout_set) + /* no timeout */ + return 0; if(!nowp) { now = Curl_now(); nowp = &now; } - /* subtract elapsed time */ - if(duringconnect) - /* since this most recent connect started */ - timeout_ms -= Curl_timediff(*nowp, data->progress.t_startsingle); - else - /* since the entire operation started */ - timeout_ms -= Curl_timediff(*nowp, data->progress.t_startop); + if(timeout_set & TIMEOUT_MAXTIME) { + maxtime_timeout_ms -= Curl_timediff(*nowp, data->progress.t_startop); + timeout_ms = maxtime_timeout_ms; + } + + if(timeout_set & TIMEOUT_CONNECT) { + connect_timeout_ms -= Curl_timediff(*nowp, data->progress.t_startsingle); + + if(!(timeout_set & TIMEOUT_MAXTIME) || + (connect_timeout_ms < maxtime_timeout_ms)) + timeout_ms = connect_timeout_ms; + } + if(!timeout_ms) /* avoid returning 0 as that means no timeout! */ return -1; @@ -611,7 +609,7 @@ static CURLcode trynextip(struct Curl_easy *data, /* Copies connection info into the transfer handle to make it available when the transfer handle is no longer associated with the connection. */ void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn, - char *local_ip, long local_port) + char *local_ip, int local_port) { memcpy(data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN); if(local_ip && local_ip[0]) @@ -627,7 +625,7 @@ void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn, /* retrieves ip address and port from a sockaddr structure. note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, - char *addr, long *port) + char *addr, int *port) { struct sockaddr_in *si = NULL; #ifdef ENABLE_IPV6 @@ -662,7 +660,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, #endif #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) case AF_UNIX: - if(salen > (curl_socklen_t)sizeof(sa_family_t)) { + if(salen > (curl_socklen_t)sizeof(CURL_SA_FAMILY_T)) { su = (struct sockaddr_un*)sa; msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path); } @@ -690,7 +688,7 @@ void Curl_conninfo_remote(struct Curl_easy *data, char buffer[STRERROR_LEN]; struct Curl_sockaddr_storage ssrem; curl_socklen_t plen; - long port; + int port; plen = sizeof(struct Curl_sockaddr_storage); memset(&ssrem, 0, sizeof(ssrem)); if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) { @@ -715,7 +713,7 @@ void Curl_conninfo_remote(struct Curl_easy *data, /* retrieves the start/end point information of a socket of an established connection */ void Curl_conninfo_local(struct Curl_easy *data, curl_socket_t sockfd, - char *local_ip, long *local_port) + char *local_ip, int *local_port) { #ifdef HAVE_GETSOCKNAME char buffer[STRERROR_LEN]; @@ -752,7 +750,7 @@ void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn, ip address and port number whenever an outgoing connection is **established** from the primary socket to a remote address. */ char local_ip[MAX_IPADR_LEN] = ""; - long local_port = -1; + int local_port = -1; if(conn->transport == TRNSPRT_TCP) { if(!conn->bits.reuse && !conn->bits.tcp_fastopen) { @@ -908,8 +906,10 @@ CURLcode Curl_is_connected(struct Curl_easy *data, connkeep(conn, "HTTP/3 default"); return CURLE_OK; } - if(result) + if(result) { + conn->tempsock[i] = CURL_SOCKET_BAD; error = SOCKERRNO; + } } else #endif @@ -1158,7 +1158,7 @@ static CURLcode singleipconnect(struct Curl_easy *data, curl_socket_t sockfd; CURLcode result; char ipaddress[MAX_IPADR_LEN]; - long port; + int port; bool is_tcp; #ifdef TCP_FASTOPEN_CONNECT int optval = 1; @@ -1180,7 +1180,7 @@ static CURLcode singleipconnect(struct Curl_easy *data, Curl_closesocket(data, conn, sockfd); return CURLE_OK; } - infof(data, " Trying %s:%ld...\n", ipaddress, port); + infof(data, " Trying %s:%d...\n", ipaddress, port); #ifdef ENABLE_IPV6 is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) && @@ -1367,14 +1367,31 @@ CURLcode Curl_connecthost(struct Curl_easy *data, 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; + if(conn->ip_version == CURL_IPRESOLVE_WHATEVER) { + /* any IP version is allowed */ + conn->tempfamily[0] = conn->tempaddr[0]? + conn->tempaddr[0]->ai_family:0; +#ifdef ENABLE_IPV6 + conn->tempfamily[1] = conn->tempfamily[0] == AF_INET6 ? + AF_INET : AF_INET6; +#else + conn->tempfamily[1] = AF_UNSPEC; +#endif + } + else { + /* only one IP version is allowed */ + conn->tempfamily[0] = (conn->ip_version == CURL_IPRESOLVE_V4) ? + AF_INET : #ifdef ENABLE_IPV6 - conn->tempfamily[1] = conn->tempfamily[0] == AF_INET6 ? - AF_INET : AF_INET6; + AF_INET6; #else - conn->tempfamily[1] = AF_UNSPEC; + AF_UNSPEC; #endif + conn->tempfamily[1] = AF_UNSPEC; + + ainext(conn, 0, FALSE); /* find first address of the right type */ + } + ainext(conn, 1, FALSE); /* assigns conn->tempaddr[1] accordingly */ DEBUGF(infof(data, "family0 == %s, family1 == %s\n", @@ -1448,11 +1465,9 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, } c = find.found; - if(connp) { + if(connp) /* only store this if the caller cares for it */ *connp = c; - c->data = data; - } return c->sock[FIRSTSOCKET]; } return CURL_SOCKET_BAD; |