[PATCH 1 of 3] QUIC: "handshake_timeout" configuration parameter

Roman Arutyunyan arut at nginx.com
Mon Sep 11 11:30:30 UTC 2023


# HG changeset patch
# User Roman Arutyunyan <arut at nginx.com>
# Date 1694415935 -14400
#      Mon Sep 11 11:05:35 2023 +0400
# Node ID 65574b876c4047495ac8622c6161fc87c1b75913
# Parent  daf8f5ba23d8e9955b22782d945f9c065f4b6baa
QUIC: "handshake_timeout" configuration parameter.

Previously QUIC did not have such parameter and handshake duration was
controlled by HTTP/3.  However that required creating and storing HTTP/3
session while processing the first client datagram.  Apparently there's
no convenient way to store the session object before QUIC handshake.  In
the following patch session creation will be postponed until first stream
creation.

diff --git a/src/event/quic/ngx_event_quic.c b/src/event/quic/ngx_event_quic.c
--- a/src/event/quic/ngx_event_quic.c
+++ b/src/event/quic/ngx_event_quic.c
@@ -213,6 +213,8 @@ ngx_quic_run(ngx_connection_t *c, ngx_qu
     ngx_add_timer(c->read, qc->tp.max_idle_timeout);
     ngx_quic_connstate_dbg(c);
 
+    ngx_add_timer(&qc->close, qc->conf->handshake_timeout);
+
     c->read->handler = ngx_quic_input_handler;
 
     return;
@@ -521,6 +523,10 @@ ngx_quic_close_connection(ngx_connection
                            qc->error_app ? "app " : "", qc->error,
                            qc->error_reason ? qc->error_reason : "");
 
+            if (qc->close.timer_set) {
+                ngx_del_timer(&qc->close);
+            }
+
             for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
                 ctx = &qc->send_ctx[i];
 
diff --git a/src/event/quic/ngx_event_quic.h b/src/event/quic/ngx_event_quic.h
--- a/src/event/quic/ngx_event_quic.h
+++ b/src/event/quic/ngx_event_quic.h
@@ -67,7 +67,8 @@ typedef struct {
     ngx_flag_t                     retry;
     ngx_flag_t                     gso_enabled;
     ngx_flag_t                     disable_active_migration;
-    ngx_msec_t                     timeout;
+    ngx_msec_t                     handshake_timeout;
+    ngx_msec_t                     idle_timeout;
     ngx_str_t                      host_key;
     size_t                         stream_buffer_size;
     ngx_uint_t                     max_concurrent_streams_bidi;
diff --git a/src/event/quic/ngx_event_quic_streams.c b/src/event/quic/ngx_event_quic_streams.c
--- a/src/event/quic/ngx_event_quic_streams.c
+++ b/src/event/quic/ngx_event_quic_streams.c
@@ -630,6 +630,10 @@ ngx_quic_do_init_streams(ngx_connection_
 
     qc->streams.initialized = 1;
 
+    if (!qc->closing && qc->close.timer_set) {
+        ngx_del_timer(&qc->close);
+    }
+
     return NGX_OK;
 }
 
diff --git a/src/event/quic/ngx_event_quic_transport.c b/src/event/quic/ngx_event_quic_transport.c
--- a/src/event/quic/ngx_event_quic_transport.c
+++ b/src/event/quic/ngx_event_quic_transport.c
@@ -1985,7 +1985,7 @@ ngx_quic_init_transport_params(ngx_quic_
      *     tp->preferred_address = NULL
      */
 
-    tp->max_idle_timeout = qcf->timeout;
+    tp->max_idle_timeout = qcf->idle_timeout;
 
     tp->max_udp_payload_size = NGX_QUIC_MAX_UDP_PAYLOAD_SIZE;
 
diff --git a/src/http/v3/ngx_http_v3_module.c b/src/http/v3/ngx_http_v3_module.c
--- a/src/http/v3/ngx_http_v3_module.c
+++ b/src/http/v3/ngx_http_v3_module.c
@@ -192,7 +192,7 @@ ngx_http_v3_create_srv_conf(ngx_conf_t *
      *     h3scf->quic.host_key = { 0, NULL }
      *     h3scf->quic.stream_reject_code_uni = 0;
      *     h3scf->quic.disable_active_migration = 0;
-     *     h3scf->quic.timeout = 0;
+     *     h3scf->quic.idle_timeout = 0;
      *     h3scf->max_blocked_streams = 0;
      */
 
@@ -223,7 +223,8 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *c
     ngx_http_v3_srv_conf_t *prev = parent;
     ngx_http_v3_srv_conf_t *conf = child;
 
-    ngx_http_ssl_srv_conf_t  *sscf;
+    ngx_http_ssl_srv_conf_t   *sscf;
+    ngx_http_core_srv_conf_t  *cscf;
 
     ngx_conf_merge_value(conf->enable, prev->enable, 1);
 
@@ -281,6 +282,9 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *c
         return NGX_CONF_ERROR;
     }
 
+    cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
+    conf->quic.handshake_timeout = cscf->client_header_timeout;
+
     sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module);
     conf->quic.ssl = &sscf->ssl;
 
diff --git a/src/http/v3/ngx_http_v3_request.c b/src/http/v3/ngx_http_v3_request.c
--- a/src/http/v3/ngx_http_v3_request.c
+++ b/src/http/v3/ngx_http_v3_request.c
@@ -58,18 +58,15 @@ static const struct {
 void
 ngx_http_v3_init_stream(ngx_connection_t *c)
 {
-    ngx_http_v3_session_t     *h3c;
     ngx_http_connection_t     *hc, *phc;
     ngx_http_v3_srv_conf_t    *h3scf;
     ngx_http_core_loc_conf_t  *clcf;
-    ngx_http_core_srv_conf_t  *cscf;
 
     hc = c->data;
 
     hc->ssl = 1;
 
     clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);
-    cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
     h3scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v3_module);
 
     if (c->quic == NULL) {
@@ -78,10 +75,7 @@ ngx_http_v3_init_stream(ngx_connection_t
             return;
         }
 
-        h3c = hc->v3_session;
-        ngx_add_timer(&h3c->keepalive, cscf->client_header_timeout);
-
-        h3scf->quic.timeout = clcf->keepalive_timeout;
+        h3scf->quic.idle_timeout = clcf->keepalive_timeout;
         ngx_quic_run(c, &h3scf->quic);
         return;
     }


More information about the nginx-devel mailing list