]> git.kaiwu.me - nginx.git/commitdiff
QUIC: optimized immediate close.
authorRoman Arutyunyan <arut@nginx.com>
Tue, 2 May 2023 13:54:53 +0000 (17:54 +0400)
committerRoman Arutyunyan <arut@nginx.com>
Tue, 2 May 2023 13:54:53 +0000 (17:54 +0400)
Previously, before sending CONNECTION_CLOSE to client, all pending frames
were sent.  This is redundant and could prevent CONNECTION_CLOSE from being
sent due to congestion control.  Now pending frames are freed and
CONNECTION_CLOSE is sent without congestion control, as advised by RFC 9002:

  Packets containing frames besides ACK or CONNECTION_CLOSE frames
  count toward congestion control limits and are considered to be in flight.

src/event/quic/ngx_event_quic.c
src/event/quic/ngx_event_quic_output.c

index 9b342d7debbc398c8fdf21ad21ea7bb0c9e29753..b4033bc3f30d6cd297a98e0730db4e034d3cbc12 100644 (file)
@@ -482,6 +482,7 @@ ngx_quic_close_connection(ngx_connection_t *c, ngx_int_t rc)
 
         /* drop packets from retransmit queues, no ack is expected */
         for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
+            ngx_quic_free_frames(c, &qc->send_ctx[i].frames);
             ngx_quic_free_frames(c, &qc->send_ctx[i].sent);
         }
 
index d2ced99a16806de501ed618eb55e6dde5af608cb..8cf844460bcd6bc8c7af4c16631e6acbbc1b7bf6 100644 (file)
@@ -882,7 +882,7 @@ ngx_quic_send_stateless_reset(ngx_connection_t *c, ngx_quic_conf_t *conf,
 ngx_int_t
 ngx_quic_send_cc(ngx_connection_t *c)
 {
-    ngx_quic_frame_t       *frame;
+    ngx_quic_frame_t        frame;
     ngx_quic_connection_t  *qc;
 
     qc = ngx_quic_get_connection(c);
@@ -898,27 +898,22 @@ ngx_quic_send_cc(ngx_connection_t *c)
         return NGX_OK;
     }
 
-    frame = ngx_quic_alloc_frame(c);
-    if (frame == NULL) {
-        return NGX_ERROR;
-    }
+    ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
 
-    frame->level = qc->error_level;
-    frame->type = qc->error_app ? NGX_QUIC_FT_CONNECTION_CLOSE_APP
-                                : NGX_QUIC_FT_CONNECTION_CLOSE;
-    frame->u.close.error_code = qc->error;
-    frame->u.close.frame_type = qc->error_ftype;
+    frame.level = qc->error_level;
+    frame.type = qc->error_app ? NGX_QUIC_FT_CONNECTION_CLOSE_APP
+                               : NGX_QUIC_FT_CONNECTION_CLOSE;
+    frame.u.close.error_code = qc->error;
+    frame.u.close.frame_type = qc->error_ftype;
 
     if (qc->error_reason) {
-        frame->u.close.reason.len = ngx_strlen(qc->error_reason);
-        frame->u.close.reason.data = (u_char *) qc->error_reason;
+        frame.u.close.reason.len = ngx_strlen(qc->error_reason);
+        frame.u.close.reason.data = (u_char *) qc->error_reason;
     }
 
-    ngx_quic_queue_frame(qc, frame);
-
     qc->last_cc = ngx_current_msec;
 
-    return ngx_quic_output(c);
+    return ngx_quic_frame_sendto(c, &frame, 0, qc->path);
 }