filter: change time reporting

Replace the QUERY filter methods for connect and appconnect time with a
new control CF_CTRL_REPORT_STATS that is triggered when a connect ends
(successful or not).

Filters in the connection can then report their statistics. Socket and
TLS filters do this only once. Subsequent CF_CTRL_REPORT_STATS will do
nothing.

This prevents timers to be reported twice in STARTTLS scenarios.

Fixes #22587 (again)
Closes #22596
This commit is contained in:
Stefan Eissing 2026-08-15 17:14:41 +02:00 committed by Daniel Stenberg
parent a01a24deaf
commit 406edd036a
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
14 changed files with 187 additions and 149 deletions

View file

@ -988,6 +988,7 @@ struct cf_socket_ctx {
BIT(accepted); /* socket was accepted, not connected */
BIT(sock_connected); /* socket is "connected", e.g. in UDP */
BIT(active);
BIT(stats_reported);
};
static CURLcode cf_socket_ctx_init(struct cf_socket_ctx *ctx,
@ -1729,6 +1730,26 @@ static CURLcode cf_socket_cntrl(struct Curl_cfilter *cf,
case CF_CTRL_FORGET_SOCKET:
ctx->sock = CURL_SOCKET_BAD;
break;
case CF_CTRL_REPORT_STATS:
if(cf->connected && !ctx->stats_reported) {
struct curltime *ts = NULL;
switch(ctx->transport) {
case TRNSPRT_UDP:
case TRNSPRT_QUIC:
/* Since UDP connected sockets work different from TCP, we use the
* time of the first byte from the peer as the "connect" time. */
if(ctx->got_first_byte)
ts = &ctx->first_byte_at;
break;
default:
ts = &ctx->connected_at;
break;
}
if(ts) {
Curl_pgrsTimeWas(data, TIMER_CONNECT, *ts);
ctx->stats_reported = TRUE;
}
}
}
return CURLE_OK;
}
@ -1799,24 +1820,6 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf,
else
*pres1 = -1;
return CURLE_OK;
case CF_QUERY_TIMER_CONNECT: {
struct curltime *when = pres2;
switch(ctx->transport) {
case TRNSPRT_UDP:
case TRNSPRT_QUIC:
/* Since UDP connected sockets work different from TCP, we use the
* time of the first byte from the peer as the "connect" time. */
if(ctx->got_first_byte) {
*when = ctx->first_byte_at;
break;
}
FALLTHROUGH();
default:
*when = ctx->connected_at;
break;
}
return CURLE_OK;
}
case CF_QUERY_IP_INFO:
#ifdef USE_IPV6
*pres1 = (ctx->addr.family == AF_INET6);
@ -1825,6 +1828,12 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf,
#endif
*(struct ip_quadruple *)pres2 = ctx->ip;
return CURLE_OK;
case CF_QUERY_REALLY_CONNECTED:
if(cf->cft != &Curl_cft_udp)
*pres1 = cf->connected;
else
*pres1 = ctx->got_first_byte;
return CURLE_OK;
default:
break;
}