Search code examples
nginxquichttp3

how to set final size when sending a reset frame in http3


The following scenario:

  1. Sender have sent continuous 10000 bytes
  2. Receiver ACK 0 - 8000(sender have recived those acks)
  3. Now, Sender will send a reset frame, the question is how to set the " final size"

a. final size is 10000
b. final size is 8000

Looking at RFC 9000(https://datatracker.ietf.org/doc/html/rfc9000#section-4.5) witch describing:

4.5. Stream Final Size

The final size is the amount of flow control credit that is consumed by a stream. Assuming that every contiguous byte on the stream was sent once, the final size is the number of bytes sent. More generally, this is one higher than the offset of the byte with the largest offset sent on the stream, or zero if no bytes were sent.

I think the final size should be 10000, and sender must not send any more(transmission and retransmission) on the identified stream, am I right? https://datatracker.ietf.org/doc/html/rfc9000#section-19.4

After sending a RESET_STREAM, an endpoint ceases transmission and
retransmission of STREAM frames on the identified stream. A receiver of RESET_STREAM can discard any data that it already received on that stream.

And nginx'iquic may have some problems, nginx will retranmit frames when nginx have sent a reset frame(for example: nginx http3 have sent all data to ctx->frames, then qs will be deleted)

   void
    ngx_quic_resend_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx)
    {
    case NGX_QUIC_FT_STREAM:
        qs = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id);

        if (qs) {
            if (qs->send_state == NGX_QUIC_STREAM_SEND_RESET_SENT
                || qs->send_state == NGX_QUIC_STREAM_SEND_RESET_RECVD)
            {
                ngx_quic_free_frame(c, f);
                break;
            }
        }
}

Solution

  • The final size is definitely 10000, as flow control credit is consumed by sending data on a stream; whether it is acknowlegded or not does not matter.

    Indeed, after sending the reset-stream frame:

    • no new data should be send (this would be a violation of the final size leading to a fatal error as described in section 4.5
    • no retransmissions should be performed

    The 3rd question is unclear to me. I'm not a ngx-quic expert, but from the code it posted i would guess it does not retransmit, as the frame is freed ;-)