summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/connect.c')
-rw-r--r--libs/libcurl/src/connect.c124
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))