Add TLS dynamic record size behaviour command line options

This commit is contained in:
Lucas Pardue 2015-10-21 10:22:46 +00:00
parent 1fdf208a28
commit dcc9aaaa24
10 changed files with 94 additions and 11 deletions

View File

@ -102,6 +102,8 @@ OPTIONS = [
"accept-proxy-protocol", "accept-proxy-protocol",
"conf", "conf",
"fastopen", "fastopen",
"tls-dyn-rec-warmup-threshold",
"tls-dyn-rec-idle-timeout"
] ]
LOGVARS = [ LOGVARS = [

View File

@ -1031,6 +1031,8 @@ void fill_default_config() {
mod_config()->tls_ticket_key_memcached_max_fail = 2; mod_config()->tls_ticket_key_memcached_max_fail = 2;
mod_config()->tls_ticket_key_memcached_interval = 10_min; mod_config()->tls_ticket_key_memcached_interval = 10_min;
mod_config()->fastopen = 0; mod_config()->fastopen = 0;
mod_config()->tls_dyn_rec_warmup_threshold = 1_m;
mod_config()->tls_dyn_rec_idle_timeout = 1.;
} }
} // namespace } // namespace
@ -1420,6 +1422,27 @@ SSL/TLS:
Specify address of memcached server to store session Specify address of memcached server to store session
cache. This enables shared session cache between cache. This enables shared session cache between
multiple nghttpx instances. multiple nghttpx instances.
--tls-dyn-rec-warmup-threshold=<SIZE>
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=<DURATION>
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: HTTP/2 and SPDY:
-c, --http2-max-concurrent-streams=<N> -c, --http2-max-concurrent-streams=<N>
@ -1810,6 +1833,8 @@ int main(int argc, char **argv) {
{SHRPX_OPT_MRUBY_FILE, required_argument, &flag, 91}, {SHRPX_OPT_MRUBY_FILE, required_argument, &flag, 91},
{SHRPX_OPT_ACCEPT_PROXY_PROTOCOL, no_argument, &flag, 93}, {SHRPX_OPT_ACCEPT_PROXY_PROTOCOL, no_argument, &flag, 93},
{SHRPX_OPT_FASTOPEN, required_argument, &flag, 94}, {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}}; {nullptr, 0, nullptr, 0}};
int option_index = 0; int option_index = 0;
@ -2215,6 +2240,14 @@ int main(int argc, char **argv) {
// --fastopen // --fastopen
cmdcfgs.emplace_back(SHRPX_OPT_FASTOPEN, optarg); cmdcfgs.emplace_back(SHRPX_OPT_FASTOPEN, optarg);
break; 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: default:
break; break;
} }

View File

