changeset 8473:1b9db5c8c29b quic

QUIC: reworked ngx_quic_send_frames() function. Instead of returning NGX_DONE/NGX_OK, the function now itself moves passed frames range into sent queue and sets PTO timer if required.
author Vladimir Homutov <vl@nginx.com>
date Wed, 15 Jul 2020 15:10:17 +0300
parents 3b15732ac03f
children 909b989ec088
files src/event/ngx_event_quic.c
diffstat 1 files changed, 29 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_quic.c
+++ b/src/event/ngx_event_quic.c
@@ -241,7 +241,8 @@ static ngx_int_t ngx_quic_output(ngx_con
 static ngx_int_t ngx_quic_output_frames(ngx_connection_t *c,
     ngx_quic_send_ctx_t *ctx);
 static void ngx_quic_free_frames(ngx_connection_t *c, ngx_queue_t *frames);
-static ngx_int_t ngx_quic_send_frames(ngx_connection_t *c, ngx_queue_t *frames);
+static ngx_int_t ngx_quic_send_frames(ngx_connection_t *c,
+    ngx_quic_send_ctx_t *ctx, ngx_queue_t *frames);
 
 static void ngx_quic_set_packet_number(ngx_quic_header_t *pkt,
     ngx_quic_send_ctx_t *ctx);
@@ -3260,10 +3261,6 @@ ngx_quic_output(ngx_connection_t *c)
         ngx_add_timer(c->read, qc->tp.max_idle_timeout);
     }
 
-    if (!qc->pto.timer_set && !qc->closing) {
-        ngx_add_timer(&qc->pto, qc->ctp.max_ack_delay + NGX_QUIC_HARDCODED_PTO);
-    }
-
     return NGX_OK;
 }
 
@@ -3272,7 +3269,6 @@ static ngx_int_t
 ngx_quic_output_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx)
 {
     size_t                  len, hlen, n;
-    ngx_int_t               rc;
     ngx_uint_t              need_ack;
     ngx_queue_t            *q, range;
     ngx_quic_frame_t       *f;
@@ -3332,32 +3328,7 @@ ngx_quic_output_frames(ngx_connection_t 
             break;
         }
 
-        rc = ngx_quic_send_frames(c, &range);
-
-        if (rc == NGX_OK) {
-            /*
-             * frames are moved into the sent queue
-             * to wait for ack/be retransmitted
-            */
-            if (qc->closing) {
-                /* if we are closing, any ack will be discarded */
-                ngx_quic_free_frames(c, &range);
-
-            } else {
-                ngx_queue_add(&ctx->sent, &range);
-            }
-
-            cg->in_flight += len;
-
-            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                           "quic congestion send if:%uz", cg->in_flight);
-
-        } else if (rc == NGX_DONE) {
-
-            /* no ack is expected for this frames, can free them */
-            ngx_quic_free_frames(c, &range);
-
-        } else {
+        if (ngx_quic_send_frames(c, ctx, &range) != NGX_OK) {
             return NGX_ERROR;
         }
 
@@ -3390,7 +3361,8 @@ ngx_quic_free_frames(ngx_connection_t *c
 
 
 static ngx_int_t
-ngx_quic_send_frames(ngx_connection_t *c, ngx_queue_t *frames)
+ngx_quic_send_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
+    ngx_queue_t *frames)
 {
     ssize_t                 len;
     u_char                 *p;
@@ -3401,7 +3373,6 @@ ngx_quic_send_frames(ngx_connection_t *c
     ngx_quic_frame_t       *f, *start;
     ngx_quic_header_t       pkt;
     ngx_quic_secrets_t     *keys;
-    ngx_quic_send_ctx_t    *ctx;
     ngx_quic_connection_t  *qc;
     static ngx_str_t        initial_token = ngx_null_string;
     static u_char           src[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
@@ -3415,8 +3386,6 @@ ngx_quic_send_frames(ngx_connection_t *c
     q = ngx_queue_head(frames);
     start = ngx_queue_data(q, ngx_quic_frame_t, queue);
 
-    ctx = ngx_quic_get_send_ctx(c->quic, start->level);
-
     ngx_memzero(&pkt, sizeof(ngx_quic_header_t));
 
     now = ngx_current_msec;
@@ -3507,7 +3476,29 @@ ngx_quic_send_frames(ngx_connection_t *c
     /* len == NGX_OK || NGX_AGAIN */
     ctx->pnum++;
 
-    return pkt.need_ack ? NGX_OK : NGX_DONE;
+    if (pkt.need_ack) {
+        /* move frames into the sent queue to wait for ack */
+
+        if (qc->closing) {
+            /* if we are closing, any ack will be discarded */
+            ngx_quic_free_frames(c, frames);
+
+        } else {
+            ngx_queue_add(&ctx->sent, frames);
+            ngx_add_timer(&qc->pto, NGX_QUIC_HARDCODED_PTO);
+        }
+
+        qc->congestion.in_flight += out.len;
+
+        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                       "quic congestion send if:%uz",
+                       qc->congestion.in_flight);
+    } else {
+        /* no ack is expected for this frames, so we can free them */
+        ngx_quic_free_frames(c, frames);
+    }
+
+    return NGX_OK;
 }
 
 
@@ -3650,16 +3641,10 @@ ngx_quic_detect_lost(ngx_connection_t *c
 
         ngx_quic_congestion_lost(c, start->last);
 
-        /* NGX_DONE is impossible here, such frames don't get into this queue */
-        if (ngx_quic_send_frames(c, &range) != NGX_OK) {
+        if (ngx_quic_send_frames(c, ctx, &range) != NGX_OK) {
             return NGX_ERROR;
         }
 
-        /* move frames group to the end of queue */
-        ngx_queue_add(&ctx->sent, &range);
-
-        wait = qc->ctp.max_ack_delay + NGX_QUIC_HARDCODED_PTO;
-
     } while (q != ngx_queue_sentinel(&ctx->sent));
 
     *waitp = wait;