lib: keep conn IP information together

new struct ip_quadruple for holding local/remote addr+port

- used in data->info and conn and cf-socket.c
- copy back and forth complete struct
- add 'secondary' to conn
- use secondary in reporting success for ftp 2nd connection

Reported-by: DasKutti on github
Fixes #13084
Closes #13090
This commit is contained in:
Stefan Eissing 2024-03-08 10:45:14 +01:00 committed by Daniel Stenberg
parent 1ccf1cd993
commit fcef00db1a
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
20 changed files with 148 additions and 200 deletions

View file

@ -1002,9 +1002,9 @@ ConnectionExists(struct Curl_easy *data,
if(!canmultiplex) {
if(Curl_resolver_asynch() &&
/* primary_ip[0] is NUL only if the resolving of the name hasn't
/* remote_ip[0] is NUL only if the resolving of the name hasn't
completed yet and until then we don't reuse this connection */
!check->primary_ip[0])
!check->primary.remote_ip[0])
continue;
}
@ -1327,11 +1327,15 @@ ConnectionExists(struct Curl_easy *data,
*/
#ifndef CURL_DISABLE_VERBOSE_STRINGS
void Curl_verboseconnect(struct Curl_easy *data,
struct connectdata *conn)
struct connectdata *conn, int sockindex)
{
if(data->set.verbose)
if(data->set.verbose && sockindex == SECONDARYSOCKET)
infof(data, "Connected 2nd connection to %s port %u",
conn->secondary.remote_ip, conn->secondary.remote_port);
else
infof(data, "Connected to %s (%s) port %u",
CURL_CONN_HOST_DISPNAME(conn), conn->primary_ip, conn->port);
CURL_CONN_HOST_DISPNAME(conn), conn->primary.remote_ip,
conn->primary.remote_port);
}
#endif
@ -1351,7 +1355,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->sockfd = CURL_SOCKET_BAD;
conn->writesockfd = CURL_SOCKET_BAD;
conn->connection_id = -1; /* no ID */
conn->port = -1; /* unknown at this point */
conn->primary.remote_port = -1; /* unknown at this point */
conn->remote_port = -1; /* unknown at this point */
/* Default protocol-independent behavior doesn't support persistent
@ -1964,7 +1968,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
}
else {
unsigned long port = strtoul(data->state.up.port, NULL, 10);
conn->port = conn->remote_port =
conn->primary.remote_port = conn->remote_port =
(data->set.use_port && data->state.allow_port) ?
data->set.use_port : curlx_ultous(port);
}
@ -2040,10 +2044,10 @@ static CURLcode setup_connection_internals(struct Curl_easy *data,
p = conn->handler; /* May have changed. */
}
if(conn->port < 0)
if(conn->primary.remote_port < 0)
/* we check for -1 here since if proxy was detected already, this
was very likely already set to the proxy port */
conn->port = p->defport;
conn->primary.remote_port = p->defport;
return CURLE_OK;
}
@ -2289,8 +2293,9 @@ static CURLcode parse_proxy(struct Curl_easy *data,
}
if(port >= 0) {
proxyinfo->port = port;
if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc)
conn->port = port;
if(conn->primary.remote_port < 0 || sockstype ||
!conn->socks_proxy.host.rawalloc)
conn->primary.remote_port = port;
}
/* now, clone the proxy host name */
@ -3188,8 +3193,8 @@ static CURLcode resolve_proxy(struct Curl_easy *data,
if(!conn->hostname_resolve)
return CURLE_OUT_OF_MEMORY;
rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
&hostaddr, timeout_ms);
rc = Curl_resolv_timeout(data, conn->hostname_resolve,
conn->primary.remote_port, &hostaddr, timeout_ms);
conn->dns_entry = hostaddr;
if(rc == CURLRESOLV_PENDING)
*async = TRUE;
@ -3219,7 +3224,7 @@ static CURLcode resolve_host(struct Curl_easy *data,
/* If not connecting via a proxy, extract the port from the URL, if it is
* there, thus overriding any defaults that might have been set above. */
conn->port = conn->bits.conn_to_port ? conn->conn_to_port :
conn->primary.remote_port = conn->bits.conn_to_port ? conn->conn_to_port :
conn->remote_port;
/* Resolve target host right on */
@ -3227,8 +3232,8 @@ static CURLcode resolve_host(struct Curl_easy *data,
if(!conn->hostname_resolve)
return CURLE_OUT_OF_MEMORY;
rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
&hostaddr, timeout_ms);
rc = Curl_resolv_timeout(data, conn->hostname_resolve,
conn->primary.remote_port, &hostaddr, timeout_ms);
conn->dns_entry = hostaddr;
if(rc == CURLRESOLV_PENDING)
*async = TRUE;
@ -3565,7 +3570,7 @@ static CURLcode create_conn(struct Curl_easy *data,
/* this is supposed to be the connect function so we better at least check
that the file is present here! */
DEBUGASSERT(conn->handler->connect_it);
Curl_persistconninfo(data, conn, NULL, -1);
Curl_persistconninfo(data, conn, NULL);
result = conn->handler->connect_it(data, &done);
/* Setup a "faked" transfer that'll do nothing */