@ -367,7 +367,9 @@ ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
get_config()->upstream_write_timeout, get_config()->upstream_write_timeout,
get_config()->upstream_read_timeout, get_config()->write_rate, get_config()->upstream_read_timeout, get_config()->write_rate,
get_config()->write_burst, get_config()->read_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_( pinned_http2sessions_(
get_config()->downstream_proto == PROTO_HTTP2 get_config()->downstream_proto == PROTO_HTTP2
? make_unique<std::vector<ssize_t>>( ? make_unique<std::vector<ssize_t>>(

View File

@ -692,6 +692,8 @@ enum {
SHRPX_OPTID_STRIP_INCOMING_X_FORWARDED_FOR, SHRPX_OPTID_STRIP_INCOMING_X_FORWARDED_FOR,
SHRPX_OPTID_SUBCERT, SHRPX_OPTID_SUBCERT,
SHRPX_OPTID_SYSLOG_FACILITY, 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_PROTO_LIST,
SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED, SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED,
SHRPX_OPTID_TLS_TICKET_KEY_CIPHER, 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)) { if (util::strieq_l("listener-disable-timeou", name, 23)) {
return SHRPX_OPTID_LISTENER_DISABLE_TIMEOUT; 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;
} }
break; break;
@ -1211,6 +1216,11 @@ int option_lookup_token(const char *name, size_t namelen) {
break; break;
case 28: case 28:
switch (name[27]) { 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': case 's':
if (util::strieq_l("http2-max-concurrent-stream", name, 27)) { if (util::strieq_l("http2-max-concurrent-stream", name, 27)) {
return SHRPX_OPTID_HTTP2_MAX_CONCURRENT_STREAMS; 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: case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL:
return parse_uint(&mod_config()->tls_ticket_key_memcached_max_fail, opt, return parse_uint(&mod_config()->tls_ticket_key_memcached_max_fail, opt,
optarg); 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: case SHRPX_OPTID_MRUBY_FILE:
#ifdef HAVE_MRUBY #ifdef HAVE_MRUBY
mod_config()->mruby_file = strcopy(optarg); mod_config()->mruby_file = strcopy(optarg);

View File

@ -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_MRUBY_FILE[] = "mruby-file";
constexpr char SHRPX_OPT_ACCEPT_PROXY_PROTOCOL[] = "accept-proxy-protocol"; constexpr char SHRPX_OPT_ACCEPT_PROXY_PROTOCOL[] = "accept-proxy-protocol";
constexpr char SHRPX_OPT_FASTOPEN[] = "fastopen"; 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 { union sockaddr_union {
sockaddr_storage storage; sockaddr_storage storage;
@ -419,6 +423,8 @@ struct Config {
// true if --tls-ticket-key-cipher is used // true if --tls-ticket-key-cipher is used
bool tls_ticket_key_cipher_given; bool tls_ticket_key_cipher_given;
bool accept_proxy_protocol; bool accept_proxy_protocol;
size_t tls_dyn_rec_warmup_threshold;
ev_tstamp tls_dyn_rec_idle_timeout;
}; };
const Config *get_config(); const Config *get_config();

View File

@ -44,11 +44,15 @@ Connection::Connection(struct ev_loop *loop, int fd, SSL *ssl,
MemchunkPool *mcpool, ev_tstamp write_timeout, MemchunkPool *mcpool, ev_tstamp write_timeout,
ev_tstamp read_timeout, size_t write_rate, ev_tstamp read_timeout, size_t write_rate,
size_t write_burst, size_t read_rate, size_t read_burst, 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)}, : tls{DefaultMemchunks(mcpool), DefaultPeekMemchunks(mcpool)},
wlimit(loop, &wev, write_rate, write_burst), wlimit(loop, &wev, write_rate, write_burst),
rlimit(loop, &rev, read_rate, read_burst, this), writecb(writecb), 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(&wev, writecb, fd, EV_WRITE);
ev_io_init(&rev, readcb, fd, EV_READ); ev_io_init(&rev, readcb, fd, EV_READ);
@ -491,19 +495,24 @@ int Connection::check_http2_requirement() {
namespace { namespace {
const size_t SHRPX_SMALL_WRITE_LIMIT = 1300; const size_t SHRPX_SMALL_WRITE_LIMIT = 1300;
const size_t SHRPX_WARMUP_THRESHOLD = 1 << 20;
} // namespace } // namespace
size_t Connection::get_tls_write_limit() { size_t Connection::get_tls_write_limit() {
if (tls_dyn_rec_warmup_threshold == 0) {
return std::numeric_limits<ssize_t>::max();
}
auto t = ev_now(loop); 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 // Time out, use small record size
tls.warmup_writelen = 0; tls.warmup_writelen = 0;
return SHRPX_SMALL_WRITE_LIMIT; 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<ssize_t>::max(); return std::numeric_limits<ssize_t>::max();
} }
@ -511,7 +520,7 @@ size_t Connection::get_tls_write_limit() {
} }
void Connection::update_tls_warmup_writelen(size_t n) { 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; tls.warmup_writelen += n;
} }
} }

View File

@ -75,7 +75,9 @@ struct Connection {
Connection(struct ev_loop *loop, int fd, SSL *ssl, MemchunkPool *mcpool, Connection(struct ev_loop *loop, int fd, SSL *ssl, MemchunkPool *mcpool,
ev_tstamp write_timeout, ev_tstamp read_timeout, size_t write_rate, ev_tstamp write_timeout, ev_tstamp read_timeout, size_t write_rate,
size_t write_burst, size_t read_rate, size_t read_burst, 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(); ~Connection();
void disconnect(); void disconnect();
@ -129,6 +131,8 @@ struct Connection {
struct ev_loop *loop; struct ev_loop *loop;
void *data; void *data;
int fd; int fd;
size_t tls_dyn_rec_warmup_threshold;
ev_tstamp tls_dyn_rec_idle_timeout;
}; };
} // namespace shrpx } // namespace shrpx

View File

@ -148,7 +148,8 @@ Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
: conn_(loop, -1, nullptr, worker->get_mcpool(), : conn_(loop, -1, nullptr, worker->get_mcpool(),
get_config()->downstream_write_timeout, get_config()->downstream_write_timeout,
get_config()->downstream_read_timeout, 0, 0, 0, 0, writecb, readcb, 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), worker_(worker), connect_blocker_(connect_blocker), ssl_ctx_(ssl_ctx),
session_(nullptr), data_pending_(nullptr), data_pendinglen_(0), session_(nullptr), data_pending_(nullptr), data_pendinglen_(0),
addr_idx_(0), group_(group), index_(idx), state_(DISCONNECTED), addr_idx_(0), group_(group), index_(idx), state_(DISCONNECTED),

View File

@ -114,7 +114,9 @@ HttpDownstreamConnection::HttpDownstreamConnection(
: DownstreamConnection(dconn_pool), : DownstreamConnection(dconn_pool),
conn_(loop, -1, nullptr, nullptr, get_config()->downstream_write_timeout, conn_(loop, -1, nullptr, nullptr, get_config()->downstream_write_timeout,
get_config()->downstream_read_timeout, 0, 0, 0, 0, connectcb, 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), ioctrl_(&conn_.rlimit), response_htp_{0}, group_(group), addr_idx_(0),
connected_(false) {} connected_(false) {}

View File

@ -93,7 +93,7 @@ constexpr ev_tstamp read_timeout = 10.;
MemcachedConnection::MemcachedConnection(const Address *addr, MemcachedConnection::MemcachedConnection(const Address *addr,
struct ev_loop *loop) struct ev_loop *loop)
: conn_(loop, -1, nullptr, nullptr, write_timeout, read_timeout, 0, 0, 0, 0, : 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) {} parse_state_{}, addr_(addr), sendsum_(0), connected_(false) {}
MemcachedConnection::~MemcachedConnection() { disconnect(); } MemcachedConnection::~MemcachedConnection() { disconnect(); }