Merge branch 'nginx' (nginx-1.15.6). Change-Id: I2ea3953dd11ca3c2d27a2d89ba0768fa911ec25d Signed-off-by: Piotr Sikora <piotrsikora@google.com>
diff --git a/.hgtags b/.hgtags index 58e35ca..04a512b 100644 --- a/.hgtags +++ b/.hgtags
@@ -431,3 +431,4 @@ 28b3e17ca7eba1e6a0891afde0e4bc5bcc99c861 release-1.15.3 49d49835653857daa418e68d6cbfed4958c78fca release-1.15.4 f062e43d74fc2578bb100a9e82a953efa1eb9e4e release-1.15.5 +2351853ce6867b6166823bdf94333c0a76633c0a release-1.15.6
diff --git a/BUILD b/BUILD index 232fe29..a08d335 100644 --- a/BUILD +++ b/BUILD
@@ -1535,5 +1535,5 @@ preinst = "@nginx_pkgoss//:debian_preinst", prerm = "@nginx_pkgoss//:debian_prerm", section = "httpd", - version = "1.15.5", + version = "1.15.6", )
diff --git a/build.bzl b/build.bzl index b416982..8a6560b 100644 --- a/build.bzl +++ b/build.bzl
@@ -663,7 +663,7 @@ name = "nginx_pkgoss", build_file_content = _PKGOSS_BUILD_FILE.format(nginx = nginx) + _PKGOSS_BUILD_FILE_TAIL, - commit = "d97bd6151f3a140021f9638c5d2ccc72e0c6911e", # nginx-1.15.5 + commit = "8cd9073e08734f32b52157e2495ad8804dbf8d51", # nginx-1.15.6 remote = "https://nginx.googlesource.com/nginx-pkgoss", )
diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml index dfff0a7..43a21e5 100644 --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml
@@ -5,6 +5,70 @@ <change_log title="nginx"> +<changes ver="1.15.6" date="2018-11-06"> + +<change type="security"> +<para lang="ru"> +при использовании HTTP/2 клиент мог вызвать +чрезмерное потреблению памяти (CVE-2018-16843) +и ресурсов процессора (CVE-2018-16844). +</para> +<para lang="en"> +when using HTTP/2 a client might cause +excessive memory consumption (CVE-2018-16843) +and CPU usage (CVE-2018-16844). +</para> +</change> + +<change type="security"> +<para lang="ru"> +при обработке специально созданного mp4-файла модулем ngx_http_mp4_module +содержимое памяти рабочего процесса могло быть отправлено клиенту +(CVE-2018-16845). +</para> +<para lang="en"> +processing of a specially crafted mp4 file with the ngx_http_mp4_module +might result in worker process memory disclosure +(CVE-2018-16845). +</para> +</change> + +<change type="feature"> +<para lang="ru"> +директивы proxy_socket_keepalive, fastcgi_socket_keepalive, +grpc_socket_keepalive, memcached_socket_keepalive, +scgi_socket_keepalive и uwsgi_socket_keepalive. +</para> +<para lang="en"> +the "proxy_socket_keepalive", "fastcgi_socket_keepalive", +"grpc_socket_keepalive", "memcached_socket_keepalive", +"scgi_socket_keepalive", and "uwsgi_socket_keepalive" directives. +</para> +</change> + +<change type="bugfix"> +<para lang="ru"> +если nginx был собран с OpenSSL 1.1.0, а использовался с OpenSSL 1.1.1, +протокол TLS 1.3 всегда был разрешён. +</para> +<para lang="en"> +if nginx was built with OpenSSL 1.1.0 and used with OpenSSL 1.1.1, +the TLS 1.3 protocol was always enabled. +</para> +</change> + +<change type="bugfix"> +<para lang="ru"> +при работе с gRPC-бэкендами могло расходоваться большое количество памяти. +</para> +<para lang="en"> +working with gRPC backends might result in excessive memory consumption. +</para> +</change> + +</changes> + + <changes ver="1.15.5" date="2018-10-02"> <change type="bugfix">
diff --git a/src/core/nginx.h b/src/core/nginx.h index c109ae1..2ddd19d 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h
@@ -13,8 +13,8 @@ #define NGINX_NAME "nginx" #endif -#define nginx_version 1015005 -#define NGINX_VERSION "1.15.5" +#define nginx_version 1015006 +#define NGINX_VERSION "1.15.6" #define NGINX_VER NGINX_NAME "/" NGINX_VERSION #ifdef NGX_BUILD
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index 6783e71..0c03b56 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h
@@ -504,7 +504,7 @@ #define ngx_event_get_conf(conf_ctx, module) \ - (*(ngx_get_conf(conf_ctx, ngx_events_module))) [module.ctx_index]; + (*(ngx_get_conf(conf_ctx, ngx_events_module))) [module.ctx_index]
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c index 714fc47..1ffa798 100644 --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c
@@ -20,7 +20,7 @@ ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc) { - int rc, type; + int rc, type, value; #if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT || NGX_LINUX) in_port_t port; #endif @@ -73,6 +73,18 @@ } } + if (pc->so_keepalive) { + value = 1; + + if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, + (const void *) &value, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, + "setsockopt(SO_KEEPALIVE) failed, ignored"); + } + } + if (ngx_nonblocking(s) == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_nonblocking_n " failed");
diff --git a/src/event/ngx_event_connect.h b/src/event/ngx_event_connect.h index 72d21d7..7253ebb 100644 --- a/src/event/ngx_event_connect.h +++ b/src/event/ngx_event_connect.h
@@ -62,6 +62,7 @@ unsigned cached:1; unsigned transparent:1; + unsigned so_keepalive:1; /* ngx_connection_log_error_e */ unsigned log_error:2;
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index b903e87..88571a9 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c
@@ -345,6 +345,11 @@ } #endif +#ifdef SSL_CTX_set_min_proto_version + SSL_CTX_set_min_proto_version(ssl->ctx, 0); + SSL_CTX_set_max_proto_version(ssl->ctx, TLS1_2_VERSION); +#endif + #ifdef TLS1_3_VERSION SSL_CTX_set_min_proto_version(ssl->ctx, 0); SSL_CTX_set_max_proto_version(ssl->ctx, TLS1_3_VERSION);
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c index f73ff21..2be0672 100644 --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -286,6 +286,13 @@ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.local), NULL }, + { ngx_string("fastcgi_socket_keepalive"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.socket_keepalive), + NULL }, + { ngx_string("fastcgi_connect_timeout"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, @@ -2721,6 +2728,7 @@ conf->upstream.force_ranges = NGX_CONF_UNSET; conf->upstream.local = NGX_CONF_UNSET_PTR; + conf->upstream.socket_keepalive = NGX_CONF_UNSET; conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; @@ -2824,6 +2832,9 @@ ngx_conf_merge_ptr_value(conf->upstream.local, prev->upstream.local, NULL); + ngx_conf_merge_value(conf->upstream.socket_keepalive, + prev->upstream.socket_keepalive, 0); + ngx_conf_merge_msec_value(conf->upstream.connect_timeout, prev->upstream.connect_timeout, 60000);
diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c index 17b0a26..18478b9 100644 --- a/src/http/modules/ngx_http_grpc_module.c +++ b/src/http/modules/ngx_http_grpc_module.c
@@ -78,6 +78,9 @@ ngx_uint_t id; + ngx_uint_t pings; + ngx_uint_t settings; + ssize_t send_window; size_t recv_window; @@ -248,6 +251,13 @@ offsetof(ngx_http_grpc_loc_conf_t, upstream.local), NULL }, + { ngx_string("grpc_socket_keepalive"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_grpc_loc_conf_t, upstream.socket_keepalive), + NULL }, + { ngx_string("grpc_connect_timeout"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, @@ -3577,6 +3587,12 @@ ctx->rest); return NGX_ERROR; } + + if (ctx->free == NULL && ctx->settings++ > 1000) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent too many settings frames"); + return NGX_ERROR; + } } for (p = b->pos; p < last; p++) { @@ -3729,6 +3745,12 @@ "upstream sent ping frame with ack flag"); return NGX_ERROR; } + + if (ctx->free == NULL && ctx->pings++ > 1000) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent too many ping frames"); + return NGX_ERROR; + } } for (p = b->pos; p < last; p++) { @@ -4150,6 +4172,7 @@ */ conf->upstream.local = NGX_CONF_UNSET_PTR; + conf->upstream.socket_keepalive = NGX_CONF_UNSET; conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT; conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; @@ -4205,6 +4228,9 @@ ngx_conf_merge_ptr_value(conf->upstream.local, prev->upstream.local, NULL); + ngx_conf_merge_value(conf->upstream.socket_keepalive, + prev->upstream.socket_keepalive, 0); + ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries, prev->upstream.next_upstream_tries, 0);
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c index 2624471..775bd7e 100644 --- a/src/http/modules/ngx_http_memcached_module.c +++ b/src/http/modules/ngx_http_memcached_module.c
@@ -67,6 +67,13 @@ offsetof(ngx_http_memcached_loc_conf_t, upstream.local), NULL }, + { ngx_string("memcached_socket_keepalive"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_memcached_loc_conf_t, upstream.socket_keepalive), + NULL }, + { ngx_string("memcached_connect_timeout"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, @@ -595,6 +602,7 @@ */ conf->upstream.local = NGX_CONF_UNSET_PTR; + conf->upstream.socket_keepalive = NGX_CONF_UNSET; conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT; conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; @@ -634,6 +642,9 @@ ngx_conf_merge_ptr_value(conf->upstream.local, prev->upstream.local, NULL); + ngx_conf_merge_value(conf->upstream.socket_keepalive, + prev->upstream.socket_keepalive, 0); + ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries, prev->upstream.next_upstream_tries, 0);
diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c index 08a68d0..2a6fafa 100644 --- a/src/http/modules/ngx_http_mp4_module.c +++ b/src/http/modules/ngx_http_mp4_module.c
@@ -942,6 +942,13 @@ atom_size = ngx_mp4_get_64value(atom_header + 8); atom_header_size = sizeof(ngx_mp4_atom_header64_t); + if (atom_size < sizeof(ngx_mp4_atom_header64_t)) { + ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, + "\"%s\" mp4 atom is too small:%uL", + mp4->file.name.data, atom_size); + return NGX_ERROR; + } + } else { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "\"%s\" mp4 atom is too small:%uL",
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index a817b5c..09c6b53 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c
@@ -324,6 +324,13 @@ offsetof(ngx_http_proxy_loc_conf_t, upstream.local), NULL }, + { ngx_string("proxy_socket_keepalive"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.socket_keepalive), + NULL }, + { ngx_string("proxy_connect_timeout"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, @@ -2840,6 +2847,7 @@ conf->upstream.force_ranges = NGX_CONF_UNSET; conf->upstream.local = NGX_CONF_UNSET_PTR; + conf->upstream.socket_keepalive = NGX_CONF_UNSET; conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; @@ -2961,6 +2969,9 @@ ngx_conf_merge_ptr_value(conf->upstream.local, prev->upstream.local, NULL); + ngx_conf_merge_value(conf->upstream.socket_keepalive, + prev->upstream.socket_keepalive, 0); + ngx_conf_merge_msec_value(conf->upstream.connect_timeout, prev->upstream.connect_timeout, 60000);
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c index ab7769a..7216f78 100644 --- a/src/http/modules/ngx_http_scgi_module.c +++ b/src/http/modules/ngx_http_scgi_module.c
@@ -143,6 +143,13 @@ offsetof(ngx_http_scgi_loc_conf_t, upstream.local), NULL }, + { ngx_string("scgi_socket_keepalive"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_scgi_loc_conf_t, upstream.socket_keepalive), + NULL }, + { ngx_string("scgi_connect_timeout"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, @@ -1200,6 +1207,7 @@ conf->upstream.force_ranges = NGX_CONF_UNSET; conf->upstream.local = NGX_CONF_UNSET_PTR; + conf->upstream.socket_keepalive = NGX_CONF_UNSET; conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; @@ -1298,6 +1306,9 @@ ngx_conf_merge_ptr_value(conf->upstream.local, prev->upstream.local, NULL); + ngx_conf_merge_value(conf->upstream.socket_keepalive, + prev->upstream.socket_keepalive, 0); + ngx_conf_merge_msec_value(conf->upstream.connect_timeout, prev->upstream.connect_timeout, 60000);
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c index d0adbdb..8b09110 100644 --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -204,6 +204,13 @@ offsetof(ngx_http_uwsgi_loc_conf_t, upstream.local), NULL }, + { ngx_string("uwsgi_socket_keepalive"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_uwsgi_loc_conf_t, upstream.socket_keepalive), + NULL }, + { ngx_string("uwsgi_connect_timeout"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, @@ -1413,6 +1420,7 @@ conf->upstream.force_ranges = NGX_CONF_UNSET; conf->upstream.local = NGX_CONF_UNSET_PTR; + conf->upstream.socket_keepalive = NGX_CONF_UNSET; conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; @@ -1519,6 +1527,9 @@ ngx_conf_merge_ptr_value(conf->upstream.local, prev->upstream.local, NULL); + ngx_conf_merge_value(conf->upstream.socket_keepalive, + prev->upstream.socket_keepalive, 0); + ngx_conf_merge_msec_value(conf->upstream.connect_timeout, prev->upstream.connect_timeout, 60000);
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c index 330833d..ecdf11e 100644 --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c
@@ -2418,23 +2418,32 @@ p = (u_char *) ngx_strchr(name.data, ':'); - if (p) { - name.len = p - name.data; - - p++; - - s.len = value[i].data + value[i].len - p; - s.data = p; - - size = ngx_parse_size(&s); - if (size > 8191) { - continue; - } + if (p == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid keys zone size \"%V\"", &value[i]); + return NGX_CONF_ERROR; } - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid keys zone size \"%V\"", &value[i]); - return NGX_CONF_ERROR; + name.len = p - name.data; + + s.data = p + 1; + s.len = value[i].data + value[i].len - s.data; + + size = ngx_parse_size(&s); + + if (size == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid keys zone size \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + if (size < (ssize_t) (2 * ngx_pagesize)) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "keys zone \"%V\" is too small", &value[i]); + return NGX_CONF_ERROR; + } + + continue; } if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 4fc41de..1127b71 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c
@@ -632,6 +632,10 @@ return; } + if (u->conf->socket_keepalive) { + u->peer.so_keepalive = 1; + } + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); u->output.alignment = clcf->directio_alignment;
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index 921a4f2..26a0cc5 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h
@@ -189,6 +189,7 @@ ngx_array_t *pass_headers; ngx_http_upstream_local_t *local; + ngx_flag_t socket_keepalive; #if (NGX_HTTP_CACHE) ngx_shm_zone_t *cache_zone;
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c index 04b3385..c070aa6 100644 --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c
@@ -663,6 +663,7 @@ h2c->pool = NULL; h2c->free_frames = NULL; + h2c->frames = 0; h2c->free_fake_connections = NULL; #if (NGX_HTTP_SSL) @@ -2938,7 +2939,7 @@ frame->blocked = 0; - } else { + } else if (h2c->frames < 10000) { pool = h2c->pool ? h2c->pool : h2c->connection->pool; frame = ngx_pcalloc(pool, sizeof(ngx_http_v2_out_frame_t)); @@ -2962,6 +2963,15 @@ frame->last = frame->first; frame->handler = ngx_http_v2_frame_handler; + + h2c->frames++; + + } else { + ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, + "http2 flood detected"); + + h2c->connection->error = 1; + return NULL; } #if (NGX_DEBUG) @@ -4550,12 +4560,19 @@ #endif - c->destroyed = 0; - ngx_reusable_connection(c, 0); - h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, ngx_http_v2_module); + if (h2c->idle++ > 10 * h2scf->max_requests) { + ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, + "http2 flood detected"); + ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR); + return; + } + + c->destroyed = 0; + ngx_reusable_connection(c, 0); + h2c->pool = ngx_create_pool(h2scf->pool_size, h2c->connection->log); if (h2c->pool == NULL) { ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h index ebd0e77..bec2216 100644 --- a/src/http/v2/ngx_http_v2.h +++ b/src/http/v2/ngx_http_v2.h
@@ -120,6 +120,8 @@ ngx_http_connection_t *http_connection; ngx_uint_t processing; + ngx_uint_t frames; + ngx_uint_t idle; ngx_uint_t pushing; ngx_uint_t concurrent_pushes;
diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c index d0497f5..c8465a7 100644 --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c
@@ -31,6 +31,7 @@ ngx_flag_t next_upstream; ngx_flag_t proxy_protocol; ngx_stream_upstream_local_t *local; + ngx_flag_t socket_keepalive; #if (NGX_STREAM_SSL) ngx_flag_t ssl_enable; @@ -136,6 +137,13 @@ 0, NULL }, + { ngx_string("proxy_socket_keepalive"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_proxy_srv_conf_t, socket_keepalive), + NULL }, + { ngx_string("proxy_connect_timeout"), NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, @@ -388,6 +396,10 @@ return; } + if (pscf->socket_keepalive) { + u->peer.so_keepalive = 1; + } + u->peer.type = c->type; u->start_sec = ngx_time(); @@ -1898,6 +1910,7 @@ conf->next_upstream = NGX_CONF_UNSET; conf->proxy_protocol = NGX_CONF_UNSET; conf->local = NGX_CONF_UNSET_PTR; + conf->socket_keepalive = NGX_CONF_UNSET; #if (NGX_STREAM_SSL) conf->ssl_enable = NGX_CONF_UNSET; @@ -1948,6 +1961,9 @@ ngx_conf_merge_ptr_value(conf->local, prev->local, NULL); + ngx_conf_merge_value(conf->socket_keepalive, + prev->socket_keepalive, 0); + #if (NGX_STREAM_SSL) ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0);