Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions auto/modules
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,10 @@ if [ $HTTP = YES ]; then
. auto/module
fi

if [ $HTTP_V2_HPACK_ENC = YES ]; then
have=NGX_HTTP_V2_HPACK_ENC . auto/have
fi

if :; then
ngx_module_name=ngx_http_static_module
ngx_module_incs=
Expand Down
3 changes: 3 additions & 0 deletions auto/options
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ HTTP_CHARSET=YES
HTTP_GZIP=YES
HTTP_SSL=NO
HTTP_V2=NO
HTTP_V2_HPACK_ENC=NO
HTTP_SSI=YES
HTTP_REALIP=NO
HTTP_XSLT=NO
Expand Down Expand Up @@ -227,6 +228,7 @@ $0: warning: the \"--with-ipv6\" option is deprecated"

--with-http_ssl_module) HTTP_SSL=YES ;;
--with-http_v2_module) HTTP_V2=YES ;;
--with-http_v2_hpack_enc) HTTP_V2_HPACK_ENC=YES ;;
--with-http_realip_module) HTTP_REALIP=YES ;;
--with-http_addition_module) HTTP_ADDITION=YES ;;
--with-http_xslt_module) HTTP_XSLT=YES ;;
Expand Down Expand Up @@ -443,6 +445,7 @@ cat << END

--with-http_ssl_module enable ngx_http_ssl_module
--with-http_v2_module enable ngx_http_v2_module
--with-http_v2_hpack_enc enable ngx_http_v2_hpack_enc
--with-http_realip_module enable ngx_http_realip_module
--with-http_addition_module enable ngx_http_addition_module
--with-http_xslt_module enable ngx_http_xslt_module
Expand Down
60 changes: 60 additions & 0 deletions src/core/ngx_murmurhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,63 @@ ngx_murmur_hash2(u_char *data, size_t len)

return h;
}


uint64_t
ngx_murmur_hash2_64(u_char *data, size_t len, uint64_t seed)
{
uint64_t h, k;

h = seed ^ len;

while (len >= 8) {
k = data[0];
k |= data[1] << 8;
k |= data[2] << 16;
k |= data[3] << 24;
k |= (uint64_t)data[4] << 32;
k |= (uint64_t)data[5] << 40;
k |= (uint64_t)data[6] << 48;
k |= (uint64_t)data[7] << 56;

k *= 0xc6a4a7935bd1e995ull;
k ^= k >> 47;
k *= 0xc6a4a7935bd1e995ull;

h ^= k;
h *= 0xc6a4a7935bd1e995ull;

data += 8;
len -= 8;
}

switch (len) {
case 7:
h ^= (uint64_t)data[6] << 48;
/* fall through */
case 6:
h ^= (uint64_t)data[5] << 40;
/* fall through */
case 5:
h ^= (uint64_t)data[4] << 32;
/* fall through */
case 4:
h ^= data[3] << 24;
/* fall through */
case 3:
h ^= data[2] << 16;
/* fall through */
case 2:
h ^= data[1] << 8;
/* fall through */
case 1:
h ^= data[0];
h *= 0xc6a4a7935bd1e995ull;
}

h ^= h >> 47;
h *= 0xc6a4a7935bd1e995ull;
h ^= h >> 47;

return h;
}
2 changes: 2 additions & 0 deletions src/core/ngx_murmurhash.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@

uint32_t ngx_murmur_hash2(u_char *data, size_t len);

uint64_t ngx_murmur_hash2_64(u_char *data, size_t len, uint64_t seed);


#endif /* _NGX_MURMURHASH_H_INCLUDED_ */
42 changes: 42 additions & 0 deletions src/event/ngx_event_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1616,6 +1616,7 @@ ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)

sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
sc->buffer_size = ssl->buffer_size;
sc->dyn_rec = ssl->dyn_rec;

sc->session_ctx = ssl->ctx;

Expand Down Expand Up @@ -2555,6 +2556,41 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)

