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.
This commit is contained in:
Roman Arutyunyan 2022-02-03 18:11:59 +03:00
parent 1cc2be9616
commit e9c170635e
2 changed files with 12 additions and 2 deletions

View File

@ -82,6 +82,7 @@ struct ngx_quic_stream_s {
uint64_t recv_offset; uint64_t recv_offset;
uint64_t recv_window; uint64_t recv_window;
uint64_t recv_last; uint64_t recv_last;
uint64_t recv_size;
uint64_t final_size; uint64_t final_size;
ngx_chain_t *in; ngx_chain_t *in;
ngx_chain_t *out; ngx_chain_t *out;

View File

@ -762,7 +762,7 @@ ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf, size_t size)
if (len == 0) { if (len == 0) {
rev->ready = 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_offset == qs->final_size)
{ {
qs->recv_state = NGX_QUIC_STREAM_RECV_DATA_READ; 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_handle_stream_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
ngx_quic_frame_t *frame) ngx_quic_frame_t *frame)
{ {
size_t size;
uint64_t last; uint64_t last;
ngx_connection_t *sc; ngx_connection_t *sc;
ngx_quic_stream_t *qs; 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, 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) == NGX_CHAIN_ERROR)
{ {
return NGX_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) { if (f->offset == qs->recv_offset) {
ngx_quic_set_event(sc->read); ngx_quic_set_event(sc->read);
} }