]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
ngtcp2: fix handling of blocked stream data
authorStefan Eissing <stefan@eissing.org>
Tue, 7 Oct 2025 09:30:46 +0000 (11:30 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 7 Oct 2025 15:24:01 +0000 (17:24 +0200)
The stream blocking might not be the one of the current easy handle.
Look up the stream to be marked as blocking via its stream_id in the
internal hash. Theoretically, this does not have to be one of the h3
streams, so not finding it is not an error.

Fixes #18905
Reported-by: Joshua Rogers
Closes #18906

lib/vquic/curl_ngtcp2.c

index af7f26eb3988028a5fdabcbf74ab14203861c0af..b48d1af555ac6d848027d1ee4c7c0b8c56e9ae73 100644 (file)
@@ -300,6 +300,35 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
   return CURLE_OK;
 }
 
+struct cf_ngtcp2_sfind_ctx {
+  curl_int64_t stream_id;
+  struct h3_stream_ctx *stream;
+  unsigned int mid;
+};
+
+static bool cf_ngtcp2_sfind(unsigned int mid, void *value, void *user_data)
+{
+  struct cf_ngtcp2_sfind_ctx *fctx = user_data;
+  struct h3_stream_ctx *stream = value;
+
+  if(fctx->stream_id == stream->id) {
+    fctx->mid = mid;
+    fctx->stream = stream;
+    return FALSE;
+  }
+  return TRUE; /* continue */
+}
+
+static struct h3_stream_ctx *
+cf_ngtcp2_get_stream(struct cf_ngtcp2_ctx *ctx, curl_int64_t stream_id)
+{
+  struct cf_ngtcp2_sfind_ctx fctx;
+  fctx.stream_id = stream_id;
+  fctx.stream = NULL;
+  Curl_uint_hash_visit(&ctx->streams, cf_ngtcp2_sfind, &fctx);
+  return fctx.stream;
+}
+
 static void cf_ngtcp2_stream_close(struct Curl_cfilter *cf,
                                    struct Curl_easy *data,
                                    struct h3_stream_ctx *stream)
@@ -1808,13 +1837,13 @@ static CURLcode read_pkt_to_send(void *userp,
     else if(n < 0) {
       switch(n) {
       case NGTCP2_ERR_STREAM_DATA_BLOCKED: {
-        struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, x->data);
+        struct h3_stream_ctx *stream;
         DEBUGASSERT(ndatalen == -1);
         nghttp3_conn_block_stream(ctx->h3conn, stream_id);
         CURL_TRC_CF(x->data, x->cf, "[%" FMT_PRId64 "] block quic flow",
                     (curl_int64_t)stream_id);
-        DEBUGASSERT(stream);
-        if(stream)
+        stream = cf_ngtcp2_get_stream(ctx, stream_id);
+        if(stream) /* it might be not one of our h3 streams? */
           stream->quic_flow_blocked = TRUE;
         n = 0;
         break;