Hi Amaury,

Thanks for taking a look.

> I'm not sure to agree yet with the proposed fix as this could have
> unwanted consequences, most notably with the backend support (which
> the proposed patch does not support here). However, a localized fix
> in qcc_recv_reset_stream() is at least mandatory here.

That's a fair point, and honestly the reason our patch doesn't cover
qcc_be_is_reusable()/backend semantics is simply that we don't run any
QUIC/HTTP3 backends ourselves, so we hadn't considered that case at
all.

We're currently carrying a live leak in production from this (around
1.22M stuck connections on one node before we restarted it), so we're
planning to apply both what we submitted before (the qcc_is_dead()
reorder, frontend-only as submitted) and the change below internally,
regardless of the outcome of the wider upstream discussion. Since
we don't run QUIC/HTTP3 backends, the backend concern you raised
doesn't affect our own deployment either way.

The change below is the qcc_recv_reset_stream() timeout refresh you
mentioned as at least mandatory. It isn't guarded by conn_is_back() at
all, so it already applies uniformly to both sides. For reference,
this is what we have (against current master):

    int qcc_recv_reset_stream(struct qcc *qcc, uint64_t id, uint64_t err, 
uint64_t final_size)
    {
            ...
            qcs->flags |= QC_SF_SIZE_KNOWN|QC_SF_RECV_RESET;
            qcs_close_remote(qcs);

    +       /* Unlike STREAM frame handling and qcc_recv_stop_sending(), this
    +        * function had no qcc_refresh_timeout() call of its own. A stream
    +        * reset before its request is complete leaves nb_hreq stuck and
    +        * never emits any TX data, so qcc->task could otherwise be left
    +        * with a stale expire computed once at qmux_init() time and never
    +        * queued. qcc_refresh_timeout() already checks qcc_may_expire()
    +        * (based on nb_sc, not nb_hreq) and recomputes from opening_list,
    +        * so it is safe to call unconditionally here.
    +        */
    +       qcc_refresh_timeout(qcc);
    +
            /* RFC 9000 3.2. Receiving Stream States
             *
             * An
             * implementation MAY interrupt delivery of stream data, discard any
             * data that was not consumed, and signal the receipt of the
             * RESET_STREAM.
            ...

Wanted to check first in case you see any problem with us applying
both of these internally ahead of whatever ends up merged upstream, or
any risk specific to a frontend-only QUIC deployment that we might be
missing beyond the backend point you already raised.

Reply via email to