diff --git a/gennghttpxfun.py b/gennghttpxfun.py index af8d60a5..6f88456e 100755 --- a/gennghttpxfun.py +++ b/gennghttpxfun.py @@ -197,6 +197,7 @@ OPTIONS = [ "rlimit-memlock", "max-worker-processes", "worker-process-grace-shutdown-period", + "frontend-quic-initial-rtt", ] LOGVARS = [ diff --git a/src/shrpx.cc b/src/shrpx.cc index 1cdc2c59..a36c168b 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -1958,6 +1958,8 @@ void fill_default_config(Config *config) { assert(0); abort(); } + + upstreamconf.initial_rtt = NGTCP2_DEFAULT_INITIAL_RTT; } auto &http3conf = config->http3; @@ -3399,6 +3401,13 @@ HTTP/3 and QUIC: (which is 8 bytes long). If this option is omitted, a random server ID is generated on startup and configuration reload. + --frontend-quic-initial-rtt= + Specify the initial RTT of the frontend QUIC connection. + Default: )" + << util::duration_str( + static_cast(config->quic.upstream.initial_rtt) / + NGTCP2_SECONDS) + << R"( --no-quic-bpf Disable eBPF. --frontend-http3-window-size= @@ -4218,6 +4227,8 @@ int main(int argc, char **argv) { {SHRPX_OPT_MAX_WORKER_PROCESSES.c_str(), required_argument, &flag, 188}, {SHRPX_OPT_WORKER_PROCESS_GRACE_SHUTDOWN_PERIOD.c_str(), required_argument, &flag, 189}, + {SHRPX_OPT_FRONTEND_QUIC_INITIAL_RTT.c_str(), required_argument, &flag, + 190}, {nullptr, 0, nullptr, 0}}; int option_index = 0; @@ -5118,6 +5129,11 @@ int main(int argc, char **argv) { cmdcfgs.emplace_back(SHRPX_OPT_WORKER_PROCESS_GRACE_SHUTDOWN_PERIOD, StringRef{optarg}); break; + case 190: + // --frontend-quic-initial-rtt + cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_QUIC_INITIAL_RTT, + StringRef{optarg}); + break; default: break; } diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index ac260b55..25576c70 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -2440,6 +2440,11 @@ int option_lookup_token(const char *name, size_t namelen) { return SHRPX_OPTID_MAX_REQUEST_HEADER_FIELDS; } break; + case 't': + if (util::strieq_l("frontend-quic-initial-rt", name, 24)) { + return SHRPX_OPTID_FRONTEND_QUIC_INITIAL_RTT; + } + break; } break; case 26: @@ -4152,6 +4157,19 @@ int parse_config(Config *config, int optid, const StringRef &opt, case SHRPX_OPTID_WORKER_PROCESS_GRACE_SHUTDOWN_PERIOD: return parse_duration(&config->worker_process_grace_shutdown_period, opt, optarg); + case SHRPX_OPTID_FRONTEND_QUIC_INITIAL_RTT: { +#ifdef ENABLE_HTTP3 + ev_tstamp d; + if (parse_duration(&d, opt, optarg) != 0) { + return -1; + } + + config->quic.upstream.initial_rtt = + static_cast(d * NGTCP2_SECONDS); +#endif // ENABLE_HTTP3 + + return 0; + } case SHRPX_OPTID_CONF: LOG(WARN) << "conf: ignored"; diff --git a/src/shrpx_config.h b/src/shrpx_config.h index 8ae8c26c..1b19d2f5 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -400,6 +400,8 @@ constexpr auto SHRPX_OPT_MAX_WORKER_PROCESSES = StringRef::from_lit("max-worker-processes"); constexpr auto SHRPX_OPT_WORKER_PROCESS_GRACE_SHUTDOWN_PERIOD = StringRef::from_lit("worker-process-grace-shutdown-period"); +constexpr auto SHRPX_OPT_FRONTEND_QUIC_INITIAL_RTT = + StringRef::from_lit("frontend-quic-initial-rtt"); constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8; @@ -780,6 +782,7 @@ struct QUICConfig { bool require_token; std::array server_id; StringRef secret_file; + ngtcp2_duration initial_rtt; } upstream; struct { StringRef prog_file; @@ -1242,6 +1245,7 @@ enum { SHRPX_OPTID_FRONTEND_QUIC_DEBUG_LOG, SHRPX_OPTID_FRONTEND_QUIC_EARLY_DATA, SHRPX_OPTID_FRONTEND_QUIC_IDLE_TIMEOUT, + SHRPX_OPTID_FRONTEND_QUIC_INITIAL_RTT, SHRPX_OPTID_FRONTEND_QUIC_QLOG_DIR, SHRPX_OPTID_FRONTEND_QUIC_REQUIRE_TOKEN, SHRPX_OPTID_FRONTEND_QUIC_SECRET_FILE, diff --git a/src/shrpx_http3_upstream.cc b/src/shrpx_http3_upstream.cc index aa0d1f8c..f59d0fff 100644 --- a/src/shrpx_http3_upstream.cc +++ b/src/shrpx_http3_upstream.cc @@ -592,6 +592,7 @@ int Http3Upstream::init(const UpstreamAddr *faddr, const Address &remote_addr, } settings.initial_ts = quic_timestamp(); + settings.initial_rtt = quicconf.upstream.initial_rtt; settings.cc_algo = quicconf.upstream.congestion_controller; settings.max_window = http3conf.upstream.max_connection_window_size; settings.max_stream_window = http3conf.upstream.max_window_size;