From dcc9aaaa240b0523d95d9b9771fe05cd44f2f853 Mon Sep 17 00:00:00 2001 From: Lucas Pardue Date: Wed, 21 Oct 2015 10:22:46 +0000 Subject: [PATCH] Add TLS dynamic record size behaviour command line options --- gennghttpxfun.py | 2 ++ src/shrpx.cc | 33 +++++++++++++++++++++++++ src/shrpx_client_handler.cc | 4 ++- src/shrpx_config.cc | 24 ++++++++++++++++++ src/shrpx_config.h | 6 +++++ src/shrpx_connection.cc | 21 +++++++++++----- src/shrpx_connection.h | 6 ++++- src/shrpx_http2_session.cc | 3 ++- src/shrpx_http_downstream_connection.cc | 4 ++- src/shrpx_memcached_connection.cc | 2 +- 10 files changed, 94 insertions(+), 11 deletions(-) diff --git a/gennghttpxfun.py b/gennghttpxfun.py index 06e859b6..e229d78a 100755 --- a/gennghttpxfun.py +++ b/gennghttpxfun.py @@ -102,6 +102,8 @@ OPTIONS = [ "accept-proxy-protocol", "conf", "fastopen", + "tls-dyn-rec-warmup-threshold", + "tls-dyn-rec-idle-timeout" ] LOGVARS = [ diff --git a/src/shrpx.cc b/src/shrpx.cc index 2a4330e6..84723f6f 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -1031,6 +1031,8 @@ void fill_default_config() { mod_config()->tls_ticket_key_memcached_max_fail = 2; mod_config()->tls_ticket_key_memcached_interval = 10_min; mod_config()->fastopen = 0; + mod_config()->tls_dyn_rec_warmup_threshold = 1_m; + mod_config()->tls_dyn_rec_idle_timeout = 1.; } } // namespace @@ -1420,6 +1422,27 @@ SSL/TLS: Specify address of memcached server to store session cache. This enables shared session cache between multiple nghttpx instances. + --tls-dyn-rec-warmup-threshold= + Specify the threshold size for TLS dynamic record size + behaviour. During a TLS session, after the threshold + number of bytes have been written, the TLS record size + will be increased to the maximum allowed (16K). The max + record size will continue to be used on the active TLS + session. After tls-dyn-rec-idle-timeout has elapsed, the + record size is reduced to 1300 bytes. Specify 0 to + always use the maximum record size, regardless of idle + period. This behaviour applies to all TLS based + frontends, and TLS HTTP/2 backends. + Default: )" + << util::utos_with_unit(get_config()->tls_dyn_rec_warmup_threshold) + << R"( + --tls-dyn-rec-idle-timeout= + Specify TLS dynamic record size behaviour timeout. See + tls-dyn-rec-warmup-threshold for more information. This + behaviour applies to all TLS based frontends, and TLS + HTTP/2 backends. + Default: )" + << util::duration_str(get_config()->tls_dyn_rec_idle_timeout) << R"( HTTP/2 and SPDY: -c, --http2-max-concurrent-streams= @@ -1810,6 +1833,8 @@ int main(int argc, char **argv) { {SHRPX_OPT_MRUBY_FILE, required_argument, &flag, 91}, {SHRPX_OPT_ACCEPT_PROXY_PROTOCOL, no_argument, &flag, 93}, {SHRPX_OPT_FASTOPEN, required_argument, &flag, 94}, + {SHRPX_OPT_TLS_DYN_REC_WARMUP_THRESHOLD, required_argument, &flag, 95}, + {SHRPX_OPT_TLS_DYN_REC_IDLE_TIMEOUT, required_argument, &flag, 96}, {nullptr, 0, nullptr, 0}}; int option_index = 0; @@ -2215,6 +2240,14 @@ int main(int argc, char **argv) { // --fastopen cmdcfgs.emplace_back(SHRPX_OPT_FASTOPEN, optarg); break; + case 95: + // --tls-dyn-rec-warmup-threshold + cmdcfgs.emplace_back(SHRPX_OPT_TLS_DYN_REC_WARMUP_THRESHOLD, optarg); + break; + case 96: + // --tls-dyn-rec-idle-timeout + cmdcfgs.emplace_back(SHRPX_OPT_TLS_DYN_REC_IDLE_TIMEOUT, optarg); + break; default: break; } diff --git a/src/shrpx_client_handler.cc b/src/shrpx_client_handler.cc index 86ab02b3..47818894 100644 --- a/src/shrpx_client_handler.cc +++ b/src/shrpx_client_handler.cc @@ -367,7 +367,9 @@ ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl, get_config()->upstream_write_timeout, get_config()->upstream_read_timeout, get_config()->write_rate, get_config()->write_burst, get_config()->read_rate, - get_config()->read_burst, writecb, readcb, timeoutcb, this), + get_config()->read_burst, writecb, readcb, timeoutcb, this, + get_config()->tls_dyn_rec_warmup_threshold, + get_config()->tls_dyn_rec_idle_timeout), pinned_http2sessions_( get_config()->downstream_proto == PROTO_HTTP2 ? make_unique>( diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index 8efd7f5e..807b8067 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -692,6 +692,8 @@ enum { SHRPX_OPTID_STRIP_INCOMING_X_FORWARDED_FOR, SHRPX_OPTID_SUBCERT, SHRPX_OPTID_SYSLOG_FACILITY, + SHRPX_OPTID_TLS_DYN_REC_IDLE_TIMEOUT, + SHRPX_OPTID_TLS_DYN_REC_WARMUP_THRESHOLD, SHRPX_OPTID_TLS_PROTO_LIST, SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED, SHRPX_OPTID_TLS_TICKET_KEY_CIPHER, @@ -1159,6 +1161,9 @@ int option_lookup_token(const char *name, size_t namelen) { if (util::strieq_l("listener-disable-timeou", name, 23)) { return SHRPX_OPTID_LISTENER_DISABLE_TIMEOUT; } + if (util::strieq_l("tls-dyn-rec-idle-timeou", name, 23)) { + return SHRPX_OPTID_TLS_DYN_REC_IDLE_TIMEOUT; + } break; } break; @@ -1211,6 +1216,11 @@ int option_lookup_token(const char *name, size_t namelen) { break; case 28: switch (name[27]) { + case 'd': + if (util::strieq_l("tls-dyn-rec-warmup-threshol", name, 27)) { + return SHRPX_OPTID_TLS_DYN_REC_WARMUP_THRESHOLD; + } + break; case 's': if (util::strieq_l("http2-max-concurrent-stream", name, 27)) { return SHRPX_OPTID_HTTP2_MAX_CONCURRENT_STREAMS; @@ -1961,6 +1971,20 @@ int parse_config(const char *opt, const char *optarg, case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL: return parse_uint(&mod_config()->tls_ticket_key_memcached_max_fail, opt, optarg); + case SHRPX_OPTID_TLS_DYN_REC_WARMUP_THRESHOLD: { + size_t n; + if (parse_uint_with_unit(&n, opt, optarg) != 0) { + return -1; + } + + mod_config()->tls_dyn_rec_warmup_threshold = n; + + return 0; + } + + case SHRPX_OPTID_TLS_DYN_REC_IDLE_TIMEOUT: + return parse_duration(&mod_config()->tls_dyn_rec_idle_timeout, opt, optarg); + case SHRPX_OPTID_MRUBY_FILE: #ifdef HAVE_MRUBY mod_config()->mruby_file = strcopy(optarg); diff --git a/src/shrpx_config.h b/src/shrpx_config.h index 98fce3a9..f53ebd36 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -187,6 +187,10 @@ constexpr char SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL[] = constexpr char SHRPX_OPT_MRUBY_FILE[] = "mruby-file"; constexpr char SHRPX_OPT_ACCEPT_PROXY_PROTOCOL[] = "accept-proxy-protocol"; constexpr char SHRPX_OPT_FASTOPEN[] = "fastopen"; +constexpr char SHRPX_OPT_TLS_DYN_REC_WARMUP_THRESHOLD[] = + "tls-dyn-rec-warmup-threshold"; +constexpr char SHRPX_OPT_TLS_DYN_REC_IDLE_TIMEOUT[] = + "tls-dyn-rec-idle-timeout"; union sockaddr_union { sockaddr_storage storage; @@ -419,6 +423,8 @@ struct Config { // true if --tls-ticket-key-cipher is used bool tls_ticket_key_cipher_given; bool accept_proxy_protocol; + size_t tls_dyn_rec_warmup_threshold; + ev_tstamp tls_dyn_rec_idle_timeout; }; const Config *get_config(); diff --git a/src/shrpx_connection.cc b/src/shrpx_connection.cc index 1c2e1e45..1ae49389 100644 --- a/src/shrpx_connection.cc +++ b/src/shrpx_connection.cc @@ -44,11 +44,15 @@ Connection::Connection(struct ev_loop *loop, int fd, SSL *ssl, MemchunkPool *mcpool, ev_tstamp write_timeout, ev_tstamp read_timeout, size_t write_rate, size_t write_burst, size_t read_rate, size_t read_burst, - IOCb writecb, IOCb readcb, TimerCb timeoutcb, void *data) + IOCb writecb, IOCb readcb, TimerCb timeoutcb, void *data, + size_t tls_dyn_rec_warmup_threshold, + ev_tstamp tls_dyn_rec_idle_timeout) : tls{DefaultMemchunks(mcpool), DefaultPeekMemchunks(mcpool)}, wlimit(loop, &wev, write_rate, write_burst), rlimit(loop, &rev, read_rate, read_burst, this), writecb(writecb), - readcb(readcb), timeoutcb(timeoutcb), loop(loop), data(data), fd(fd) { + readcb(readcb), timeoutcb(timeoutcb), loop(loop), data(data), fd(fd), + tls_dyn_rec_warmup_threshold(tls_dyn_rec_warmup_threshold), + tls_dyn_rec_idle_timeout(tls_dyn_rec_idle_timeout) { ev_io_init(&wev, writecb, fd, EV_WRITE); ev_io_init(&rev, readcb, fd, EV_READ); @@ -491,19 +495,24 @@ int Connection::check_http2_requirement() { namespace { const size_t SHRPX_SMALL_WRITE_LIMIT = 1300; -const size_t SHRPX_WARMUP_THRESHOLD = 1 << 20; } // namespace size_t Connection::get_tls_write_limit() { + + if (tls_dyn_rec_warmup_threshold == 0) { + return std::numeric_limits::max(); + } + auto t = ev_now(loop); - if (tls.last_write_idle >= 0. && t - tls.last_write_idle > 1.) { + if (tls.last_write_idle >= 0. && + t - tls.last_write_idle > tls_dyn_rec_idle_timeout) { // Time out, use small record size tls.warmup_writelen = 0; return SHRPX_SMALL_WRITE_LIMIT; } - if (tls.warmup_writelen >= SHRPX_WARMUP_THRESHOLD) { + if (tls.warmup_writelen >= tls_dyn_rec_warmup_threshold) { return std::numeric_limits::max(); } @@ -511,7 +520,7 @@ size_t Connection::get_tls_write_limit() { } void Connection::update_tls_warmup_writelen(size_t n) { - if (tls.warmup_writelen < SHRPX_WARMUP_THRESHOLD) { + if (tls.warmup_writelen < tls_dyn_rec_warmup_threshold) { tls.warmup_writelen += n; } } diff --git a/src/shrpx_connection.h b/src/shrpx_connection.h index 03e1ece8..4906a19a 100644 --- a/src/shrpx_connection.h +++ b/src/shrpx_connection.h @@ -75,7 +75,9 @@ struct Connection { Connection(struct ev_loop *loop, int fd, SSL *ssl, MemchunkPool *mcpool, ev_tstamp write_timeout, ev_tstamp read_timeout, size_t write_rate, size_t write_burst, size_t read_rate, size_t read_burst, - IOCb writecb, IOCb readcb, TimerCb timeoutcb, void *data); + IOCb writecb, IOCb readcb, TimerCb timeoutcb, void *data, + size_t tls_dyn_rec_warmup_threshold, + ev_tstamp tls_dyn_rec_idle_timeout); ~Connection(); void disconnect(); @@ -129,6 +131,8 @@ struct Connection { struct ev_loop *loop; void *data; int fd; + size_t tls_dyn_rec_warmup_threshold; + ev_tstamp tls_dyn_rec_idle_timeout; }; } // namespace shrpx diff --git a/src/shrpx_http2_session.cc b/src/shrpx_http2_session.cc index 6c8bb8b5..f9bb0136 100644 --- a/src/shrpx_http2_session.cc +++ b/src/shrpx_http2_session.cc @@ -148,7 +148,8 @@ Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx, : conn_(loop, -1, nullptr, worker->get_mcpool(), get_config()->downstream_write_timeout, get_config()->downstream_read_timeout, 0, 0, 0, 0, writecb, readcb, - timeoutcb, this), + timeoutcb, this, get_config()->tls_dyn_rec_warmup_threshold, + get_config()->tls_dyn_rec_idle_timeout), worker_(worker), connect_blocker_(connect_blocker), ssl_ctx_(ssl_ctx), session_(nullptr), data_pending_(nullptr), data_pendinglen_(0), addr_idx_(0), group_(group), index_(idx), state_(DISCONNECTED), diff --git a/src/shrpx_http_downstream_connection.cc b/src/shrpx_http_downstream_connection.cc index b14c78a0..12d0d005 100644 --- a/src/shrpx_http_downstream_connection.cc +++ b/src/shrpx_http_downstream_connection.cc @@ -114,7 +114,9 @@ HttpDownstreamConnection::HttpDownstreamConnection( : DownstreamConnection(dconn_pool), conn_(loop, -1, nullptr, nullptr, get_config()->downstream_write_timeout, get_config()->downstream_read_timeout, 0, 0, 0, 0, connectcb, - readcb, timeoutcb, this), + readcb, timeoutcb, this, + get_config()->tls_dyn_rec_warmup_threshold, + get_config()->tls_dyn_rec_idle_timeout), ioctrl_(&conn_.rlimit), response_htp_{0}, group_(group), addr_idx_(0), connected_(false) {} diff --git a/src/shrpx_memcached_connection.cc b/src/shrpx_memcached_connection.cc index 5f6b93f7..e5e831ec 100644 --- a/src/shrpx_memcached_connection.cc +++ b/src/shrpx_memcached_connection.cc @@ -93,7 +93,7 @@ constexpr ev_tstamp read_timeout = 10.; MemcachedConnection::MemcachedConnection(const Address *addr, struct ev_loop *loop) : conn_(loop, -1, nullptr, nullptr, write_timeout, read_timeout, 0, 0, 0, 0, - connectcb, readcb, timeoutcb, this), + connectcb, readcb, timeoutcb, this, 0, 0.), parse_state_{}, addr_(addr), sendsum_(0), connected_(false) {} MemcachedConnection::~MemcachedConnection() { disconnect(); }