changeset 8924:d6ef13c5fd8e quic

QUIC: simplified configuration. Directives that set transport parameters are removed from the configuration. Corresponding values are derived from the quic configuration or initialized to default. Whenever possible, quic configuration parameters are taken from higher-level protocol settings, i.e. HTTP/3.
author Vladimir Homutov <vl@nginx.com>
date Mon, 06 Dec 2021 15:19:54 +0300
parents 651cc905b7c2
children 18d23ed15eef
files README src/event/quic/ngx_event_quic.c src/event/quic/ngx_event_quic.h src/event/quic/ngx_event_quic_streams.c src/event/quic/ngx_event_quic_transport.c src/event/quic/ngx_event_quic_transport.h src/http/v3/ngx_http_v3.h src/http/v3/ngx_http_v3_module.c src/http/v3/ngx_http_v3_request.c src/http/v3/ngx_http_v3_streams.c src/stream/ngx_stream_quic_module.c
diffstat 11 files changed, 163 insertions(+), 413 deletions(-) [+]
line wrap: on
line diff
--- a/README
+++ b/README
@@ -98,21 +98,6 @@ 3. Configuration
     Along with "http3" or "quic", you also have to specify "reuseport"
     option [6] to make it work properly with multiple workers.
 
-    A number of directives were added that specify transport parameter values:
-
-        quic_max_idle_timeout
-        quic_max_ack_delay
-        quic_max_udp_payload_size
-        quic_initial_max_data
-        quic_initial_max_stream_data_bidi_local
-        quic_initial_max_stream_data_bidi_remote
-        quic_initial_max_stream_data_uni
-        quic_initial_max_streams_bidi
-        quic_initial_max_streams_uni
-        quic_ack_delay_exponent
-        quic_disable_active_migration
-        quic_active_connection_id_limit
-
     To enable address validation:
 
         quic_retry on;
@@ -129,14 +114,23 @@ 3. Configuration
 
         quic_gso on;
 
+    To limit maximum packet size:
+
+        quic_mtu <size>;
+
+    To set host key for various tokens:
+
+        quic_host_key <filename>;
+
+
     By default this Linux-specific optimization [8] is disabled.
     Enable if your network interface is configured to support GSO.
 
     A number of directives were added that configure HTTP/3:
 
-        http3_max_table_capacity
-        http3_max_blocked_streams
+        http3_stream_buffer_size
         http3_max_concurrent_pushes
+        http3_max_concurrent_streams
         http3_push
         http3_push_preload
         http3_hq (requires NGX_HTTP_V3_HQ macro)
