connect: limit update IP info

Update IP related information at the connection and the transfer in two
places only: once the filter chain connects and when a transfer is added
to a connection. The latter only updates on reuse when the filters
already are connected.

The only user of that information before a full connect is the HAProxy
filter. Add cfilter CF_QUERY_IP_INFO query to let it find the
information from the filters "below".

This solves two issues with the previous version:
- updates where often done twice with the same info
- happy eyeballing filter "forks" could overwrite each others
  updates before the full winner was determined.

Closes #14699
This commit is contained in:
Stefan Eissing 2024-08-27 12:12:37 +02:00 committed by Daniel Stenberg
parent 87f0a79439
commit ea6f5c9f0f
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
15 changed files with 122 additions and 77 deletions

View file

@ -70,8 +70,9 @@ static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
{
struct cf_haproxy_ctx *ctx = cf->ctx;
CURLcode result;
const char *tcp_version;
const char *client_ip;
struct ip_quadruple ipquad;
int is_ipv6;
DEBUGASSERT(ctx);
DEBUGASSERT(ctx->state == HAPROXY_INIT);
@ -81,19 +82,20 @@ static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
result = Curl_dyn_addn(&ctx->data_out, STRCONST("PROXY UNKNOWN\r\n"));
else {
#endif /* USE_UNIX_SOCKETS */
result = Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad);
if(result)
return result;
/* Emit the correct prefix for IPv6 */
tcp_version = cf->conn->bits.ipv6 ? "TCP6" : "TCP4";
if(data->set.str[STRING_HAPROXY_CLIENT_IP])
client_ip = data->set.str[STRING_HAPROXY_CLIENT_IP];
else
client_ip = data->info.primary.local_ip;
client_ip = ipquad.local_ip;
result = Curl_dyn_addf(&ctx->data_out, "PROXY %s %s %s %i %i\r\n",
tcp_version,
client_ip,
data->info.primary.remote_ip,
data->info.primary.local_port,
data->info.primary.remote_port);
is_ipv6? "TCP6" : "TCP4",
client_ip, ipquad.remote_ip,
ipquad.local_port, ipquad.remote_port);
#ifdef USE_UNIX_SOCKETS
}