for ( ;; ) {

/* Dynamic record resizing:
We want the initial records to fit into one TCP segment
so we don't get TCP HoL blocking due to TCP Slow Start.
A connection always starts with small records, but after
a given amount of records sent, we make the records larger
to reduce header overhead.
After a connection has idled for a given timeout, begin
the process from the start. The actual parameters are
configurable. If dyn_rec_timeout is 0, we assume dyn_rec is off. */

if (c->ssl->dyn_rec.timeout > 0 ) {

if (ngx_current_msec - c->ssl->dyn_rec_last_write >
c->ssl->dyn_rec.timeout)
{
buf->end = buf->start + c->ssl->dyn_rec.size_lo;
c->ssl->dyn_rec_records_sent = 0;

} else {
if (c->ssl->dyn_rec_records_sent >
c->ssl->dyn_rec.threshold * 2)
{
buf->end = buf->start + c->ssl->buffer_size;

} else if (c->ssl->dyn_rec_records_sent >
c->ssl->dyn_rec.threshold)
{
buf->end = buf->start + c->ssl->dyn_rec.size_hi;

} else {
buf->end = buf->start + c->ssl->dyn_rec.size_lo;
}
}
}

while (in && buf->last < buf->end && send < limit) {
if (in->buf->last_buf || in->buf->flush) {
flush = 1;
Expand Down Expand Up @@ -2662,6 +2698,9 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)

if (n > 0) {

c->ssl->dyn_rec_records_sent++;
c->ssl->dyn_rec_last_write = ngx_current_msec;

if (c->ssl->saved_read_handler) {

c->read->handler = c->ssl->saved_read_handler;
Expand Down Expand Up @@ -2773,6 +2812,9 @@ ngx_ssl_write_early(ngx_connection_t *c, u_char *data, size_t size)

if (n > 0) {

c->ssl->dyn_rec_records_sent++;
c->ssl->dyn_rec_last_write = ngx_current_msec;

if (c->ssl->saved_read_handler) {

c->read->handler = c->ssl->saved_read_handler;
Expand Down
12 changes: 11 additions & 1 deletion src/event/ngx_event_openssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,18 @@

typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t;

typedef struct {
ngx_msec_t timeout;
ngx_uint_t threshold;
size_t size_lo;
size_t size_hi;
} ngx_ssl_dyn_rec_t;

struct ngx_ssl_s {
SSL_CTX *ctx;
ngx_log_t *log;
size_t buffer_size;
ngx_ssl_dyn_rec_t dyn_rec;
};


Expand Down Expand Up @@ -101,6 +108,9 @@ struct ngx_ssl_connection_s {
unsigned no_wait_shutdown:1;
unsigned no_send_shutdown:1;
unsigned handshake_buffer_set:1;
ngx_ssl_dyn_rec_t dyn_rec;
ngx_msec_t dyn_rec_last_write;
ngx_uint_t dyn_rec_records_sent;
unsigned try_early_data:1;
unsigned in_early:1;
unsigned in_ocsp:1;
Expand All @@ -115,7 +125,7 @@ struct ngx_ssl_connection_s {
#define NGX_SSL_DFLT_BUILTIN_SCACHE -5


#define NGX_SSL_MAX_SESSION_SIZE 4096
#define NGX_SSL_MAX_SESSION_SIZE 16384

typedef struct ngx_ssl_sess_id_s ngx_ssl_sess_id_t;

Expand Down
77 changes: 77 additions & 0 deletions src/http/modules/ngx_http_ssl_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,41 @@ static ngx_command_t ngx_http_ssl_commands[] = {
offsetof(ngx_http_ssl_srv_conf_t, reject_handshake),
NULL },

{ ngx_string("ssl_dyn_rec_enable"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_enable),
NULL },

{ ngx_string("ssl_dyn_rec_timeout"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_msec_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_timeout),
NULL },

{ ngx_string("ssl_dyn_rec_size_lo"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_size_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_size_lo),
NULL },

{ ngx_string("ssl_dyn_rec_size_hi"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_size_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_size_hi),
NULL },

{ ngx_string("ssl_dyn_rec_threshold"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_num_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_threshold),
NULL },

ngx_null_command
};

Expand Down Expand Up @@ -638,6 +673,12 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
sscf->stapling = NGX_CONF_UNSET;
sscf->stapling_verify = NGX_CONF_UNSET;

sscf->dyn_rec_enable = NGX_CONF_UNSET;
sscf->dyn_rec_timeout = NGX_CONF_UNSET_MSEC;
sscf->dyn_rec_size_lo = NGX_CONF_UNSET_SIZE;
sscf->dyn_rec_size_hi = NGX_CONF_UNSET_SIZE;
sscf->dyn_rec_threshold = NGX_CONF_UNSET_UINT;

return sscf;
}

Expand Down Expand Up @@ -712,6 +753,20 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->stapling_responder,
prev->stapling_responder, "");

ngx_conf_merge_value(conf->dyn_rec_enable, prev->dyn_rec_enable, 0);
ngx_conf_merge_msec_value(conf->dyn_rec_timeout, prev->dyn_rec_timeout,
1000);
/* Default sizes for the dynamic record sizes are defined to fit maximal
TLS + IPv6 overhead in a single TCP segment for lo and 3 segments for hi:
1369 = 1500 - 40 (IP) - 20 (TCP) - 10 (Time) - 61 (Max TLS overhead) */
ngx_conf_merge_size_value(conf->dyn_rec_size_lo, prev->dyn_rec_size_lo,
1369);
/* 4229 = (1500 - 40 - 20 - 10) * 3 - 61 */
ngx_conf_merge_size_value(conf->dyn_rec_size_hi, prev->dyn_rec_size_hi,
4229);
ngx_conf_merge_uint_value(conf->dyn_rec_threshold, prev->dyn_rec_threshold,
40);

conf->ssl.log = cf->log;

if (conf->enable) {
Expand Down Expand Up @@ -943,6 +998,28 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}

if (conf->dyn_rec_enable) {
conf->ssl.dyn_rec.timeout = conf->dyn_rec_timeout;
conf->ssl.dyn_rec.threshold = conf->dyn_rec_threshold;

if (conf->buffer_size > conf->dyn_rec_size_lo) {
conf->ssl.dyn_rec.size_lo = conf->dyn_rec_size_lo;

} else {
conf->ssl.dyn_rec.size_lo = conf->buffer_size;
}

if (conf->buffer_size > conf->dyn_rec_size_hi) {
conf->ssl.dyn_rec.size_hi = conf->dyn_rec_size_hi;

} else {
conf->ssl.dyn_rec.size_hi = conf->buffer_size;
}

} else {
conf->ssl.dyn_rec.timeout = 0;
}

return NGX_CONF_OK;
}

Expand Down
6 changes: 6 additions & 0 deletions src/http/modules/ngx_http_ssl_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ typedef struct {

u_char *file;
ngx_uint_t line;

ngx_flag_t dyn_rec_enable;
ngx_msec_t dyn_rec_timeout;
size_t dyn_rec_size_lo;
size_t dyn_rec_size_hi;
ngx_uint_t dyn_rec_threshold;
} ngx_http_ssl_srv_conf_t;


Expand Down
1 change: 1 addition & 0 deletions src/http/ngx_http_core_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ static ngx_conf_enum_t ngx_http_core_server_tokens[] = {
{ ngx_string("off"), NGX_HTTP_SERVER_TOKENS_OFF },
{ ngx_string("on"), NGX_HTTP_SERVER_TOKENS_ON },
{ ngx_string("build"), NGX_HTTP_SERVER_TOKENS_BUILD },
{ ngx_string("none"), NGX_HTTP_SERVER_TOKENS_NONE },
{ ngx_null_string, 0 }
};

Expand Down
1 change: 1 addition & 0 deletions src/http/ngx_http_core_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ typedef struct ngx_thread_pool_s ngx_thread_pool_t;
#define NGX_HTTP_SERVER_TOKENS_OFF 0
#define NGX_HTTP_SERVER_TOKENS_ON 1
#define NGX_HTTP_SERVER_TOKENS_BUILD 2
#define NGX_HTTP_SERVER_TOKENS_NONE 3


typedef struct ngx_http_location_tree_node_s ngx_http_location_tree_node_t;
Expand Down
4 changes: 2 additions & 2 deletions src/http/ngx_http_header_filter_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ ngx_http_header_filter(ngx_http_request_t *r)

clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

if (r->headers_out.server == NULL) {
if (r->headers_out.server == NULL && clcf->server_tokens != NGX_HTTP_SERVER_TOKENS_NONE) {
if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
len += sizeof(ngx_http_server_full_string) - 1;

Expand Down Expand Up @@ -448,7 +448,7 @@ ngx_http_header_filter(ngx_http_request_t *r)
}
*b->last++ = CR; *b->last++ = LF;

if (r->headers_out.server == NULL) {
if (r->headers_out.server == NULL && clcf->server_tokens != NGX_HTTP_SERVER_TOKENS_NONE) {
if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
p = ngx_http_server_full_string;
len = sizeof(ngx_http_server_full_string) - 1;
Expand Down
9 changes: 8 additions & 1 deletion src/http/ngx_http_special_response.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ static u_char ngx_http_error_tail[] =
"</html>" CRLF
;

static u_char ngx_http_error_none_tail[] =
"" CRLF
"</body>" CRLF
"</html>" CRLF
;

static u_char ngx_http_msie_padding[] =
"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
Expand Down Expand Up @@ -686,7 +691,9 @@ ngx_http_send_special_response(ngx_http_request_t *r,
} else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
len = sizeof(ngx_http_error_build_tail) - 1;
tail = ngx_http_error_build_tail;

} else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_NONE) {
len = sizeof(ngx_http_error_none_tail) - 1;
tail = ngx_http_error_none_tail;
} else {
len = sizeof(ngx_http_error_tail) - 1;
tail = ngx_http_error_tail;
Expand Down
Loading