ngtcp2: let verify failures win over expiry processing errors

A flaky CI failure of `test_17_05_bad_ip_addr[h3]` (GnuTLS, event-based)
had curl detect the certificate name mismatch yet exit with
`CURLE_RECV_ERROR` (56) instead of `CURLE_PEER_FAILED_VERIFICATION`
(60). `Curl_cf_ngtcp2_cmn_connect` calls `Curl_cf_ngtcp2_cmn_set_expiry`
after its `ctx->tls_vrfy_result` override and returns the error
unfiltered, so when the server's final handshake flight happens to be
processed by the ingress inside set_expiry, the verify failure surfaces
as a generic receive error.

This PR makes set_expiry prefer `ctx->tls_vrfy_result` over generic
progress errors, as the recv and send paths already do after calling it,
and also covers the `cf-ngtcp2-proxy.c` call sites that lack the
override. Completes #21712. Seen in
https://github.com/curl/curl/actions/runs/29243256619/job/86794119412.

Closes #22317
This commit is contained in:
Graham Campbell 2026-07-14 01:37:41 +01:00 committed by Viktor Szakats
parent 8b5f1809bd
commit b8c061c751
No known key found for this signature in database

View file

@ -1750,11 +1750,14 @@ CURLcode Curl_cf_ngtcp2_cmn_set_expiry(struct Curl_cfilter *cf,
return CURLE_SEND_ERROR;
}
result = Curl_cf_ngtcp2_progress_ingress(cf, data, pktx);
if(result)
return result;
result = Curl_cf_ngtcp2_progress_egress(cf, data, pktx);
if(result)
if(!result)
result = Curl_cf_ngtcp2_progress_egress(cf, data, pktx);
if(result) {
/* a verify failure during ingress must win over generic errors */
if(ctx->tls_vrfy_result)
result = ctx->tls_vrfy_result;
return result;
}
/* ask again, things might have changed */
expiry = ngtcp2_conn_get_expiry(ctx->qconn);
}