--- a/src/event/quic/ngx_event_quic.c
+++ b/src/event/quic/ngx_event_quic.c
@@ -294,7 +294,10 @@ ngx_quic_new_connection(ngx_connection_t
     qc->path_validation.cancelable = 1;
 
     qc->conf = conf;
-    qc->tp = conf->tp;
+
+    if (ngx_quic_init_transport_params(&qc->tp, conf) != NGX_OK) {
+        return NULL;
+    }
 
     ctp = &qc->ctp;
 
--- a/src/event/quic/ngx_event_quic.h
+++ b/src/event/quic/ngx_event_quic.h
@@ -27,43 +27,23 @@
 #define NGX_QUIC_STREAM_SERVER_INITIATED     0x01
 #define NGX_QUIC_STREAM_UNIDIRECTIONAL       0x02
 
-#define NGX_QUIC_STREAM_BUFSIZE              65536
-
-
-typedef struct {
-    /* configurable */
-    ngx_msec_t                 max_idle_timeout;
-    ngx_msec_t                 max_ack_delay;
-
-    size_t                     max_udp_payload_size;
-    size_t                     initial_max_data;
-    size_t                     initial_max_stream_data_bidi_local;
-    size_t                     initial_max_stream_data_bidi_remote;
-    size_t                     initial_max_stream_data_uni;
-    ngx_uint_t                 initial_max_streams_bidi;
-    ngx_uint_t                 initial_max_streams_uni;
-    ngx_uint_t                 ack_delay_exponent;
-    ngx_uint_t                 active_connection_id_limit;
-    ngx_flag_t                 disable_active_migration;
-    ngx_str_t                  original_dcid;
-    ngx_str_t                  initial_scid;
-    ngx_str_t                  retry_scid;
-    u_char                     sr_token[NGX_QUIC_SR_TOKEN_LEN];
-
-    /* TODO */
-    void                      *preferred_address;
-} ngx_quic_tp_t;
-
 
 typedef struct {
     ngx_ssl_t                 *ssl;
-    ngx_quic_tp_t              tp;
+
     ngx_flag_t                 retry;
     ngx_flag_t                 gso_enabled;
+    ngx_flag_t                 disable_active_migration;
+    ngx_msec_t                 timeout;
     ngx_str_t                  host_key;
+    size_t                     mtu;
+    size_t                     stream_buffer_size;
+    ngx_uint_t                 max_concurrent_streams_bidi;
+    ngx_uint_t                 max_concurrent_streams_uni;
     ngx_int_t                  stream_close_code;
     ngx_int_t                  stream_reject_code_uni;
     ngx_int_t                  stream_reject_code_bidi;
+
     u_char                     av_token_key[NGX_QUIC_AV_KEY_LEN];
     u_char                     sr_token_key[NGX_QUIC_SR_KEY_LEN];
 } ngx_quic_conf_t;
--- a/src/event/quic/ngx_event_quic_streams.c
+++ b/src/event/quic/ngx_event_quic_streams.c
@@ -851,7 +851,7 @@ ngx_quic_max_stream_flow(ngx_connection_
     qs = c->quic;
     qc = ngx_quic_get_connection(qs->parent);
 
-    size = NGX_QUIC_STREAM_BUFSIZE;
+    size = qc->conf->stream_buffer_size;
     sent = c->sent;
     unacked = sent - qs->acked;
 
@@ -859,15 +859,13 @@ ngx_quic_max_stream_flow(ngx_connection_
         qc->streams.send_max_data = qc->ctp.initial_max_data;
     }
 
-    if (unacked >= NGX_QUIC_STREAM_BUFSIZE) {
+    if (unacked >= size) {
         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
                        "quic send flow hit buffer size");
         return 0;
     }
 
-    if (unacked + size > NGX_QUIC_STREAM_BUFSIZE) {
-        size = NGX_QUIC_STREAM_BUFSIZE - unacked;
-    }
+    size -= unacked;
 
     if (qc->streams.sent >= qc->streams.send_max_data) {
         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
@@ -1493,7 +1491,7 @@ ngx_quic_handle_stream_ack(ngx_connectio
     sent = qs->connection->sent;
     unacked = sent - qs->acked;
 
-    if (unacked >= NGX_QUIC_STREAM_BUFSIZE && wev->active) {
+    if (unacked >= qc->conf->stream_buffer_size && wev->active) {
         wev->ready = 1;
         ngx_post_event(wev, &ngx_posted_events);
     }
--- a/src/event/quic/ngx_event_quic_transport.c
+++ b/src/event/quic/ngx_event_quic_transport.c
@@ -1937,6 +1937,50 @@ ngx_quic_create_retire_connection_id(u_c
 }
 
 
+ngx_int_t
+ngx_quic_init_transport_params(ngx_quic_tp_t *tp, ngx_quic_conf_t *qcf)
+{
+    ngx_uint_t  nstreams;
+
+    ngx_memzero(tp, sizeof(ngx_quic_tp_t));
+
+    /*
+     * set by ngx_memzero():
+     *
+     *     tp->disable_active_migration = 0;
+     *     tp->original_dcid = { 0, NULL };
+     *     tp->initial_scid = { 0, NULL };
+     *     tp->retry_scid = { 0, NULL };
+     *     tp->sr_token = { 0 }
+     *     tp->sr_enabled = 0
+     *     tp->preferred_address = NULL
+     */
+
+    tp->max_idle_timeout = qcf->timeout;
+
+    tp->max_udp_payload_size = qcf->mtu;
+
+    nstreams = qcf->max_concurrent_streams_bidi
+               + qcf->max_concurrent_streams_uni;
+
+    tp->initial_max_data = nstreams * qcf->stream_buffer_size;
+    tp->initial_max_stream_data_bidi_local = qcf->stream_buffer_size;
+    tp->initial_max_stream_data_bidi_remote = qcf->stream_buffer_size;
+    tp->initial_max_stream_data_uni = qcf->stream_buffer_size;
+
+    tp->initial_max_streams_bidi = qcf->max_concurrent_streams_bidi;
+    tp->initial_max_streams_uni = qcf->max_concurrent_streams_uni;
+
+    tp->max_ack_delay = NGX_QUIC_DEFAULT_MAX_ACK_DELAY;
+    tp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT;
+
+    tp->active_connection_id_limit = 2;
+    tp->disable_active_migration = qcf->disable_active_migration;
+
+    return NGX_OK;
+}
+
+
 ssize_t
 ngx_quic_create_transport_params(u_char *pos, u_char *end, ngx_quic_tp_t *tp,
     size_t *clen)
--- a/src/event/quic/ngx_event_quic_transport.h
+++ b/src/event/quic/ngx_event_quic_transport.h
@@ -338,6 +338,31 @@ typedef struct {
 } ngx_quic_header_t;
 
 
+typedef struct {
+    ngx_msec_t                 max_idle_timeout;
+    ngx_msec_t                 max_ack_delay;
+
+    size_t                     max_udp_payload_size;
+    size_t                     initial_max_data;
+    size_t                     initial_max_stream_data_bidi_local;
+    size_t                     initial_max_stream_data_bidi_remote;
+    size_t                     initial_max_stream_data_uni;
+    ngx_uint_t                 initial_max_streams_bidi;
+    ngx_uint_t                 initial_max_streams_uni;
+    ngx_uint_t                 ack_delay_exponent;
+    ngx_uint_t                 active_connection_id_limit;
+    ngx_flag_t                 disable_active_migration;
+
+    ngx_str_t                  original_dcid;
+    ngx_str_t                  initial_scid;
+    ngx_str_t                  retry_scid;
+    u_char                     sr_token[NGX_QUIC_SR_TOKEN_LEN];
+
+    /* TODO */
+    void                      *preferred_address;
+} ngx_quic_tp_t;
+
+
 ngx_int_t ngx_quic_parse_packet(ngx_quic_header_t *pkt);
 
 size_t ngx_quic_create_version_negotiation(ngx_quic_header_t *pkt, u_char *out);
@@ -358,6 +383,8 @@ ssize_t ngx_quic_parse_ack_range(ngx_log
     u_char *end, uint64_t *gap, uint64_t *range);
 size_t ngx_quic_create_ack_range(u_char *p, uint64_t gap, uint64_t range);
 
+ngx_int_t ngx_quic_init_transport_params(ngx_quic_tp_t *tp,
+    ngx_quic_conf_t *qcf);
 ngx_int_t ngx_quic_parse_transport_params(u_char *p, u_char *end,
     ngx_quic_tp_t *tp, ngx_log_t *log);
 ssize_t ngx_quic_create_transport_params(u_char *p, u_char *end,
--- a/src/http/v3/ngx_http_v3.h
+++ b/src/http/v3/ngx_http_v3.h
@@ -45,6 +45,8 @@
 #define NGX_HTTP_V3_PARAM_MAX_HEADER_LIST_SIZE     0x06
 #define NGX_HTTP_V3_PARAM_BLOCKED_STREAMS          0x07
 
+#define NGX_HTTP_V3_MAX_TABLE_CAPACITY             4096
+
 #define NGX_HTTP_V3_STREAM_CLIENT_CONTROL          0
 #define NGX_HTTP_V3_STREAM_SERVER_CONTROL          1
 #define NGX_HTTP_V3_STREAM_CLIENT_ENCODER          2
@@ -52,6 +54,7 @@
 #define NGX_HTTP_V3_STREAM_CLIENT_DECODER          4
 #define NGX_HTTP_V3_STREAM_SERVER_DECODER          5
 #define NGX_HTTP_V3_MAX_KNOWN_STREAM               6
+#define NGX_HTTP_V3_MAX_UNI_STREAMS                3
 
 /* HTTP/3 errors */
 #define NGX_HTTP_V3_ERR_NO_ERROR                   0x100
@@ -101,7 +104,7 @@ typedef struct {
     size_t                        max_table_capacity;
     ngx_uint_t                    max_blocked_streams;
     ngx_uint_t                    max_concurrent_pushes;
-    ngx_uint_t                    max_uni_streams;
+    ngx_uint_t                    max_concurrent_streams;
 #if (NGX_HTTP_V3_HQ)
     ngx_flag_t                    hq;
 #endif
--- a/src/http/v3/ngx_http_v3_module.c
+++ b/src/http/v3/ngx_http_v3_module.c
@@ -16,9 +16,7 @@ static ngx_int_t ngx_http_v3_add_variabl
 static void *ngx_http_v3_create_srv_conf(ngx_conf_t *cf);
 static char *ngx_http_v3_merge_srv_conf(ngx_conf_t *cf, void *parent,
     void *child);
-static char *ngx_http_quic_max_ack_delay(ngx_conf_t *cf, void *post,
-    void *data);
-static char *ngx_http_quic_max_udp_payload_size(ngx_conf_t *cf, void *post,
+static char *ngx_http_quic_mtu(ngx_conf_t *cf, void *post,
     void *data);
 static char *ngx_http_quic_host_key(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
@@ -28,32 +26,12 @@ static char *ngx_http_v3_merge_loc_conf(
 static char *ngx_http_v3_push(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 
 
-static ngx_conf_post_t  ngx_http_quic_max_ack_delay_post =
-    { ngx_http_quic_max_ack_delay };
-static ngx_conf_post_t  ngx_http_quic_max_udp_payload_size_post =
-    { ngx_http_quic_max_udp_payload_size };
-static ngx_conf_num_bounds_t  ngx_http_quic_ack_delay_exponent_bounds =
-    { ngx_conf_check_num_bounds, 0, 20 };
-static ngx_conf_num_bounds_t  ngx_http_quic_active_connection_id_limit_bounds =
-    { ngx_conf_check_num_bounds, 2, -1 };
+static ngx_conf_post_t  ngx_http_quic_mtu_post =
+    { ngx_http_quic_mtu };
 
 
 static ngx_command_t  ngx_http_v3_commands[] = {
 
-    { ngx_string("http3_max_table_capacity"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_size_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, max_table_capacity),
-      NULL },
-
-    { ngx_string("http3_max_blocked_streams"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_num_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, max_blocked_streams),
-      NULL },
-
     { ngx_string("http3_max_concurrent_pushes"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_num_slot,
@@ -61,11 +39,11 @@ static ngx_command_t  ngx_http_v3_comman
       offsetof(ngx_http_v3_srv_conf_t, max_concurrent_pushes),
       NULL },
 
-    { ngx_string("http3_max_uni_streams"),
+    { ngx_string("http3_max_concurrent_streams"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_num_slot,
       NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, max_uni_streams),
+      offsetof(ngx_http_v3_srv_conf_t, max_concurrent_streams),
       NULL },
 
 #if (NGX_HTTP_V3_HQ)
@@ -91,92 +69,13 @@ static ngx_command_t  ngx_http_v3_comman
       offsetof(ngx_http_v3_loc_conf_t, push_preload),
       NULL },
 
-    { ngx_string("quic_max_idle_timeout"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_msec_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, quic.tp.max_idle_timeout),
-      NULL },
-
-    { ngx_string("quic_max_ack_delay"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_msec_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, quic.tp.max_ack_delay),
-      &ngx_http_quic_max_ack_delay_post },
-
-    { ngx_string("quic_max_udp_payload_size"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_size_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, quic.tp.max_udp_payload_size),
-      &ngx_http_quic_max_udp_payload_size_post },
-
-    { ngx_string("quic_initial_max_data"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_size_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, quic.tp.initial_max_data),
-      NULL },
-
-    { ngx_string("quic_initial_max_stream_data_bidi_local"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_size_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t,
-               quic.tp.initial_max_stream_data_bidi_local),
-      NULL },
-
-    { ngx_string("quic_initial_max_stream_data_bidi_remote"),
+    { ngx_string("http3_stream_buffer_size"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_size_slot,
       NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t,
-               quic.tp.initial_max_stream_data_bidi_remote),
-      NULL },
-
-    { ngx_string("quic_initial_max_stream_data_uni"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_size_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, quic.tp.initial_max_stream_data_uni),
-      NULL },
-
-    { ngx_string("quic_initial_max_streams_bidi"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_num_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, quic.tp.initial_max_streams_bidi),
+      offsetof(ngx_http_v3_srv_conf_t, quic.stream_buffer_size),
       NULL },
 
-    { ngx_string("quic_initial_max_streams_uni"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_num_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, quic.tp.initial_max_streams_uni),
-      NULL },
-
-    { ngx_string("quic_ack_delay_exponent"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_num_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, quic.tp.ack_delay_exponent),
-      &ngx_http_quic_ack_delay_exponent_bounds },
-
-    { ngx_string("quic_disable_active_migration"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_flag_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, quic.tp.disable_active_migration),
-      NULL },
-
-    { ngx_string("quic_active_connection_id_limit"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_num_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_v3_srv_conf_t, quic.tp.active_connection_id_limit),
-      &ngx_http_quic_active_connection_id_limit_bounds },
-
     { ngx_string("quic_retry"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
       ngx_conf_set_flag_slot,
@@ -191,6 +90,13 @@ static ngx_command_t  ngx_http_v3_comman
       offsetof(ngx_http_v3_srv_conf_t, quic.gso_enabled),
       NULL },
 
+    { ngx_string("quic_mtu"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_size_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_v3_srv_conf_t, quic.mtu),
+      &ngx_http_quic_mtu_post },
+
     { ngx_string("quic_host_key"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
       ngx_http_quic_host_key,
@@ -313,37 +219,23 @@ ngx_http_v3_create_srv_conf(ngx_conf_t *
     /*
      * set by ngx_pcalloc():
      *
-     *     h3scf->quic.tp.original_dcid = { 0, NULL };
-     *     h3scf->quic.tp.initial_scid = { 0, NULL };
-     *     h3scf->quic.tp.retry_scid = { 0, NULL };
-     *     h3scf->quic.tp.sr_token = { 0 }
-     *     h3scf->quic.tp.sr_enabled = 0
-     *     h3scf->quic.tp.preferred_address = NULL
      *     h3scf->quic.host_key = { 0, NULL }
      *     h3scf->quic.stream_reject_code_uni = 0;
+     *     h3scf->quic.disable_active_migration = 0;
+     *     h3scf->quic.timeout = 0;
+     *     h3scf->max_blocked_streams = 0;
      */
-
-    h3scf->max_table_capacity = NGX_CONF_UNSET_SIZE;
-    h3scf->max_blocked_streams = NGX_CONF_UNSET_UINT;
+    h3scf->max_table_capacity = NGX_HTTP_V3_MAX_TABLE_CAPACITY;
     h3scf->max_concurrent_pushes = NGX_CONF_UNSET_UINT;
-    h3scf->max_uni_streams = NGX_CONF_UNSET_UINT;
+    h3scf->max_concurrent_streams = NGX_CONF_UNSET_UINT;
 #if (NGX_HTTP_V3_HQ)
     h3scf->hq = NGX_CONF_UNSET;
 #endif
 
-    h3scf->quic.tp.max_idle_timeout = NGX_CONF_UNSET_MSEC;
-    h3scf->quic.tp.max_ack_delay = NGX_CONF_UNSET_MSEC;
-    h3scf->quic.tp.max_udp_payload_size = NGX_CONF_UNSET_SIZE;
-    h3scf->quic.tp.initial_max_data = NGX_CONF_UNSET_SIZE;
-    h3scf->quic.tp.initial_max_stream_data_bidi_local = NGX_CONF_UNSET_SIZE;
-    h3scf->quic.tp.initial_max_stream_data_bidi_remote = NGX_CONF_UNSET_SIZE;
-    h3scf->quic.tp.initial_max_stream_data_uni = NGX_CONF_UNSET_SIZE;
-    h3scf->quic.tp.initial_max_streams_bidi = NGX_CONF_UNSET_UINT;
-    h3scf->quic.tp.initial_max_streams_uni = NGX_CONF_UNSET_UINT;
-    h3scf->quic.tp.ack_delay_exponent = NGX_CONF_UNSET_UINT;
-    h3scf->quic.tp.disable_active_migration = NGX_CONF_UNSET;
-    h3scf->quic.tp.active_connection_id_limit = NGX_CONF_UNSET_UINT;
-
+    h3scf->quic.mtu = NGX_CONF_UNSET_SIZE;
+    h3scf->quic.stream_buffer_size = NGX_CONF_UNSET_SIZE;
+    h3scf->quic.max_concurrent_streams_bidi = NGX_CONF_UNSET_UINT;
+    h3scf->quic.max_concurrent_streams_uni = NGX_HTTP_V3_MAX_UNI_STREAMS;
     h3scf->quic.retry = NGX_CONF_UNSET;
     h3scf->quic.gso_enabled = NGX_CONF_UNSET;
     h3scf->quic.stream_close_code = NGX_HTTP_V3_ERR_NO_ERROR;
@@ -361,64 +253,27 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *c
 
     ngx_http_ssl_srv_conf_t  *sscf;
 
-    ngx_conf_merge_size_value(conf->max_table_capacity,
-                              prev->max_table_capacity, 16384);
-
-    ngx_conf_merge_uint_value(conf->max_blocked_streams,
-                              prev->max_blocked_streams, 16);
-
     ngx_conf_merge_uint_value(conf->max_concurrent_pushes,
                               prev->max_concurrent_pushes, 10);
 
-    ngx_conf_merge_uint_value(conf->max_uni_streams,
-                              prev->max_uni_streams, 3);
+    ngx_conf_merge_uint_value(conf->max_concurrent_streams,
+                              prev->max_concurrent_streams, 128);
+
+    conf->max_blocked_streams = conf->max_concurrent_streams;
 
 #if (NGX_HTTP_V3_HQ)
     ngx_conf_merge_value(conf->hq, prev->hq, 0);
 #endif
 
-    ngx_conf_merge_msec_value(conf->quic.tp.max_idle_timeout,
-                              prev->quic.tp.max_idle_timeout, 60000);
 
-    ngx_conf_merge_msec_value(conf->quic.tp.max_ack_delay,
-                              prev->quic.tp.max_ack_delay,
-                              NGX_QUIC_DEFAULT_MAX_ACK_DELAY);
-
-    ngx_conf_merge_size_value(conf->quic.tp.max_udp_payload_size,
-                              prev->quic.tp.max_udp_payload_size,
+    ngx_conf_merge_size_value(conf->quic.mtu, prev->quic.mtu,
                               NGX_QUIC_MAX_UDP_PAYLOAD_SIZE);
 
-    ngx_conf_merge_size_value(conf->quic.tp.initial_max_data,
-                              prev->quic.tp.initial_max_data,
-                              16 * NGX_QUIC_STREAM_BUFSIZE);
-
-    ngx_conf_merge_size_value(conf->quic.tp.initial_max_stream_data_bidi_local,
-                              prev->quic.tp.initial_max_stream_data_bidi_local,
-                              NGX_QUIC_STREAM_BUFSIZE);
-
-    ngx_conf_merge_size_value(conf->quic.tp.initial_max_stream_data_bidi_remote,
-                              prev->quic.tp.initial_max_stream_data_bidi_remote,
-                              NGX_QUIC_STREAM_BUFSIZE);
-
-    ngx_conf_merge_size_value(conf->quic.tp.initial_max_stream_data_uni,
-                              prev->quic.tp.initial_max_stream_data_uni,
-                              NGX_QUIC_STREAM_BUFSIZE);
+    ngx_conf_merge_size_value(conf->quic.stream_buffer_size,
+                              prev->quic.stream_buffer_size,
+                              65536);
 
-    ngx_conf_merge_uint_value(conf->quic.tp.initial_max_streams_bidi,
-                              prev->quic.tp.initial_max_streams_bidi, 16);
-
-    ngx_conf_merge_uint_value(conf->quic.tp.initial_max_streams_uni,
-                              prev->quic.tp.initial_max_streams_uni, 3);
-
-    ngx_conf_merge_uint_value(conf->quic.tp.ack_delay_exponent,
-                              prev->quic.tp.ack_delay_exponent,
-                              NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT);
-
-    ngx_conf_merge_value(conf->quic.tp.disable_active_migration,
-                              prev->quic.tp.disable_active_migration, 0);
-
-    ngx_conf_merge_uint_value(conf->quic.tp.active_connection_id_limit,
-                              prev->quic.tp.active_connection_id_limit, 2);
+    conf->quic.max_concurrent_streams_bidi = conf->max_concurrent_streams;
 
     ngx_conf_merge_value(conf->quic.retry, prev->quic.retry, 0);
     ngx_conf_merge_value(conf->quic.gso_enabled, prev->quic.gso_enabled, 0);
@@ -465,23 +320,7 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *c
 
 
 static char *
-ngx_http_quic_max_ack_delay(ngx_conf_t *cf, void *post, void *data)
-{
-    ngx_msec_t *sp = data;
-
-    if (*sp >= 16384) {
-        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                           "\"quic_max_ack_delay\" must be less than 16384");
-
-        return NGX_CONF_ERROR;
-    }
-
-    return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_quic_max_udp_payload_size(ngx_conf_t *cf, void *post, void *data)
+ngx_http_quic_mtu(ngx_conf_t *cf, void *post, void *data)
 {
     size_t *sp = data;
 
@@ -489,8 +328,7 @@ ngx_http_quic_max_udp_payload_size(ngx_c
         || *sp > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE)
     {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                           "\"quic_max_udp_payload_size\" must be between "
-                           "%d and %d",
+                           "\"quic_mtu\" must be between %d and %d",
                            NGX_QUIC_MIN_INITIAL_SIZE,
                            NGX_QUIC_MAX_UDP_PAYLOAD_SIZE);
 
--- a/src/http/v3/ngx_http_v3_request.c
+++ b/src/http/v3/ngx_http_v3_request.c
@@ -66,9 +66,11 @@ ngx_http_v3_init(ngx_connection_t *c)
 
     hc->ssl = 1;
 
+    clcf = ngx_http_get_module_loc_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) {
+        h3scf->quic.timeout = clcf->keepalive_timeout;
         ngx_quic_run(c, &h3scf->quic);
         return;
     }
@@ -79,7 +81,6 @@ ngx_http_v3_init(ngx_connection_t *c)
         hc->ssl_servername = phc->ssl_servername;
         hc->conf_ctx = phc->conf_ctx;
 
-        clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);
         ngx_set_connection_log(c, clcf->error_log);
     }
 
--- a/src/http/v3/ngx_http_v3_streams.c
+++ b/src/http/v3/ngx_http_v3_streams.c
@@ -36,16 +36,13 @@ void
 ngx_http_v3_init_uni_stream(ngx_connection_t *c)
 {
     uint64_t                   n;
-    ngx_http_v3_srv_conf_t    *h3scf;
     ngx_http_v3_uni_stream_t  *us;
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init uni stream");
 
-    h3scf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module);
-
     n = c->quic->id >> 2;
 
-    if (n >= h3scf->max_uni_streams) {
+    if (n >= NGX_HTTP_V3_MAX_UNI_STREAMS) {
         ngx_http_v3_finalize_connection(c,
                                       NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR,
                                       "reached maximum number of uni streams");
--- a/src/stream/ngx_stream_quic_module.c
+++ b/src/stream/ngx_stream_quic_module.c
@@ -16,111 +16,36 @@ static ngx_int_t ngx_stream_quic_add_var
 static void *ngx_stream_quic_create_srv_conf(ngx_conf_t *cf);
 static char *ngx_stream_quic_merge_srv_conf(ngx_conf_t *cf, void *parent,
     void *child);
-static char *ngx_stream_quic_max_ack_delay(ngx_conf_t *cf, void *post,
-    void *data);
-static char *ngx_stream_quic_max_udp_payload_size(ngx_conf_t *cf, void *post,
-    void *data);
+static char *ngx_stream_quic_mtu(ngx_conf_t *cf, void *post, void *data);
 static char *ngx_stream_quic_host_key(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 
-
-static ngx_conf_post_t  ngx_stream_quic_max_ack_delay_post =
-    { ngx_stream_quic_max_ack_delay };
-static ngx_conf_post_t  ngx_stream_quic_max_udp_payload_size_post =
-    { ngx_stream_quic_max_udp_payload_size };
-static ngx_conf_num_bounds_t  ngx_stream_quic_ack_delay_exponent_bounds =
-    { ngx_conf_check_num_bounds, 0, 20 };
-static ngx_conf_num_bounds_t
-                            ngx_stream_quic_active_connection_id_limit_bounds =
-    { ngx_conf_check_num_bounds, 2, -1 };
-
+static ngx_conf_post_t  ngx_stream_quic_mtu_post =
+    { ngx_stream_quic_mtu };
 
 static ngx_command_t  ngx_stream_quic_commands[] = {
 
-    { ngx_string("quic_max_idle_timeout"),
-      NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_msec_slot,
-      NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.max_idle_timeout),
-      NULL },
-
-    { ngx_string("quic_max_ack_delay"),
+    { ngx_string("quic_timeout"),
       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_msec_slot,
       NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.max_ack_delay),
-      &ngx_stream_quic_max_ack_delay_post },
+      offsetof(ngx_quic_conf_t, timeout),
+      NULL },
 
-    { ngx_string("quic_max_udp_payload_size"),
-      NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_size_slot,
-      NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.max_udp_payload_size),
-      &ngx_stream_quic_max_udp_payload_size_post },
-
-    { ngx_string("quic_initial_max_data"),
+    { ngx_string("quic_mtu"),
       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_size_slot,
       NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.initial_max_data),
-      NULL },
+      offsetof(ngx_quic_conf_t, mtu),
+      &ngx_stream_quic_mtu_post },
 
-    { ngx_string("quic_initial_max_stream_data_bidi_local"),
-      NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_size_slot,
-      NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.initial_max_stream_data_bidi_local),
-      NULL },
-
-    { ngx_string("quic_initial_max_stream_data_bidi_remote"),
-      NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_size_slot,
-      NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.initial_max_stream_data_bidi_remote),
-      NULL },
-
-    { ngx_string("quic_initial_max_stream_data_uni"),
+    { ngx_string("quic_stream_buffer_size"),
       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_size_slot,
       NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.initial_max_stream_data_uni),
-      NULL },
-
-    { ngx_string("quic_initial_max_streams_bidi"),
-      NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_num_slot,
-      NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.initial_max_streams_bidi),
-      NULL },
-
-    { ngx_string("quic_initial_max_streams_uni"),
-      NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_num_slot,
-      NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.initial_max_streams_uni),
+      offsetof(ngx_quic_conf_t, stream_buffer_size),
       NULL },
 
-    { ngx_string("quic_ack_delay_exponent"),
-      NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_num_slot,
-      NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.ack_delay_exponent),
-      &ngx_stream_quic_ack_delay_exponent_bounds },
-
-    { ngx_string("quic_disable_active_migration"),
-      NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_flag_slot,
-      NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.disable_active_migration),
-      NULL },
-
-    { ngx_string("quic_active_connection_id_limit"),
-      NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_num_slot,
-      NGX_STREAM_SRV_CONF_OFFSET,
-      offsetof(ngx_quic_conf_t, tp.active_connection_id_limit),
-      &ngx_stream_quic_active_connection_id_limit_bounds },
-
     { ngx_string("quic_retry"),
       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
       ngx_conf_set_flag_slot,
@@ -236,28 +161,17 @@ ngx_stream_quic_create_srv_conf(ngx_conf
     /*
      * set by ngx_pcalloc():
      *
-     *     conf->tp.original_dcid = { 0, NULL };
-     *     conf->tp.initial_scid = { 0, NULL };
-     *     conf->tp.retry_scid = { 0, NULL };
-     *     conf->tp.preferred_address = NULL
      *     conf->host_key = { 0, NULL }
      *     conf->stream_close_code = 0;
      *     conf->stream_reject_code_uni = 0;
      *     conf->stream_reject_code_bidi= 0;
      */
 
-    conf->tp.max_idle_timeout = NGX_CONF_UNSET_MSEC;
-    conf->tp.max_ack_delay = NGX_CONF_UNSET_MSEC;
-    conf->tp.max_udp_payload_size = NGX_CONF_UNSET_SIZE;
-    conf->tp.initial_max_data = NGX_CONF_UNSET_SIZE;
-    conf->tp.initial_max_stream_data_bidi_local = NGX_CONF_UNSET_SIZE;
-    conf->tp.initial_max_stream_data_bidi_remote = NGX_CONF_UNSET_SIZE;
-    conf->tp.initial_max_stream_data_uni = NGX_CONF_UNSET_SIZE;
-    conf->tp.initial_max_streams_bidi = NGX_CONF_UNSET_UINT;
-    conf->tp.initial_max_streams_uni = NGX_CONF_UNSET_UINT;
-    conf->tp.ack_delay_exponent = NGX_CONF_UNSET_UINT;
-    conf->tp.disable_active_migration = NGX_CONF_UNSET;
-    conf->tp.active_connection_id_limit = NGX_CONF_UNSET_UINT;
+    conf->timeout = NGX_CONF_UNSET_MSEC;
+    conf->mtu = NGX_CONF_UNSET_SIZE;
+    conf->stream_buffer_size = NGX_CONF_UNSET_SIZE;
+    conf->max_concurrent_streams_bidi = NGX_CONF_UNSET_UINT;
+    conf->max_concurrent_streams_uni = NGX_CONF_UNSET_UINT;
 
     conf->retry = NGX_CONF_UNSET;
     conf->gso_enabled = NGX_CONF_UNSET;
@@ -274,48 +188,16 @@ ngx_stream_quic_merge_srv_conf(ngx_conf_
 
     ngx_stream_ssl_conf_t  *scf;
 
-    ngx_conf_merge_msec_value(conf->tp.max_idle_timeout,
-                              prev->tp.max_idle_timeout, 60000);
+    ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
 
-    ngx_conf_merge_msec_value(conf->tp.max_ack_delay,
-                              prev->tp.max_ack_delay,
-                              NGX_QUIC_DEFAULT_MAX_ACK_DELAY);
-
-    ngx_conf_merge_size_value(conf->tp.max_udp_payload_size,
-                              prev->tp.max_udp_payload_size,
+    ngx_conf_merge_size_value(conf->mtu, prev->mtu,
                               NGX_QUIC_MAX_UDP_PAYLOAD_SIZE);
 
-    ngx_conf_merge_size_value(conf->tp.initial_max_data,
-                              prev->tp.initial_max_data,
-                              16 * NGX_QUIC_STREAM_BUFSIZE);
-
-    ngx_conf_merge_size_value(conf->tp.initial_max_stream_data_bidi_local,
-                              prev->tp.initial_max_stream_data_bidi_local,
-                              NGX_QUIC_STREAM_BUFSIZE);
-
-    ngx_conf_merge_size_value(conf->tp.initial_max_stream_data_bidi_remote,
-                              prev->tp.initial_max_stream_data_bidi_remote,
-                              NGX_QUIC_STREAM_BUFSIZE);
-
-    ngx_conf_merge_size_value(conf->tp.initial_max_stream_data_uni,
-                              prev->tp.initial_max_stream_data_uni,
-                              NGX_QUIC_STREAM_BUFSIZE);
+    ngx_conf_merge_uint_value(conf->max_concurrent_streams_bidi,
+                              prev->max_concurrent_streams_bidi, 16);
 
-    ngx_conf_merge_uint_value(conf->tp.initial_max_streams_bidi,
-                              prev->tp.initial_max_streams_bidi, 16);
-
-    ngx_conf_merge_uint_value(conf->tp.initial_max_streams_uni,
-                              prev->tp.initial_max_streams_uni, 16);
-
-    ngx_conf_merge_uint_value(conf->tp.ack_delay_exponent,
-                              prev->tp.ack_delay_exponent,
-                              NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT);
-
-    ngx_conf_merge_value(conf->tp.disable_active_migration,
-                              prev->tp.disable_active_migration, 0);
-
-    ngx_conf_merge_uint_value(conf->tp.active_connection_id_limit,
-                              prev->tp.active_connection_id_limit, 2);
+    ngx_conf_merge_uint_value(conf->max_concurrent_streams_uni,
+                              prev->max_concurrent_streams_uni, 3);
 
     ngx_conf_merge_value(conf->retry, prev->retry, 0);
     ngx_conf_merge_value(conf->gso_enabled, prev->gso_enabled, 0);
@@ -361,23 +243,7 @@ ngx_stream_quic_merge_srv_conf(ngx_conf_
 
 
 static char *
-ngx_stream_quic_max_ack_delay(ngx_conf_t *cf, void *post, void *data)
-{
-    ngx_msec_t *sp = data;
-
-    if (*sp >= 16384) {
-        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                           "\"quic_max_ack_delay\" must be less than 16384");
-
-        return NGX_CONF_ERROR;
-    }
-
-    return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_stream_quic_max_udp_payload_size(ngx_conf_t *cf, void *post, void *data)
+ngx_stream_quic_mtu(ngx_conf_t *cf, void *post, void *data)
 {
     size_t *sp = data;
 
@@ -385,8 +251,7 @@ ngx_stream_quic_max_udp_payload_size(ngx
         || *sp > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE)
     {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                           "\"quic_max_udp_payload_size\" must be between "
-                           "%d and %d",
+                           "\"quic_mtu\" must be between %d and %d",
                            NGX_QUIC_MIN_INITIAL_SIZE,
                            NGX_QUIC_MAX_UDP_PAYLOAD_SIZE);