summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/event/ngx_event_quic.c168
1 files changed, 109 insertions, 59 deletions
diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c
index 94097c4d9..51d32eb83 100644
--- a/src/event/ngx_event_quic.c
+++ b/src/event/ngx_event_quic.c
@@ -265,7 +265,10 @@ static ngx_int_t ngx_quic_send_frames(ngx_connection_t *c,
static void ngx_quic_set_packet_number(ngx_quic_header_t *pkt,
ngx_quic_send_ctx_t *ctx);
static void ngx_quic_pto_handler(ngx_event_t *ev);
-static ngx_int_t ngx_quic_detect_lost(ngx_connection_t *c, ngx_uint_t ack);
+static void ngx_quic_lost_handler(ngx_event_t *ev);
+static ngx_int_t ngx_quic_detect_lost(ngx_connection_t *c);
+static ngx_int_t ngx_quic_resend_frames(ngx_connection_t *c,
+ ngx_quic_send_ctx_t *ctx, ngx_quic_frame_t *start);
static void ngx_quic_push_handler(ngx_event_t *ev);
static void ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp,
@@ -2401,7 +2404,7 @@ ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
}
}
- return ngx_quic_detect_lost(c, 1);
+ return ngx_quic_detect_lost(c);
}
@@ -3682,18 +3685,46 @@ ngx_quic_set_packet_number(ngx_quic_header_t *pkt, ngx_quic_send_ctx_t *ctx)
static void
ngx_quic_pto_handler(ngx_event_t *ev)
{
- ngx_connection_t *c;
+ ngx_uint_t i;
+ ngx_queue_t *q;
+ ngx_connection_t *c;
+ ngx_quic_frame_t *start;
+ ngx_quic_send_ctx_t *ctx;
+ ngx_quic_connection_t *qc;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic pto timer");
c = ev->data;
+ qc = c->quic;
- if (ngx_quic_detect_lost(c, 0) != NGX_OK) {
- ngx_quic_close_connection(c, NGX_ERROR);
- return;
- }
+ qc->pto_count++;
+
+ for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
+
+ ctx = &qc->send_ctx[i];
+
+ if (ngx_queue_empty(&ctx->sent)) {
+ continue;
+ }
+
+ q = ngx_queue_head(&ctx->sent);
+ start = ngx_queue_data(q, ngx_quic_frame_t, queue);
+
+ if (start->pnum <= ctx->largest_ack
+ && ctx->largest_ack != (uint64_t) -1)
+ {
+ continue;
+ }
- c->quic->pto_count++;
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "quic pto pnum:%ui pto_count:%ui level:%d",
+ start->pnum, c->quic->pto_count, start->level);
+
+ if (ngx_quic_resend_frames(c, ctx, start) != NGX_OK) {
+ ngx_quic_close_connection(c, NGX_ERROR);
+ return;
+ }
+ }
}
@@ -3713,14 +3744,28 @@ ngx_quic_push_handler(ngx_event_t *ev)
}
+static
+void ngx_quic_lost_handler(ngx_event_t *ev)
+{
+ ngx_connection_t *c;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic lost timer");
+
+ c = ev->data;
+
+ if (ngx_quic_detect_lost(c) != NGX_OK) {
+ ngx_quic_close_connection(c, NGX_ERROR);
+ }
+}
+
+
static ngx_int_t
-ngx_quic_detect_lost(ngx_connection_t *c, ngx_uint_t ack)
+ngx_quic_detect_lost(ngx_connection_t *c)
{
- uint64_t pn;
ngx_uint_t i;
ngx_msec_t now, wait, min_wait, thr;
- ngx_queue_t *q, range;
- ngx_quic_frame_t *f, *start;
+ ngx_queue_t *q;
+ ngx_quic_frame_t *start;
ngx_quic_send_ctx_t *ctx;
ngx_quic_connection_t *qc;
@@ -3729,88 +3774,93 @@ ngx_quic_detect_lost(ngx_connection_t *c, ngx_uint_t ack)
min_wait = 0;
-#if (NGX_SUPPRESS_WARN)
- thr = 0;
-#endif
-
- if (ack) {
- thr = NGX_QUIC_TIME_THR * ngx_max(qc->latest_rtt, qc->avg_rtt);
- thr = ngx_max(thr, NGX_QUIC_TIME_GRANULARITY);
- }
+ thr = NGX_QUIC_TIME_THR * ngx_max(qc->latest_rtt, qc->avg_rtt);
+ thr = ngx_max(thr, NGX_QUIC_TIME_GRANULARITY);
for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
ctx = &qc->send_ctx[i];
- if (ngx_queue_empty(&ctx->sent)) {
- continue;
- }
-
- if (!ack) {
- thr = ngx_quic_pto(c, ctx);
- }
-
- q = ngx_queue_head(&ctx->sent);
+ while (!ngx_queue_empty(&ctx->sent)) {
- do {
+ q = ngx_queue_head(&ctx->sent);
start = ngx_queue_data(q, ngx_quic_frame_t, queue);
wait = start->last + thr - now;
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "quic detect_lost pnum:%ui thr:%M wait:%i level:%d",
+ start->pnum, thr, (ngx_int_t) wait, start->level);
+
if ((ngx_msec_int_t) wait >= 0) {
if (min_wait == 0 || wait < min_wait) {
min_wait = wait;
}
- if (!ack) {
- break;
- }
-
if ((start->pnum > ctx->largest_ack)
+ || ctx->largest_ack == (uint64_t) -1
|| ((ctx->largest_ack - start->pnum) < NGX_QUIC_PKT_THR))
{
break;
}
}
- pn = start->pnum;
+ if (ngx_quic_resend_frames(c, ctx, start) != NGX_OK) {
+ return NGX_ERROR;
+ }
+ }
+ }
- ngx_queue_init(&range);
+ /* no more preceeding packets */
- /* send frames with same packet number to the wire */
- do {
- f = ngx_queue_data(q, ngx_quic_frame_t, queue);
+ if (min_wait == 0) {
+ qc->pto.handler = ngx_quic_pto_handler;
+ return NGX_OK;
+ }
- if (f->pnum != pn) {
- break;
- }
+ qc->pto.handler = ngx_quic_lost_handler;
- q = ngx_queue_next(q);
+ if (qc->pto.timer_set) {
+ ngx_del_timer(&qc->pto);
+ }
- ngx_queue_remove(&f->queue);
- ngx_queue_insert_tail(&range, &f->queue);
+ ngx_add_timer(&qc->pto, min_wait);
- } while (q != ngx_queue_sentinel(&ctx->sent));
+ return NGX_OK;
+}
- ngx_quic_congestion_lost(c, start);
- if (ngx_quic_send_frames(c, ctx, &range) != NGX_OK) {
- return NGX_ERROR;
- }
+static ngx_int_t
+ngx_quic_resend_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
+ ngx_quic_frame_t *start)
+{
+ ngx_queue_t *q, range;
+ ngx_quic_frame_t *f;
- } while (q != ngx_queue_sentinel(&ctx->sent));
- }
+ ngx_queue_init(&range);
- if (qc->pto.timer_set) {
- ngx_del_timer(&qc->pto);
- }
+ /* send frames with same packet number to the wire */
- if (min_wait > 0) {
- ngx_add_timer(&qc->pto, min_wait);
- }
+ q = ngx_queue_head(&ctx->sent);
- return NGX_OK;
+ do {
+ f = ngx_queue_data(q, ngx_quic_frame_t, queue);
+
+ if (f->pnum != start->pnum) {
+ break;
+ }
+
+ q = ngx_queue_next(q);
+
+ ngx_queue_remove(&f->queue);
+ ngx_queue_insert_tail(&range, &f->queue);
+
+ } while (q != ngx_queue_sentinel(&ctx->sent));
+
+ ngx_quic_congestion_lost(c, start);
+
+ return ngx_quic_send_frames(c, ctx, &range);
}