diff options
author | Roman Arutyunyan <arut@nginx.com> | 2022-02-03 18:11:59 +0300 |
---|---|---|
committer | Roman Arutyunyan <arut@nginx.com> | 2022-02-03 18:11:59 +0300 |
commit | e9c170635e7b35dd2a92ab72e57f38a3403e9566 (patch) | |
tree | 10537b2f27db00df5defc3d826a2fa43357c2e03 | |
parent | 1cc2be9616bd9117778d3576dcf3112eb93da4e3 (diff) | |
download | nginx-e9c170635e7b35dd2a92ab72e57f38a3403e9566.tar.gz nginx-e9c170635e7b35dd2a92ab72e57f38a3403e9566.zip |
QUIC: switch stream to DATA_RECVD state.
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.
-rw-r--r-- | src/event/quic/ngx_event_quic.h | 1 | ||||
-rw-r--r-- | src/event/quic/ngx_event_quic_streams.c | 13 |
2 files changed, 12 insertions, 2 deletions
diff --git a/src/event/quic/ngx_event_quic.h b/src/event/quic/ngx_event_quic.h index 8a188c2da..af6b6838f 100644 --- a/src/event/quic/ngx_event_quic.h +++ b/src/event/quic/ngx_event_quic.h @@ -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; diff --git a/src/event/quic/ngx_event_quic_streams.c b/src/event/quic/ngx_event_quic_streams.c index 6f10ff125..c0f32394d 100644 --- a/src/event/quic/ngx_event_quic_streams.c +++ b/src/event/quic/ngx_event_quic_streams.c @@ -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); } |