summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/connect.c
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2021-02-07 18:49:47 +0300
committerdartraiden <wowemuh@gmail.com>2021-02-07 18:49:47 +0300
commit2f0eaffffe7e5d3ac074797f880480494dbcc6f3 (patch)
tree161fa6a6df8387d618530a684de9f61f58640596 /libs/libcurl/src/connect.c
parent061f5621d3f64835c376a7781af86a5e5ee1145c (diff)
libcurl: update to 7.75.0
Diffstat (limited to 'libs/libcurl/src/connect.c')
-rw-r--r--libs/libcurl/src/connect.c236
1 files changed, 139 insertions, 97 deletions
diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c
index e65d24d9e9..baab1840e1 100644
--- a/libs/libcurl/src/connect.c
+++ b/libs/libcurl/src/connect.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -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 */
@@ -256,6 +256,9 @@ static CURLcode bindlocal(struct connectdata *conn,
int portnum = data->set.localportrange;
const char *dev = data->set.str[STRING_DEVICE];
int error;
+#ifdef IP_BIND_ADDRESS_NO_PORT
+ int on = 1;
+#endif
/*************************************************************
* Select device to bind socket to
@@ -345,7 +348,7 @@ static CURLcode bindlocal(struct connectdata *conn,
* of the connection. The resolve functions should really be changed
* to take a type parameter instead.
*/
- long ipver = conn->ip_version;
+ unsigned char ipver = conn->ip_version;
int rc;
if(af == AF_INET)
@@ -355,9 +358,9 @@ static CURLcode bindlocal(struct connectdata *conn,
conn->ip_version = CURL_IPRESOLVE_V6;
#endif
- rc = Curl_resolv(conn, dev, 0, FALSE, &h);
+ rc = Curl_resolv(data, dev, 0, FALSE, &h);
if(rc == CURLRESOLV_PENDING)
- (void)Curl_resolver_wait_resolv(conn, &h);
+ (void)Curl_resolver_wait_resolv(data, &h);
conn->ip_version = ipver;
if(h) {
@@ -441,7 +444,9 @@ static CURLcode bindlocal(struct connectdata *conn,
sizeof_sa = sizeof(struct sockaddr_in);
}
}
-
+#ifdef IP_BIND_ADDRESS_NO_PORT
+ (void)setsockopt(sockfd, SOL_IP, IP_BIND_ADDRESS_NO_PORT, &on, sizeof(on));
+#endif
for(;;) {
if(bind(sockfd, sock, sizeof_sa) >= 0) {
/* we succeeded to bind */
@@ -568,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)
{
@@ -586,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;
@@ -597,21 +603,25 @@ 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,
+ char *local_ip, long local_port)
{
- 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);
+ if(local_ip && local_ip[0])
+ memcpy(data->info.conn_local_ip, local_ip, MAX_IPADR_LEN);
+ else
+ data->info.conn_local_ip[0] = 0;
+ data->info.conn_scheme = conn->handler->scheme;
+ data->info.conn_protocol = conn->handler->protocol;
+ data->info.conn_primary_port = conn->port;
+ data->info.conn_local_port = local_port;
}
/* retrieves ip address and port from a sockaddr structure.
@@ -673,27 +683,30 @@ 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];
struct Curl_sockaddr_storage ssrem;
curl_socklen_t plen;
+ long port;
plen = sizeof(struct Curl_sockaddr_storage);
+ 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",
+ conn->primary_ip, &port)) {
+ 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
@@ -701,7 +714,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, curl_socket_t sockfd,
+ char *local_ip, long *local_port)
{
#ifdef HAVE_GETSOCKNAME
char buffer[STRERROR_LEN];
@@ -711,35 +725,44 @@ 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",
+ local_ip, local_port)) {
+ failf(data, "ssloc inet_ntop() failed with errno %d: %s",
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
return;
}
#else
- (void)conn;
+ (void)data;
(void)sockfd;
+ (void)local_ip;
+ (void)local_port;
#endif
}
/* 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)
{
+ /* 'local_ip' and 'local_port' get filled with local's numerical
+ 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;
+
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, sockfd, local_ip, &local_port);
}
} /* end of TCP-only section */
/* persist connection info in session handle */
- Curl_persistconninfo(conn);
+ Curl_persistconninfo(data, conn, local_ip, local_port);
}
/* After a TCP connection to the proxy has been verified, this function does
@@ -749,12 +772,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)
@@ -775,27 +799,27 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
case CURLPROXY_SOCKS5:
case CURLPROXY_SOCKS5_HOSTNAME:
pxresult = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
- host, port, sockindex, conn, done);
+ host, port, sockindex, data, done);
break;
case CURLPROXY_SOCKS4:
case CURLPROXY_SOCKS4A:
pxresult = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
- conn, done);
+ data, done);
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 */
@@ -807,7 +831,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)
{
@@ -815,21 +840,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;
@@ -860,9 +885,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;
}
@@ -873,13 +898,13 @@ CURLcode Curl_is_connected(struct connectdata *conn,
error = 0;
#ifdef ENABLE_QUIC
if(conn->transport == TRNSPRT_QUIC) {
- result = Curl_quic_is_connected(conn, i, connected);
+ result = Curl_quic_is_connected(data, conn, i, 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);
+ post_SOCKS(data, conn, sockindex, connected);
connkeep(conn, "HTTP/3 default");
return CURLE_OK;
}
@@ -914,7 +939,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) {
@@ -931,17 +956,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;
}
@@ -972,7 +997,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 */
@@ -990,7 +1015,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;
@@ -1010,8 +1035,8 @@ 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);
+ Curl_quic_disconnect(data, conn, 0);
+ Curl_quic_disconnect(data, conn, 1);
#ifdef WSAETIMEDOUT
if(WSAETIMEDOUT == data->state.os_errno)
@@ -1027,16 +1052,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,
@@ -1044,7 +1068,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
}
@@ -1054,10 +1078,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) {
@@ -1123,7 +1146,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)
{
@@ -1131,7 +1155,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];
@@ -1144,7 +1167,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;
@@ -1154,7 +1177,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);
@@ -1166,9 +1189,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);
@@ -1186,7 +1209,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;
}
}
@@ -1197,10 +1220,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 */
@@ -1268,7 +1291,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
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, tempindex,
+ result = Curl_quic_connect(data, conn, sockfd, tempindex,
&addr.sa_addr, addr.addrlen);
if(result)
error = SOCKERRNO;
@@ -1303,7 +1326,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;
}
}
@@ -1320,10 +1343,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);
@@ -1361,7 +1384,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);
@@ -1370,7 +1393,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;
@@ -1381,9 +1404,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;
@@ -1465,8 +1490,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)
@@ -1476,17 +1501,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);
@@ -1502,12 +1527,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)
@@ -1568,8 +1593,21 @@ CURLcode Curl_socket(struct connectdata *conn,
}
#endif
- return CURLE_OK;
+#if defined(__linux__) && defined(IP_RECVERR)
+ if(addr->socktype == SOCK_DGRAM) {
+ int one = 1;
+ switch(addr->family) {
+ case AF_INET:
+ (void)setsockopt(*sockfd, SOL_IP, IP_RECVERR, &one, sizeof(one));
+ break;
+ case AF_INET6:
+ (void)setsockopt(*sockfd, SOL_IPV6, IPV6_RECVERR, &one, sizeof(one));
+ break;
+ }
+ }
+#endif
+ return CURLE_OK;
}
/*
@@ -1582,16 +1620,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 */
}