aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/event/quic/ngx_event_quic.h4
-rw-r--r--src/event/quic/ngx_event_quic_ack.c1
-rw-r--r--src/event/quic/ngx_event_quic_streams.c82
3 files changed, 64 insertions, 23 deletions
diff --git a/src/event/quic/ngx_event_quic.h b/src/event/quic/ngx_event_quic.h
index 231ff6e96..d33bd8d4d 100644
--- a/src/event/quic/ngx_event_quic.h
+++ b/src/event/quic/ngx_event_quic.h
@@ -85,6 +85,7 @@ struct ngx_quic_stream_s {
ngx_connection_t *parent;
ngx_connection_t *connection;
uint64_t id;
+ uint64_t sent;
uint64_t acked;
uint64_t send_max_data;
uint64_t send_offset;
@@ -98,7 +99,8 @@ struct ngx_quic_stream_s {
ngx_quic_buffer_t recv;
ngx_quic_stream_send_state_e send_state;
ngx_quic_stream_recv_state_e recv_state;
- ngx_uint_t cancelable; /* unsigned cancelable:1; */
+ unsigned cancelable:1;
+ unsigned fin_acked:1;
};
diff --git a/src/event/quic/ngx_event_quic_ack.c b/src/event/quic/ngx_event_quic_ack.c
index ebbcf7210..d236deb59 100644
--- a/src/event/quic/ngx_event_quic_ack.c
+++ b/src/event/quic/ngx_event_quic_ack.c
@@ -253,6 +253,7 @@ ngx_quic_handle_ack_frame_range(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
break;
case NGX_QUIC_FT_STREAM:
+ case NGX_QUIC_FT_RESET_STREAM:
ngx_quic_handle_stream_ack(c, f);
break;
}
diff --git a/src/event/quic/ngx_event_quic_streams.c b/src/event/quic/ngx_event_quic_streams.c
index bad8b4ae5..999bfccef 100644
--- a/src/event/quic/ngx_event_quic_streams.c
+++ b/src/event/quic/ngx_event_quic_streams.c
@@ -887,7 +887,7 @@ ngx_quic_stream_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
qs->send_state = NGX_QUIC_STREAM_SEND_SEND;
- flow = qs->acked + qc->conf->stream_buffer_size - c->sent;
+ flow = qs->acked + qc->conf->stream_buffer_size - qs->sent;
if (flow == 0) {
wev->ready = 0;
@@ -900,13 +900,14 @@ ngx_quic_stream_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
n = qs->send.size;
- in = ngx_quic_write_buffer(pc, &qs->send, in, limit, c->sent);
+ in = ngx_quic_write_buffer(pc, &qs->send, in, limit, qs->sent);
if (in == NGX_CHAIN_ERROR) {
return NGX_CHAIN_ERROR;
}
n = qs->send.size - n;
c->sent += n;
+ qs->sent += n;
qc->streams.sent += n;
if (flow == n) {
@@ -1045,9 +1046,12 @@ ngx_quic_close_stream(ngx_quic_stream_t *qs)
if (!qc->closing) {
/* make sure everything is sent and final size is received */
- if (qs->recv_state == NGX_QUIC_STREAM_RECV_RECV
- || qs->send_state == NGX_QUIC_STREAM_SEND_READY
- || qs->send_state == NGX_QUIC_STREAM_SEND_SEND)
+ if (qs->recv_state == NGX_QUIC_STREAM_RECV_RECV) {
+ return NGX_OK;
+ }
+
+ if (qs->send_state != NGX_QUIC_STREAM_SEND_DATA_RECVD
+ && qs->send_state != NGX_QUIC_STREAM_SEND_RESET_RECVD)
{
return NGX_OK;
}
@@ -1488,36 +1492,70 @@ ngx_quic_handle_max_streams_frame(ngx_connection_t *c,
void
ngx_quic_handle_stream_ack(ngx_connection_t *c, ngx_quic_frame_t *f)
{
- uint64_t sent, unacked;
+ uint64_t acked;
ngx_quic_stream_t *qs;
ngx_quic_connection_t *qc;
qc = ngx_quic_get_connection(c);
- qs = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id);
- if (qs == NULL) {
- return;
- }
+ switch (f->type) {
- if (qs->connection == NULL) {
+ case NGX_QUIC_FT_RESET_STREAM:
+
+ qs = ngx_quic_find_stream(&qc->streams.tree, f->u.reset_stream.id);
+ if (qs == NULL) {
+ return;
+ }
+
+ qs->send_state = NGX_QUIC_STREAM_SEND_RESET_RECVD;
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "quic stream id:0x%xL ack reset final_size:%uL",
+ qs->id, f->u.reset_stream.final_size);
+
+ break;
+
+ case NGX_QUIC_FT_STREAM:
+
+ qs = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id);
+ if (qs == NULL) {
+ return;
+ }
+
+ acked = qs->acked;
qs->acked += f->u.stream.length;
- return;
- }
- sent = qs->connection->sent;
- unacked = sent - qs->acked;
- qs->acked += f->u.stream.length;
+ if (f->u.stream.fin) {
+ qs->fin_acked = 1;
+ }
+
+ if (qs->send_state == NGX_QUIC_STREAM_SEND_DATA_SENT
+ && qs->acked == qs->sent && qs->fin_acked)
+ {
+ qs->send_state = NGX_QUIC_STREAM_SEND_DATA_RECVD;
+ }
+
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "quic stream id:0x%xL ack len:%uL fin:%d unacked:%uL",
+ qs->id, f->u.stream.length, f->u.stream.fin,
+ qs->sent - qs->acked);
+
+ if (qs->connection
+ && qs->sent - acked == qc->conf->stream_buffer_size
+ && f->u.stream.length > 0)
+ {
+ ngx_quic_set_event(qs->connection->write);
+ }
- ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "quic stream id:0x%xL ack len:%uL acked:%uL unacked:%uL",
- qs->id, f->u.stream.length, qs->acked, sent - qs->acked);
+ break;
- if (unacked != qc->conf->stream_buffer_size) {
- /* not blocked on buffer size */
+ default:
return;
}
- ngx_quic_set_event(qs->connection->write);
+ if (qs->connection == NULL) {
+ ngx_quic_close_stream(qs);
+ }
}