]> git.kaiwu.me - nginx.git/commitdiff
QUIC: switch stream to DATA_RECVD state.
authorRoman Arutyunyan <arut@nginx.com>
Thu, 3 Feb 2022 15:11:59 +0000 (18:11 +0300)
committerRoman Arutyunyan <arut@nginx.com>
Thu, 3 Feb 2022 15:11:59 +0000 (18:11 +0300)
The switch happens when received byte counter reaches stream final size.
Previously, this state was skipped.  The stream went from SIZE_KNOWN to
DATA_READ when all bytes were read by application.

The change prevents STOP_SENDING frames from being sent when all data is
received from client, but not yet fully read by application.

src/event/quic/ngx_event_quic.h
src/event/quic/ngx_event_quic_streams.c

index 8a188c2dad017d718e362400aaaf2710a4990047..af6b6838f499c909f5962e71bef92ef793364040 100644 (file)
@@ -82,6 +82,7 @@ struct ngx_quic_stream_s {
     uint64_t                       recv_offset;
     uint64_t                       recv_window;
     uint64_t                       recv_last;
+    uint64_t                       recv_size;
     uint64_t                       final_size;
     ngx_chain_t                   *in;
     ngx_chain_t                   *out;
index 6f10ff125732c7faa9c391e954a0f106d9a87b23..c0f32394d7a04815ac883e88d4caeb03e6e27e6c 100644 (file)
@@ -762,7 +762,7 @@ ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf, size_t size)
     if (len == 0) {
         rev->ready = 0;
 
-        if (qs->recv_state == NGX_QUIC_STREAM_RECV_SIZE_KNOWN
+        if (qs->recv_state == NGX_QUIC_STREAM_RECV_DATA_RECVD
             && qs->recv_offset == qs->final_size)
         {
             qs->recv_state = NGX_QUIC_STREAM_RECV_DATA_READ;
@@ -1018,6 +1018,7 @@ ngx_int_t
 ngx_quic_handle_stream_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
     ngx_quic_frame_t *frame)
 {
+    size_t                    size;
     uint64_t                  last;
     ngx_connection_t         *sc;
     ngx_quic_stream_t        *qs;
@@ -1089,12 +1090,20 @@ ngx_quic_handle_stream_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
     }
 
     if (ngx_quic_write_chain(c, &qs->in, frame->data, f->length,
-                             f->offset - qs->recv_offset, NULL)
+                             f->offset - qs->recv_offset, &size)
         == NGX_CHAIN_ERROR)
     {
         return NGX_ERROR;
     }
 
+    qs->recv_size += size;
+
+    if (qs->recv_state == NGX_QUIC_STREAM_RECV_SIZE_KNOWN
+        && qs->recv_size == qs->final_size)
+    {
+        qs->recv_state = NGX_QUIC_STREAM_RECV_DATA_RECVD;
+    }
+
     if (f->offset == qs->recv_offset) {
         ngx_quic_set_event(sc->read);
     }