diff options
author | nginx <nginx@nginx.org> | 2015-05-26 14:16:13 +0000 |
---|---|---|
committer | Jon Kolb <kolbyjack@gmail.com> | 2015-05-26 14:16:13 +0000 |
commit | 2db2346e9858b0e2bc441fe293f1581a1b3371ae (patch) | |
tree | 8b27ae15499ddaeeb6a7649e94404a5c0d61a9f1 | |
parent | cf6aa562bf80ee87c803ec940cb23234487f1444 (diff) | |
download | nginx-1.9.1.tar.gz |
Changes with nginx 1.9.1 26 May 2015v1.9.1
*) Change: now SSLv3 protocol is disabled by default.
*) Change: some long deprecated directives are not supported anymore.
*) Feature: the "reuseport" parameter of the "listen" directive.
Thanks to Sepherosa Ziehau and Yingqi Lu.
*) Feature: the $upstream_connect_time variable.
*) Bugfix: in the "hash" directive on big-endian platforms.
*) Bugfix: nginx might fail to start on some old Linux variants; the bug
had appeared in 1.7.11.
*) Bugfix: in IP address parsing.
Thanks to Sergey Polovko.
40 files changed, 381 insertions, 195 deletions
@@ -1,4 +1,24 @@ +Changes with nginx 1.9.1 26 May 2015 + + *) Change: now SSLv3 protocol is disabled by default. + + *) Change: some long deprecated directives are not supported anymore. + + *) Feature: the "reuseport" parameter of the "listen" directive. + Thanks to Sepherosa Ziehau and Yingqi Lu. + + *) Feature: the $upstream_connect_time variable. + + *) Bugfix: in the "hash" directive on big-endian platforms. + + *) Bugfix: nginx might fail to start on some old Linux variants; the bug + had appeared in 1.7.11. + + *) Bugfix: in IP address parsing. + Thanks to Sergey Polovko. + + Changes with nginx 1.9.0 28 Apr 2015 *) Change: obsolete aio and rtsig event methods have been removed. diff --git a/CHANGES.ru b/CHANGES.ru index f91a0d7ce..b70c132a4 100644 --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,25 @@ +Изменения в nginx 1.9.1 26.05.2015 + + *) Изменение: теперь протокол SSLv3 по умолчанию запрещён. + + *) Изменение: некоторые давно устаревшие директивы больше не + поддерживаются. + + *) Добавление: параметр reuseport директивы listen. + Спасибо Sepherosa Ziehau и Yingqi Lu. + + *) Добавление: переменная $upstream_connect_time. + + *) Исправление: в директиве hash на big-endian платформах. + + *) Исправление: nginx мог не запускаться на некоторых старых версиях + Linux; ошибка появилась в 1.7.11. + + *) Исправление: в парсинге IP-адресов. + Спасибо Сергею Половко. + + Изменения в nginx 1.9.0 28.04.2015 *) Изменение: устаревшие методы обработки соединений aio и rtsig больше diff --git a/auto/options b/auto/options index 5ecb84bff..e3a7edead 100644 --- a/auto/options +++ b/auto/options @@ -243,12 +243,6 @@ do --without-http_uwsgi_module) HTTP_UWSGI=NO ;; --without-http_scgi_module) HTTP_SCGI=NO ;; --without-http_memcached_module) HTTP_MEMCACHED=NO ;; - --without-http_limit_zone_module) - HTTP_LIMIT_CONN=NO - NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG -$0: warning: the \"--without-http_limit_zone_module\" option is deprecated, \ -use the \"--without-http_limit_conn_module\" option instead" - ;; --without-http_limit_conn_module) HTTP_LIMIT_CONN=NO ;; --without-http_limit_req_module) HTTP_LIMIT_REQ=NO ;; --without-http_empty_gif_module) HTTP_EMPTY_GIF=NO ;; @@ -270,8 +264,18 @@ use the \"--without-http_limit_conn_module\" option instead" --with-mail) MAIL=YES ;; --with-mail_ssl_module) MAIL_SSL=YES ;; # STUB - --with-imap) MAIL=YES ;; - --with-imap_ssl_module) MAIL_SSL=YES ;; + --with-imap) + MAIL=YES + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-imap\" option is deprecated, \ +use the \"--with-mail\" option instead" + ;; + --with-imap_ssl_module) + MAIL_SSL=YES + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-imap_ssl_module\" option is deprecated, \ +use the \"--with-mail_ssl_module\" option instead" + ;; --without-mail_pop3_module) MAIL_POP3=NO ;; --without-mail_imap_module) MAIL_IMAP=NO ;; --without-mail_smtp_module) MAIL_SMTP=NO ;; diff --git a/auto/os/conf b/auto/os/conf index fe720160a..6ad0e74e0 100644 --- a/auto/os/conf +++ b/auto/os/conf @@ -60,6 +60,15 @@ case "$NGX_PLATFORM" in CORE_SRCS="$UNIX_SRCS" ;; + GNU:*) + # GNU Hurd + have=NGX_GNU_HURD . auto/have_headers + CORE_INCS="$UNIX_INCS" + CORE_DEPS="$UNIX_DEPS $POSIX_DEPS" + CORE_SRCS="$UNIX_SRCS" + CC_AUX_FLAGS="$CC_AUX_FLAGS -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64" + ;; + *) CORE_INCS="$UNIX_INCS" CORE_DEPS="$UNIX_DEPS $POSIX_DEPS" @@ -304,7 +304,17 @@ ngx_feature_run=no ngx_feature_incs="#include <sys/socket.h>" ngx_feature_path= ngx_feature_libs= -ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_SETFIB, NULL, 4)" +ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_SETFIB, NULL, 0)" +. auto/feature + + +ngx_feature="SO_REUSEPORT" +ngx_feature_name="NGX_HAVE_REUSEPORT" +ngx_feature_run=no +ngx_feature_incs="#include <sys/socket.h>" +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_REUSEPORT, NULL, 0)" . auto/feature diff --git a/src/core/nginx.h b/src/core/nginx.h index 347c25e82..ec818e042 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1009000 -#define NGINX_VERSION "1.9.0" +#define nginx_version 1009001 +#define NGINX_VERSION "1.9.1" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 52b97ce89..04a365a76 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -91,6 +91,43 @@ ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen) ngx_int_t +ngx_clone_listening(ngx_conf_t *cf, ngx_listening_t *ls) +{ +#if (NGX_HAVE_REUSEPORT) + + ngx_int_t n; + ngx_core_conf_t *ccf; + ngx_listening_t ols; + + if (!ls->reuseport) { + return NGX_OK; + } + + ols = *ls; + + ccf = (ngx_core_conf_t *) ngx_get_conf(cf->cycle->conf_ctx, + ngx_core_module); + + for (n = 1; n < ccf->worker_processes; n++) { + + /* create a socket for each worker process */ + + ls = ngx_array_push(&cf->cycle->listening); + if (ls == NULL) { + return NGX_ERROR; + } + + *ls = ols; + ls->worker = n; + } + +#endif + + return NGX_OK; +} + + +ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle) { size_t len; @@ -106,6 +143,9 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle) #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) int timeout; #endif +#if (NGX_HAVE_REUSEPORT) + int reuseport; +#endif ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { @@ -215,6 +255,25 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle) #endif #endif +#if (NGX_HAVE_REUSEPORT) + + reuseport = 0; + olen = sizeof(int); + + if (getsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT, + (void *) &reuseport, &olen) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "getsockopt(SO_REUSEPORT) %V failed, ignored", + &ls[i].addr_text); + + } else { + ls[i].reuseport = reuseport ? 1 : 0; + } + +#endif + #if (NGX_HAVE_TCP_FASTOPEN) olen = sizeof(int); @@ -332,6 +391,31 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle) continue; } +#if (NGX_HAVE_REUSEPORT) + + if (ls[i].add_reuseport) { + + /* + * to allow transition from a socket without SO_REUSEPORT + * to multiple sockets with SO_REUSEPORT, we have to set + * SO_REUSEPORT on the old socket before opening new ones + */ + + int reuseport = 1; + + if (setsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT, + (const void *) &reuseport, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(SO_REUSEPORT) %V failed, ignored", + &ls[i].addr_text); + } + + ls[i].add_reuseport = 0; + } +#endif + if (ls[i].fd != (ngx_socket_t) -1) { continue; } @@ -370,6 +454,32 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle) return NGX_ERROR; } +#if (NGX_HAVE_REUSEPORT) + + if (ls[i].reuseport) { + int reuseport; + + reuseport = 1; + + if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, + (const void *) &reuseport, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "setsockopt(SO_REUSEPORT) %V failed, ignored", + &ls[i].addr_text); + + if (ngx_close_socket(s) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_close_socket_n " %V failed", + &ls[i].addr_text); + } + + return NGX_ERROR; + } + } +#endif + #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) if (ls[i].sockaddr->sa_family == AF_INET6) { diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index 27bb8a99c..a49aa9579 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -51,6 +51,8 @@ struct ngx_listening_s { ngx_listening_t *previous; ngx_connection_t *connection; + ngx_uint_t worker; + unsigned open:1; unsigned remain:1; unsigned ignore:1; @@ -66,6 +68,10 @@ struct ngx_listening_s { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:1; #endif +#if (NGX_HAVE_REUSEPORT) + unsigned reuseport:1; + unsigned add_reuseport:1; +#endif unsigned keepalive:2; #if (NGX_HAVE_DEFERRED_ACCEPT) @@ -203,6 +209,7 @@ struct ngx_connection_s { ngx_listening_t *ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen); +ngx_int_t ngx_clone_listening(ngx_conf_t *cf, ngx_listening_t *ls); ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle); ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle); void ngx_configure_listening_sockets(ngx_cycle_t *cycle); diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c index 4852e3bbe..b358f3dbe 100644 --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -493,6 +493,10 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) continue; } + if (ls[i].remain) { + continue; + } + if (ngx_cmp_sockaddr(nls[n].sockaddr, nls[n].socklen, ls[i].sockaddr, ls[i].socklen, 1) == NGX_OK) @@ -540,6 +544,13 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) nls[n].add_deferred = 1; } #endif + +#if (NGX_HAVE_REUSEPORT) + if (nls[n].reuseport && !ls[i].reuseport) { + nls[n].add_reuseport = 1; + } +#endif + break; } } diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c index 2c84daf6e..96a04fded 100644 --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -26,15 +26,15 @@ ngx_inet_addr(u_char *text, size_t len) n = 0; for (p = text; p < text + len; p++) { - - if (octet > 255) { - return INADDR_NONE; - } - c = *p; if (c >= '0' && c <= '9') { octet = octet * 10 + (c - '0'); + + if (octet > 255) { + return INADDR_NONE; + } + continue; } diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c index 2aea37440..08938715d 100644 --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -609,7 +609,7 @@ ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head) return NGX_CONF_ERROR; } - buf = ngx_palloc(cf->pool, sizeof(ngx_log_memory_buf_t)); + buf = ngx_pcalloc(cf->pool, sizeof(ngx_log_memory_buf_t)); if (buf == NULL) { return NGX_CONF_ERROR; } diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c index 3458b209a..d7f915de9 100644 --- a/src/event/modules/ngx_epoll_module.c +++ b/src/event/modules/ngx_epoll_module.c @@ -329,7 +329,7 @@ ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer) #if (NGX_HAVE_EVENTFD) if (ngx_epoll_notify_init(cycle->log) != NGX_OK) { - return NGX_ERROR; + ngx_epoll_module_ctx.actions.notify = NULL; } #endif diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index 5ca6e826a..34a07e4dc 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -126,13 +126,6 @@ static ngx_command_t ngx_event_core_commands[] = { 0, NULL }, - { ngx_string("connections"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_event_connections, - 0, - 0, - NULL }, - { ngx_string("use"), NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_event_use, @@ -732,6 +725,12 @@ ngx_event_process_init(ngx_cycle_t *cycle) ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { +#if (NGX_HAVE_REUSEPORT) + if (ls[i].reuseport && ls[i].worker != ngx_worker) { + continue; + } +#endif + c = ngx_get_connection(ls[i].fd, cycle->log); if (c == NULL) { @@ -812,7 +811,12 @@ ngx_event_process_init(ngx_cycle_t *cycle) rev->handler = ngx_event_accept; - if (ngx_use_accept_mutex) { + if (ngx_use_accept_mutex +#if (NGX_HAVE_REUSEPORT) + && !ls[i].reuseport +#endif + ) + { continue; } @@ -956,12 +960,6 @@ ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return "is duplicate"; } - if (ngx_strcmp(cmd->name.data, "connections") == 0) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "the \"connections\" directive is deprecated, " - "use the \"worker_connections\" directive instead"); - } - value = cf->args->elts; ecf->connections = ngx_atoi(value[1].data, value[1].len); if (ecf->connections == (ngx_uint_t) NGX_ERROR) { diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index 21819dc4d..855c58df4 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -68,6 +68,14 @@ struct ngx_event_s { unsigned posted:1; + unsigned closed:1; + + /* to test on worker exit */ + unsigned channel:1; + unsigned resolver:1; + + unsigned cancelable:1; + #if (NGX_WIN32) /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was successful */ unsigned accept_context_updated:1; @@ -116,15 +124,6 @@ struct ngx_event_s { /* the posted queue */ ngx_queue_t queue; - unsigned closed:1; - - /* to test on worker exit */ - unsigned channel:1; - unsigned resolver:1; - - unsigned cancelable:1; - - #if 0 /* the threads support */ diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index 3f1c0b164..8888f5acc 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -11,7 +11,7 @@ static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle); -static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle); +static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all); static void ngx_close_accepted_connection(ngx_connection_t *c); @@ -109,7 +109,7 @@ ngx_event_accept(ngx_event_t *ev) } if (err == NGX_EMFILE || err == NGX_ENFILE) { - if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle) + if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle, 1) != NGX_OK) { return; @@ -390,7 +390,7 @@ ngx_trylock_accept_mutex(ngx_cycle_t *cycle) "accept mutex lock failed: %ui", ngx_accept_mutex_held); if (ngx_accept_mutex_held) { - if (ngx_disable_accept_events(cycle) == NGX_ERROR) { + if (ngx_disable_accept_events(cycle, 0) == NGX_ERROR) { return NGX_ERROR; } @@ -413,7 +413,7 @@ ngx_enable_accept_events(ngx_cycle_t *cycle) c = ls[i].connection; - if (c->read->active) { + if (c == NULL || c->read->active) { continue; } @@ -427,7 +427,7 @@ ngx_enable_accept_events(ngx_cycle_t *cycle) static ngx_int_t -ngx_disable_accept_events(ngx_cycle_t *cycle) +ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all) { ngx_uint_t i; ngx_listening_t *ls; @@ -438,10 +438,23 @@ ngx_disable_accept_events(ngx_cycle_t *cycle) c = ls[i].connection; - if (!c->read->active) { + if (c == NULL || !c->read->active) { continue; } +#if (NGX_HAVE_REUSEPORT) + + /* + * do not disable accept on worker's own sockets + * when disabling accept events due to accept mutex + */ + + if (ls[i].reuseport && !all) { + continue; + } + +#endif + if (ngx_del_event(c->read, NGX_READ_EVENT, NGX_DISABLE_EVENT) == NGX_ERROR) { diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index 00e8923a0..514c23bac 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -3168,9 +3168,8 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) prev->upstream.ssl_session_reuse, 1); ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols, - (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3 - |NGX_SSL_TLSv1|NGX_SSL_TLSv1_1 - |NGX_SSL_TLSv1_2)); + (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 + |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT"); diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index 275febe65..d6a1794e4 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -561,7 +561,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) prev->prefer_server_ciphers, 0); ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, - (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1 + (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, diff --git a/src/http/modules/ngx_http_upstream_hash_module.c b/src/http/modules/ngx_http_upstream_hash_module.c index e3dd0b6a5..1e2e05cb4 100644 --- a/src/http/modules/ngx_http_upstream_hash_module.c +++ b/src/http/modules/ngx_http_upstream_hash_module.c @@ -277,13 +277,17 @@ ngx_http_upstream_init_chash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) { u_char *host, *port, c; size_t host_len, port_len, size; - uint32_t hash, base_hash, prev_hash; + uint32_t hash, base_hash; ngx_str_t *server; ngx_uint_t npoints, i, j; ngx_http_upstream_rr_peer_t *peer; ngx_http_upstream_rr_peers_t *peers; ngx_http_upstream_chash_points_t *points; ngx_http_upstream_hash_srv_conf_t *hcf; + union { + uint32_t value; + u_char byte[4]; + } prev_hash; if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) { return NGX_ERROR; @@ -350,20 +354,27 @@ ngx_http_upstream_init_chash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) ngx_crc32_update(&base_hash, (u_char *) "", 1); ngx_crc32_update(&base_hash, port, port_len); - prev_hash = 0; + prev_hash.value = 0; npoints = peer->weight * 160; for (j = 0; j < npoints; j++) { hash = base_hash; - ngx_crc32_update(&hash, (u_char *) &prev_hash, sizeof(uint32_t)); + ngx_crc32_update(&hash, prev_hash.byte, 4); ngx_crc32_final(hash); points->point[points->number].hash = hash; points->point[points->number].server = server; points->number++; - prev_hash = hash; +#if (NGX_HAVE_LITTLE_ENDIAN) + prev_hash.value = hash; +#else + prev_hash.byte[0] = (u_char) (hash & 0xff); + prev_hash.byte[1] = (u_char) ((hash >> 8) & 0xff); + prev_hash.byte[2] = (u_char) ((hash >> 16) & 0xff); + prev_hash.byte[3] = (u_char) ((hash >> 24) & 0xff); +#endif } } diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c index 0d0bc5857..a50c55320 100644 --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -1724,9 +1724,8 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) prev->upstream.ssl_session_reuse, 1); ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols, - (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3 - |NGX_SSL_TLSv1|NGX_SSL_TLSv1_1 - |NGX_SSL_TLSv1_2)); + (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 + |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT"); diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index 924c4b548..4642559ea 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -1719,13 +1719,7 @@ ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port) ls->servers = hport; - if (i == last - 1) { - hport->naddrs = last; - - } else { - hport->naddrs = 1; - i = 0; - } + hport->naddrs = i + 1; switch (ls->sockaddr->sa_family) { @@ -1743,6 +1737,10 @@ ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port) break; } + if (ngx_clone_listening(cf, ls) != NGX_OK) { + return NGX_ERROR; + } + addr++; last--; } @@ -1821,6 +1819,10 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr) ls->fastopen = addr->opt.fastopen; #endif +#if (NGX_HAVE_REUSEPORT) + ls->reuseport = addr->opt.reuseport; +#endif + return ls; } diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 81960414f..f5255265e 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -96,18 +96,6 @@ static ngx_conf_post_t ngx_http_core_lowat_post = static ngx_conf_post_handler_pt ngx_http_core_pool_size_p = ngx_http_core_pool_size; -static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_server_names = { - ngx_conf_deprecated, "optimize_server_names", "server_name_in_redirect" -}; - -static ngx_conf_deprecated_t ngx_conf_deprecated_open_file_cache_retest = { - ngx_conf_deprecated, "open_file_cache_retest", "open_file_cache_valid" -}; - -static ngx_conf_deprecated_t ngx_conf_deprecated_satisfy_any = { - ngx_conf_deprecated, "satisfy_any", "satisfy" -}; - static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = { { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF }, @@ -255,13 +243,6 @@ static ngx_command_t ngx_http_core_commands[] = { offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers), NULL }, - { ngx_string("optimize_server_names"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect), - &ngx_conf_deprecated_optimize_server_names }, - { ngx_string("ignore_invalid_headers"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -519,13 +500,6 @@ static ngx_command_t ngx_http_core_commands[] = { offsetof(ngx_http_core_loc_conf_t, satisfy), &ngx_http_core_satisfy }, - { ngx_string("satisfy_any"), - 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_core_loc_conf_t, satisfy), - &ngx_conf_deprecated_satisfy_any }, - { ngx_string("internal"), NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, ngx_http_core_internal, @@ -689,13 +663,6 @@ static ngx_command_t ngx_http_core_commands[] = { offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid), NULL }, - { ngx_string("open_file_cache_retest"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_sec_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid), - &ngx_conf_deprecated_open_file_cache_retest }, - { ngx_string("open_file_cache_min_uses"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, @@ -4199,6 +4166,19 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) #endif } + if (ngx_strcmp(value[n].data, "reuseport") == 0) { +#if (NGX_HAVE_REUSEPORT) + lsopt.reuseport = 1; + lsopt.set = 1; + lsopt.bind = 1; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "reuseport is not supported " + "on this platform, ignored"); +#endif + continue; + } + if (ngx_strcmp(value[n].data, "ssl") == 0) { #if (NGX_HTTP_SSL) lsopt.ssl = 1; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index e0ca2ce47..e6be5ac99 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -85,6 +85,9 @@ typedef struct { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:1; #endif +#if (NGX_HAVE_REUSEPORT) + unsigned reuseport:1; +#endif unsigned so_keepalive:2; unsigned proxy_protocol:1; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index ba01d1ce5..47b574e84 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -363,6 +363,10 @@ static ngx_http_variable_t ngx_http_upstream_vars[] = { ngx_http_upstream_status_variable, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, + { ngx_string("upstream_connect_time"), NULL, + ngx_http_upstream_response_time_variable, 2, + NGX_HTTP_VAR_NOCACHEABLE, 0 }, + { ngx_string("upstream_header_time"), NULL, ngx_http_upstream_response_time_variable, 1, NGX_HTTP_VAR_NOCACHEABLE, 0 }, @@ -1300,15 +1304,12 @@ static void ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u) { ngx_int_t rc; - ngx_time_t *tp; ngx_connection_t *c; r->connection->log->action = "connecting to upstream"; - if (u->state && u->state->response_sec) { - tp = ngx_timeofday(); - u->state->response_sec = tp->sec - u->state->response_sec; - u->state->response_msec = tp->msec - u->state->response_msec; + if (u->state && u->state->response_time) { + u->state->response_time = ngx_current_msec - u->state->response_time; } u->state = ngx_array_push(r->upstream_states); @@ -1320,10 +1321,9 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u) ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t)); - tp = ngx_timeofday(); - u->state->response_sec = tp->sec; - u->state->response_msec = tp->msec; - u->state->header_sec = (time_t) NGX_ERROR; + u->state->response_time = ngx_current_msec; + u->state->connect_time = (ngx_msec_t) -1; + u->state->header_time = (ngx_msec_t) -1; rc = ngx_event_connect_peer(&u->peer); @@ -1765,6 +1765,10 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http upstream send request"); + if (u->state->connect_time == (ngx_msec_t) -1) { + u->state->connect_time = ngx_current_msec - u->state->response_time; + } + if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) { ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); return; @@ -2017,7 +2021,6 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u) { ssize_t n; ngx_int_t rc; - ngx_time_t *tp; ngx_connection_t *c; c = u->peer.connection; @@ -2138,9 +2141,7 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u) /* rc == NGX_OK */ - tp = ngx_timeofday(); - u->state->header_sec = tp->sec - u->state->response_sec; - u->state->header_msec = tp->msec - u->state->response_msec; + u->state->header_time = ngx_current_msec - u->state->response_time; if (u->headers_in.status_n >= NGX_HTTP_SPECIAL_RESPONSE) { @@ -3923,8 +3924,7 @@ static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_int_t rc) { - ngx_uint_t flush; - ngx_time_t *tp; + ngx_uint_t flush; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "finalize http upstream request: %i", rc); @@ -3943,10 +3943,8 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r, u->resolved->ctx = NULL; } - if (u->state && u->state->response_sec) { - tp = ngx_timeofday(); - u->state->response_sec = tp->sec - u->state->response_sec; - u->state->response_msec = tp->msec - u->state->response_msec; + if (u->state && u->state->response_time) { + u->state->response_time = ngx_current_msec - u->state->response_time; if (u->pipe && u->pipe->read_length) { u->state->response_length = u->pipe->read_length; @@ -5020,15 +5018,14 @@ ngx_http_upstream_response_time_variable(ngx_http_request_t *r, for ( ;; ) { if (state[i].status) { - if (data - && state[i].header_sec != (time_t) NGX_ERROR) - { - ms = (ngx_msec_int_t) - (state[i].header_sec * 1000 + state[i].header_msec); + if (data == 1 && state[i].header_time != (ngx_msec_t) -1) { + ms = state[i].header_time; + + } else if (data == 2 && state[i].connect_time != (ngx_msec_t) -1) { + ms = state[i].connect_time; } else { - ms = (ngx_msec_int_t) - (state[i].response_sec * 1000 + state[i].response_msec); + ms = state[i].response_time; } ms = ngx_max(ms, 0); diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index 28e4142fc..64157e6a7 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -58,10 +58,9 @@ typedef struct { ngx_uint_t bl_state; ngx_uint_t status; - time_t response_sec; - ngx_uint_t response_msec; - time_t header_sec; - ngx_uint_t header_msec; + ngx_msec_t response_time; + ngx_msec_t connect_time; + ngx_msec_t header_time; off_t response_length; ngx_str_t *peer; diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c index 487b0e3cc..d6ae33bf1 100644 --- a/src/http/ngx_http_upstream_round_robin.c +++ b/src/http/ngx_http_upstream_round_robin.c @@ -622,6 +622,11 @@ ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, if (peer->max_fails) { peer->effective_weight -= peer->weight / peer->max_fails; + + if (peer->fails >= peer->max_fails) { + ngx_log_error(NGX_LOG_WARN, pc->log, 0, + "upstream server temporarily disabled"); + } } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, diff --git a/src/mail/ngx_mail.c b/src/mail/ngx_mail.c index 3e4b2cbf4..f10f08c5f 100644 --- a/src/mail/ngx_mail.c +++ b/src/mail/ngx_mail.c @@ -36,13 +36,6 @@ static ngx_command_t ngx_mail_commands[] = { 0, NULL }, - { ngx_string("imap"), - NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_mail_block, - 0, - 0, - NULL }, - ngx_null_command }; @@ -83,12 +76,6 @@ ngx_mail_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_mail_core_srv_conf_t **cscfp; ngx_mail_core_main_conf_t *cmcf; - if (cmd->name.data[0] == 'i') { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "the \"imap\" directive is deprecated, " - "use the \"mail\" directive instead"); - } - /* the main mail context */ ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t)); @@ -405,13 +392,7 @@ ngx_mail_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) ls->servers = mport; - if (i == last - 1) { - mport->naddrs = last; - - } else { - mport->naddrs = 1; - i = 0; - } + mport->naddrs = i + 1; switch (ls->sockaddr->sa_family) { #if (NGX_HAVE_INET6) diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h index e15bc6342..dd8a23abb 100644 --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -131,8 +131,6 @@ typedef struct { ngx_msec_t timeout; ngx_msec_t resolver_timeout; - ngx_flag_t so_keepalive; - ngx_str_t server_name; u_char *file_name; diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c index 9f349fa5e..ab455b8d9 100644 --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_core_module.c @@ -27,12 +27,6 @@ static char *ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static ngx_conf_deprecated_t ngx_conf_deprecated_so_keepalive = { - ngx_conf_deprecated, "so_keepalive", - "so_keepalive\" parameter of the \"listen" -}; - - static ngx_command_t ngx_mail_core_commands[] = { { ngx_string("server"), @@ -56,13 +50,6 @@ static ngx_command_t ngx_mail_core_commands[] = { 0, NULL }, - { ngx_string("so_keepalive"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, so_keepalive), - &ngx_conf_deprecated_so_keepalive }, - { ngx_string("timeout"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, @@ -175,7 +162,6 @@ ngx_mail_core_create_srv_conf(ngx_conf_t *cf) cscf->timeout = NGX_CONF_UNSET_MSEC; cscf->resolver_timeout = NGX_CONF_UNSET_MSEC; - cscf->so_keepalive = NGX_CONF_UNSET; cscf->resolver = NGX_CONF_UNSET_PTR; @@ -196,8 +182,6 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_msec_value(conf->resolver_timeout, prev->resolver_timeout, 30000); - ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0); - ngx_conf_merge_str_value(conf->server_name, prev->server_name, ""); diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c index 41cbcf6e3..3802c3e67 100644 --- a/src/mail/ngx_mail_proxy_module.c +++ b/src/mail/ngx_mail_proxy_module.c @@ -111,7 +111,6 @@ static u_char smtp_auth_ok[] = "235 2.0.0 OK" CRLF; void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer) { - int keepalive; ngx_int_t rc; ngx_mail_proxy_ctx_t *p; ngx_mail_proxy_conf_t *pcf; @@ -121,18 +120,6 @@ ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer) cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); - if (cscf->so_keepalive) { - keepalive = 1; - - if (setsockopt(s->connection->fd, SOL_SOCKET, SO_KEEPALIVE, - (const void *) &keepalive, sizeof(int)) - == -1) - { - ngx_log_error(NGX_LOG_ALERT, s->connection->log, ngx_socket_errno, - "setsockopt(SO_KEEPALIVE) failed"); - } - } - p = ngx_pcalloc(s->connection->pool, sizeof(ngx_mail_proxy_ctx_t)); if (p == NULL) { ngx_mail_session_internal_server_error(s); diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c index e1efb61d6..1075410da 100644 --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -284,7 +284,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child) prev->prefer_server_ciphers, 0); ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, - (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1 + (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); diff --git a/src/os/unix/ngx_posix_config.h b/src/os/unix/ngx_posix_config.h index d725659df..443c4b001 100644 --- a/src/os/unix/ngx_posix_config.h +++ b/src/os/unix/ngx_posix_config.h @@ -21,6 +21,14 @@ #endif +#if (NGX_GNU_HURD) +#ifndef _GNU_SOURCE +#define _GNU_SOURCE /* accept4() */ +#endif +#define _FILE_OFFSET_BITS 64 +#endif + + #ifdef __CYGWIN__ #define timezonevar /* timezone is variable */ #define NGX_BROKEN_SCM_RIGHTS 1 diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index 50676326f..c69932ecd 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -29,6 +29,7 @@ static void ngx_cache_loader_process_handler(ngx_event_t *ev); ngx_uint_t ngx_process; +ngx_uint_t ngx_worker; ngx_pid_t ngx_pid; sig_atomic_t ngx_reap; @@ -731,6 +732,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) ngx_connection_t *c; ngx_process = NGX_PROCESS_WORKER; + ngx_worker = worker; ngx_worker_process_init(cycle, worker); diff --git a/src/os/unix/ngx_process_cycle.h b/src/os/unix/ngx_process_cycle.h index d44c377ce..69495d5f4 100644 --- a/src/os/unix/ngx_process_cycle.h +++ b/src/os/unix/ngx_process_cycle.h @@ -39,6 +39,7 @@ void ngx_single_process_cycle(ngx_cycle_t *cycle); extern ngx_uint_t ngx_process; +extern ngx_uint_t ngx_worker; extern ngx_pid_t ngx_pid; extern ngx_pid_t ngx_new_binary; extern ngx_uint_t ngx_inherited; diff --git a/src/stream/ngx_stream.c b/src/stream/ngx_stream.c index e5ffcf9bc..1c5e7a87c 100644 --- a/src/stream/ngx_stream.c +++ b/src/stream/ngx_stream.c @@ -393,13 +393,7 @@ ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) ls->servers = stport; - if (i == last - 1) { - stport->naddrs = last; - - } else { - stport->naddrs = 1; - i = 0; - } + stport->naddrs = i + 1; switch (ls->sockaddr->sa_family) { #if (NGX_HAVE_INET6) @@ -416,6 +410,10 @@ ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) break; } + if (ngx_clone_listening(cf, ls) != NGX_OK) { + return NGX_CONF_ERROR; + } + addr++; last--; } diff --git a/src/stream/ngx_stream.h b/src/stream/ngx_stream.h index 83a43a41f..a10f68fff 100644 --- a/src/stream/ngx_stream.h +++ b/src/stream/ngx_stream.h @@ -45,6 +45,9 @@ typedef struct { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:1; #endif +#if (NGX_HAVE_REUSEPORT) + unsigned reuseport:1; +#endif unsigned so_keepalive:2; #if (NGX_HAVE_KEEPALIVE_TUNABLE) int tcp_keepidle; diff --git a/src/stream/ngx_stream_core_module.c b/src/stream/ngx_stream_core_module.c index c0df412a5..c8d8e66bc 100644 --- a/src/stream/ngx_stream_core_module.c +++ b/src/stream/ngx_stream_core_module.c @@ -384,6 +384,18 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) #endif } + if (ngx_strcmp(value[i].data, "reuseport") == 0) { +#if (NGX_HAVE_REUSEPORT) + ls->reuseport = 1; + ls->bind = 1; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "reuseport is not supported " + "on this platform, ignored"); +#endif + continue; + } + if (ngx_strcmp(value[i].data, "ssl") == 0) { #if (NGX_STREAM_SSL) ls->ssl = 1; diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c index 8727629fd..a34b7ceb9 100644 --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -1139,9 +1139,8 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) prev->ssl_session_reuse, 1); ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols, - (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3 - |NGX_SSL_TLSv1|NGX_SSL_TLSv1_1 - |NGX_SSL_TLSv1_2)); + (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 + |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT"); diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c index ecdd14c56..4b27a1e3e 100644 --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -211,7 +211,7 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child) prev->prefer_server_ciphers, 0); ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, - (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1 + (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); ngx_conf_merge_str_value(conf->certificate, prev->certificate, ""); diff --git a/src/stream/ngx_stream_upstream_hash_module.c b/src/stream/ngx_stream_upstream_hash_module.c index 14f50222d..88e74145f 100644 --- a/src/stream/ngx_stream_upstream_hash_module.c +++ b/src/stream/ngx_stream_upstream_hash_module.c @@ -271,13 +271,17 @@ ngx_stream_upstream_init_chash(ngx_conf_t *cf, { u_char *host, *port, c; size_t host_len, port_len, size; - uint32_t hash, base_hash, prev_hash; + uint32_t hash, base_hash; ngx_str_t *server; ngx_uint_t npoints, i, j; ngx_stream_upstream_rr_peer_t *peer; ngx_stream_upstream_rr_peers_t *peers; ngx_stream_upstream_chash_points_t *points; ngx_stream_upstream_hash_srv_conf_t *hcf; + union { + uint32_t value; + u_char byte[4]; + } prev_hash; if (ngx_stream_upstream_init_round_robin(cf, us) != NGX_OK) { return NGX_ERROR; @@ -344,20 +348,27 @@ ngx_stream_upstream_init_chash(ngx_conf_t *cf, ngx_crc32_update(&base_hash, (u_char *) "", 1); ngx_crc32_update(&base_hash, port, port_len); - prev_hash = 0; + prev_hash.value = 0; npoints = peer->weight * 160; for (j = 0; j < npoints; j++) { hash = base_hash; - ngx_crc32_update(&hash, (u_char *) &prev_hash, sizeof(uint32_t)); + ngx_crc32_update(&hash, prev_hash.byte, 4); ngx_crc32_final(hash); points->point[points->number].hash = hash; points->point[points->number].server = server; points->number++; - prev_hash = hash; +#if (NGX_HAVE_LITTLE_ENDIAN) + prev_hash.value = hash; +#else + prev_hash.byte[0] = (u_char) (hash & 0xff); + prev_hash.byte[1] = (u_char) ((hash >> 8) & 0xff); + prev_hash.byte[2] = (u_char) ((hash >> 16) & 0xff); + prev_hash.byte[3] = (u_char) ((hash >> 24) & 0xff); +#endif } } diff --git a/src/stream/ngx_stream_upstream_round_robin.c b/src/stream/ngx_stream_upstream_round_robin.c index c9157cd99..efedb2882 100644 --- a/src/stream/ngx_stream_upstream_round_robin.c +++ b/src/stream/ngx_stream_upstream_round_robin.c @@ -495,6 +495,11 @@ ngx_stream_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, if (peer->max_fails) { peer->effective_weight -= peer->weight / peer->max_fails; + + if (peer->fails >= peer->max_fails) { + ngx_log_error(NGX_LOG_WARN, pc->log, 0, + "upstream server temporarily disabled"); + } } ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0, |