diff options
Diffstat (limited to 'lib/connect.c')
-rw-r--r-- | lib/connect.c | 174 |
1 files changed, 93 insertions, 81 deletions
diff --git a/lib/connect.c b/lib/connect.c index 345b800ee..b0af08445 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -160,7 +160,8 @@ tcpkeepalive(struct Curl_easy *data, } static CURLcode -singleipconnect(struct connectdata *conn, +singleipconnect(struct Curl_easy *data, + struct connectdata *conn, const struct Curl_addrinfo *ai, /* start connecting to this */ int tempindex); /* 0 or 1 among the temp ones */ @@ -236,11 +237,10 @@ timediff_t Curl_timeleft(struct Curl_easy *data, return timeout_ms; } -static CURLcode bindlocal(struct connectdata *conn, +static CURLcode bindlocal(struct Curl_easy *data, curl_socket_t sockfd, int af, unsigned int scope) { - struct Curl_easy *data = conn->data; - + struct connectdata *conn = data->conn; struct Curl_sockaddr_storage sa; struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */ curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */ @@ -573,7 +573,8 @@ static struct Curl_addrinfo *ainext(struct connectdata *conn, /* Used within the multi interface. Try next IP address, returns error if no more address exists or error */ -static CURLcode trynextip(struct connectdata *conn, +static CURLcode trynextip(struct Curl_easy *data, + struct connectdata *conn, int sockindex, int tempindex) { @@ -591,7 +592,7 @@ static CURLcode trynextip(struct connectdata *conn, while(ai) { if(ai) { - result = singleipconnect(conn, ai, tempindex); + result = singleipconnect(data, conn, ai, tempindex); if(result == CURLE_COULDNT_CONNECT) { ai = ainext(conn, tempindex, TRUE); continue; @@ -602,21 +603,21 @@ static CURLcode trynextip(struct connectdata *conn, } if(fd_to_close != CURL_SOCKET_BAD) - Curl_closesocket(conn, fd_to_close); + Curl_closesocket(data, conn, fd_to_close); return result; } -/* Copies connection info into the session handle to make it available - when the session handle is no longer associated with a connection. */ -void Curl_persistconninfo(struct connectdata *conn) +/* 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) { - memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN); - memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN); - conn->data->info.conn_scheme = conn->handler->scheme; - conn->data->info.conn_protocol = conn->handler->protocol; - conn->data->info.conn_primary_port = conn->primary_port; - conn->data->info.conn_local_port = conn->local_port; + memcpy(data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN); + memcpy(data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN); + data->info.conn_scheme = conn->handler->scheme; + data->info.conn_protocol = conn->handler->protocol; + data->info.conn_primary_port = conn->primary_port; + data->info.conn_local_port = conn->local_port; } /* retrieves ip address and port from a sockaddr structure. @@ -678,7 +679,8 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, /* retrieves the start/end point information of a socket of an established connection */ -void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd) +void Curl_conninfo_remote(struct Curl_easy *data, + struct connectdata *conn, curl_socket_t sockfd) { #ifdef HAVE_GETPEERNAME char buffer[STRERROR_LEN]; @@ -688,18 +690,19 @@ void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd) memset(&ssrem, 0, sizeof(ssrem)); if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) { int error = SOCKERRNO; - failf(conn->data, "getpeername() failed with errno %d: %s", + failf(data, "getpeername() failed with errno %d: %s", error, Curl_strerror(error, buffer, sizeof(buffer))); return; } if(!Curl_addr2string((struct sockaddr*)&ssrem, plen, conn->primary_ip, &conn->primary_port)) { - failf(conn->data, "ssrem inet_ntop() failed with errno %d: %s", + failf(data, "ssrem inet_ntop() failed with errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); return; } memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); #else + (void)data; (void)conn; (void)sockfd; #endif @@ -707,7 +710,8 @@ void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd) /* retrieves the start/end point information of a socket of an established connection */ -void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd) +void Curl_conninfo_local(struct Curl_easy *data, struct connectdata *conn, + curl_socket_t sockfd) { #ifdef HAVE_GETSOCKNAME char buffer[STRERROR_LEN]; @@ -717,17 +721,18 @@ void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd) memset(&ssloc, 0, sizeof(ssloc)); if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) { int error = SOCKERRNO; - failf(conn->data, "getsockname() failed with errno %d: %s", + failf(data, "getsockname() failed with errno %d: %s", error, Curl_strerror(error, buffer, sizeof(buffer))); return; } if(!Curl_addr2string((struct sockaddr*)&ssloc, slen, conn->local_ip, &conn->local_port)) { - failf(conn->data, "ssloc inet_ntop() failed with errno %d: %s", + failf(data, "ssloc inet_ntop() failed with errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); return; } #else + (void)data; (void)conn; (void)sockfd; #endif @@ -735,17 +740,18 @@ void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd) /* retrieves the start/end point information of a socket of an established connection */ -void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) +void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn, + curl_socket_t sockfd) { if(conn->transport == TRNSPRT_TCP) { if(!conn->bits.reuse && !conn->bits.tcp_fastopen) { - Curl_conninfo_remote(conn, sockfd); - Curl_conninfo_local(conn, sockfd); + Curl_conninfo_remote(data, conn, sockfd); + Curl_conninfo_local(data, conn, sockfd); } } /* end of TCP-only section */ /* persist connection info in session handle */ - Curl_persistconninfo(conn); + Curl_persistconninfo(data, conn); } /* After a TCP connection to the proxy has been verified, this function does @@ -755,12 +761,13 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) Note: this function's sub-functions call failf() */ -static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex, +static CURLcode connect_SOCKS(struct Curl_easy *data, int sockindex, bool *done) { CURLcode result = CURLE_OK; #ifndef CURL_DISABLE_PROXY CURLproxycode pxresult = CURLPX_OK; + struct connectdata *conn = data->conn; if(conn->bits.socksproxy) { /* for the secondary socket (FTP), use the "connect to host" * but ignore the "connect to port" (use the secondary port) @@ -791,17 +798,17 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex, break; default: - failf(conn->data, "unknown proxytype option given"); + failf(data, "unknown proxytype option given"); result = CURLE_COULDNT_CONNECT; } /* switch proxytype */ if(pxresult) { result = CURLE_PROXY; - conn->data->info.pxcode = pxresult; + data->info.pxcode = pxresult; } } else #else - (void)conn; + (void)data; (void)sockindex; #endif /* CURL_DISABLE_PROXY */ *done = TRUE; /* no SOCKS proxy, so consider us connected */ @@ -813,7 +820,8 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex, * post_SOCKS() is called after a successful connect to the peer, which * *could* be a SOCKS proxy */ -static void post_SOCKS(struct connectdata *conn, +static void post_SOCKS(struct Curl_easy *data, + struct connectdata *conn, int sockindex, bool *connected) { @@ -821,21 +829,21 @@ static void post_SOCKS(struct connectdata *conn, *connected = TRUE; if(sockindex == FIRSTSOCKET) - Curl_pgrsTime(conn->data, TIMER_CONNECT); /* connect done */ - Curl_updateconninfo(conn, conn->sock[sockindex]); - Curl_verboseconnect(conn); - conn->data->info.numconnects++; /* to track the number of connections made */ + Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ + Curl_updateconninfo(data, conn, conn->sock[sockindex]); + Curl_verboseconnect(data, conn); + data->info.numconnects++; /* to track the number of connections made */ } /* * Curl_is_connected() checks if the socket has connected. */ -CURLcode Curl_is_connected(struct connectdata *conn, +CURLcode Curl_is_connected(struct Curl_easy *data, + struct connectdata *conn, int sockindex, bool *connected) { - struct Curl_easy *data = conn->data; CURLcode result = CURLE_OK; timediff_t allow; int error = 0; @@ -866,9 +874,9 @@ CURLcode Curl_is_connected(struct connectdata *conn, if(SOCKS_STATE(conn->cnnct.state)) { /* still doing SOCKS */ - result = connect_SOCKS(conn, sockindex, connected); + result = connect_SOCKS(data, sockindex, connected); if(!result && *connected) - post_SOCKS(conn, sockindex, connected); + post_SOCKS(data, conn, sockindex, connected); return result; } @@ -885,7 +893,7 @@ CURLcode Curl_is_connected(struct connectdata *conn, conn->sock[sockindex] = conn->tempsock[i]; conn->ip_addr = conn->tempaddr[i]; conn->tempsock[i] = CURL_SOCKET_BAD; - post_SOCKS(conn, sockindex, connected); + post_SOCKS(data, conn, sockindex, connected); connkeep(conn, "HTTP/3 default"); return CURLE_OK; } @@ -920,7 +928,7 @@ CURLcode Curl_is_connected(struct connectdata *conn, (Curl_timediff(now, conn->connecttime) >= data->set.happy_eyeballs_timeout)) { conn->bits.parallel_connect = TRUE; /* starting now */ - trynextip(conn, sockindex, 1); + trynextip(data, conn, sockindex, 1); } } else if(rc == CURL_CSELECT_OUT || conn->bits.tcp_fastopen) { @@ -937,17 +945,17 @@ CURLcode Curl_is_connected(struct connectdata *conn, /* close the other socket, if open */ if(conn->tempsock[other] != CURL_SOCKET_BAD) { - Curl_closesocket(conn, conn->tempsock[other]); + Curl_closesocket(data, conn, conn->tempsock[other]); conn->tempsock[other] = CURL_SOCKET_BAD; } /* see if we need to kick off any SOCKS proxy magic once we connected */ - result = connect_SOCKS(conn, sockindex, connected); + result = connect_SOCKS(data, sockindex, connected); if(result || !*connected) return result; - post_SOCKS(conn, sockindex, connected); + post_SOCKS(data, conn, sockindex, connected); return CURLE_OK; } @@ -978,7 +986,7 @@ CURLcode Curl_is_connected(struct connectdata *conn, conn->timeoutms_per_addr[i] = conn->tempaddr[i]->ai_next == NULL ? allow : allow / 2; ainext(conn, i, TRUE); - status = trynextip(conn, sockindex, i); + status = trynextip(data, conn, sockindex, i); if((status != CURLE_COULDNT_CONNECT) || conn->tempsock[other] == CURL_SOCKET_BAD) /* the last attempt failed and no other sockets remain open */ @@ -996,7 +1004,7 @@ CURLcode Curl_is_connected(struct connectdata *conn, /* 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); + result = trynextip(data, conn, sockindex, 1); if(!result) return result; @@ -1033,16 +1041,15 @@ CURLcode Curl_is_connected(struct connectdata *conn, return result; } -static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) +static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd) { #if defined(TCP_NODELAY) curl_socklen_t onoff = (curl_socklen_t) 1; int level = IPPROTO_TCP; #if !defined(CURL_DISABLE_VERBOSE_STRINGS) - struct Curl_easy *data = conn->data; char buffer[STRERROR_LEN]; #else - (void) conn; + (void) data; #endif if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff, @@ -1050,7 +1057,7 @@ static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) infof(data, "Could not set TCP_NODELAY: %s\n", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); #else - (void)conn; + (void)data; (void)sockfd; #endif } @@ -1060,10 +1067,9 @@ static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) sending data to a dead peer (instead of relying on the 4th argument to send being MSG_NOSIGNAL). Possibly also existing and in use on other BSD systems? */ -static void nosigpipe(struct connectdata *conn, +static void nosigpipe(struct Curl_easy *data, curl_socket_t sockfd) { - struct Curl_easy *data = conn->data; int onoff = 1; if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff, sizeof(onoff)) < 0) { @@ -1129,7 +1135,8 @@ void Curl_sndbufset(curl_socket_t sockfd) * singleipconnect() connects to the given IP only, and it may return without * having connected. */ -static CURLcode singleipconnect(struct connectdata *conn, +static CURLcode singleipconnect(struct Curl_easy *data, + struct connectdata *conn, const struct Curl_addrinfo *ai, int tempindex) { @@ -1137,7 +1144,6 @@ static CURLcode singleipconnect(struct connectdata *conn, int rc = -1; int error = 0; bool isconnected = FALSE; - struct Curl_easy *data = conn->data; curl_socket_t sockfd; CURLcode result; char ipaddress[MAX_IPADR_LEN]; @@ -1150,7 +1156,7 @@ static CURLcode singleipconnect(struct connectdata *conn, curl_socket_t *sockp = &conn->tempsock[tempindex]; *sockp = CURL_SOCKET_BAD; - result = Curl_socket(conn, ai, &addr, &sockfd); + result = Curl_socket(data, ai, &addr, &sockfd); if(result) return result; @@ -1160,7 +1166,7 @@ static CURLcode singleipconnect(struct connectdata *conn, /* malformed address or bug in inet_ntop, try next address */ failf(data, "sa_addr inet_ntop() failed with errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); - Curl_closesocket(conn, sockfd); + Curl_closesocket(data, conn, sockfd); return CURLE_OK; } infof(data, " Trying %s:%ld...\n", ipaddress, port); @@ -1172,9 +1178,9 @@ static CURLcode singleipconnect(struct connectdata *conn, is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM; #endif if(is_tcp && data->set.tcp_nodelay) - tcpnodelay(conn, sockfd); + tcpnodelay(data, sockfd); - nosigpipe(conn, sockfd); + nosigpipe(data, sockfd); Curl_sndbufset(sockfd); @@ -1192,7 +1198,7 @@ static CURLcode singleipconnect(struct connectdata *conn, if(error == CURL_SOCKOPT_ALREADY_CONNECTED) isconnected = TRUE; else if(error) { - Curl_closesocket(conn, sockfd); /* close the socket and bail out */ + Curl_closesocket(data, conn, sockfd); /* close the socket and bail out */ return CURLE_ABORTED_BY_CALLBACK; } } @@ -1203,10 +1209,10 @@ static CURLcode singleipconnect(struct connectdata *conn, || addr.family == AF_INET6 #endif ) { - result = bindlocal(conn, sockfd, addr.family, + result = bindlocal(data, sockfd, addr.family, Curl_ipv6_scope((struct sockaddr*)&addr.sa_addr)); if(result) { - Curl_closesocket(conn, sockfd); /* close socket and bail out */ + Curl_closesocket(data, conn, sockfd); /* close socket and bail out */ if(result == CURLE_UNSUPPORTED_PROTOCOL) { /* The address family is not supported on this interface. We can continue trying addresses */ @@ -1309,7 +1315,7 @@ static CURLcode singleipconnect(struct connectdata *conn, data->state.os_errno = error; /* connect failed */ - Curl_closesocket(conn, sockfd); + Curl_closesocket(data, conn, sockfd); result = CURLE_COULDNT_CONNECT; } } @@ -1326,10 +1332,10 @@ static CURLcode singleipconnect(struct connectdata *conn, * pointer with the connected socket. */ -CURLcode Curl_connecthost(struct connectdata *conn, /* context */ +CURLcode Curl_connecthost(struct Curl_easy *data, + struct connectdata *conn, /* context */ const struct Curl_dns_entry *remotehost) { - struct Curl_easy *data = conn->data; CURLcode result = CURLE_COULDNT_CONNECT; int i; timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); @@ -1367,7 +1373,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ /* get through the list in family order in case of quick failures */ for(i = 0; (i < 2) && result; i++) { while(conn->tempaddr[i]) { - result = singleipconnect(conn, conn->tempaddr[i], i); + result = singleipconnect(data, conn, conn->tempaddr[i], i); if(!result) break; ainext(conn, i, TRUE); @@ -1376,7 +1382,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ if(result) return result; - Curl_expire(conn->data, data->set.happy_eyeballs_timeout, + Curl_expire(data, data->set.happy_eyeballs_timeout, EXPIRE_HAPPY_EYEBALLS); return CURLE_OK; @@ -1387,9 +1393,11 @@ struct connfind { struct connectdata *found; }; -static int conn_is_conn(struct connectdata *conn, void *param) +static int conn_is_conn(struct Curl_easy *data, + struct connectdata *conn, void *param) { struct connfind *f = (struct connfind *)param; + (void)data; if(conn->connection_id == f->id_tofind) { f->found = conn; return 1; @@ -1471,8 +1479,8 @@ bool Curl_connalive(struct connectdata *conn) * * 'conn' can be NULL, beware! */ -int Curl_closesocket(struct connectdata *conn, - curl_socket_t sock) +int Curl_closesocket(struct Curl_easy *data, struct connectdata *conn, + curl_socket_t sock) { if(conn && conn->fclosesocket) { if((sock == conn->sock[SECONDARYSOCKET]) && conn->bits.sock_accepted) @@ -1482,17 +1490,17 @@ int Curl_closesocket(struct connectdata *conn, conn->bits.sock_accepted = FALSE; else { int rc; - Curl_multi_closed(conn->data, sock); - Curl_set_in_callback(conn->data, true); + Curl_multi_closed(data, sock); + Curl_set_in_callback(data, true); rc = conn->fclosesocket(conn->closesocket_client, sock); - Curl_set_in_callback(conn->data, false); + Curl_set_in_callback(data, false); return rc; } } if(conn) /* tell the multi-socket code about this */ - Curl_multi_closed(conn->data, sock); + Curl_multi_closed(data, sock); sclose(sock); @@ -1508,12 +1516,12 @@ int Curl_closesocket(struct connectdata *conn, * If the open socket callback is set, used that! * */ -CURLcode Curl_socket(struct connectdata *conn, +CURLcode Curl_socket(struct Curl_easy *data, const struct Curl_addrinfo *ai, struct Curl_sockaddr_ex *addr, curl_socket_t *sockfd) { - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; struct Curl_sockaddr_ex dummy; if(!addr) @@ -1601,16 +1609,20 @@ void Curl_conncontrol(struct connectdata *conn, #endif ) { - /* close if a connection, or a stream that isn't multiplexed */ - bool closeit = (ctrl == CONNCTRL_CONNECTION) || - ((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM)); + /* close if a connection, or a stream that isn't multiplexed. */ + /* This function will be called both before and after this connection is + associated with a transfer. */ + bool closeit; DEBUGASSERT(conn); +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + (void)reason; /* useful for debugging */ +#endif + closeit = (ctrl == CONNCTRL_CONNECTION) || + ((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM)); if((ctrl == CONNCTRL_STREAM) && (conn->handler->flags & PROTOPT_STREAM)) - DEBUGF(infof(conn->data, "Kill stream: %s\n", reason)); + ; else if((bit)closeit != conn->bits.close) { - DEBUGF(infof(conn->data, "Marked for [%s]: %s\n", - closeit?"closure":"keep alive", reason)); conn->bits.close = closeit; /* the only place in the source code that should assign this bit */ } |