changeset 8977:7c2adf237091 quic

Merged with the default branch.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 25 Jan 2022 23:42:48 +0300
parents 4646a981111f (current diff) 56ead48cfe88 (diff)
children c37ea624c307
files src/event/ngx_event.c src/event/ngx_event.h src/event/ngx_event_openssl.c src/http/ngx_http_header_filter_module.c
diffstat 10 files changed, 136 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags
+++ b/.hgtags
@@ -466,3 +466,4 @@ bfbc52374adcbf2f9060afd62de940f6fab3bba5
 2217a9c1d0b86026f22700b3c089545db1964f55 release-1.21.3
 39be8a682c58308d9399cddd57e37f9fdb7bdf3e release-1.21.4
 d986378168fd4d70e0121cabac274c560cca9bdf release-1.21.5
+714eb4b2c09e712fb2572a2164ce2bf67638ccac release-1.21.6
--- a/contrib/vim/syntax/nginx.vim
+++ b/contrib/vim/syntax/nginx.vim
@@ -5,6 +5,9 @@ if exists("b:current_syntax")
   finish
 end
 
+let s:save_cpo = &cpo
+set cpo&vim
+
 " general syntax
 
 if has("patch-7.4.1142")
@@ -2485,4 +2488,7 @@ hi def link ngxDirectiveThirdPartyDeprec
 hi def link ngxListenOptions Keyword
 hi def link ngxListenOptionsDeprecated Error
 
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
 let b:current_syntax = "nginx"
--- a/docs/xml/nginx/changes.xml
+++ b/docs/xml/nginx/changes.xml
@@ -5,6 +5,44 @@
 <change_log title="nginx">
 
 
+<changes ver="1.21.6" date="2022-01-25">
+
+<change type="bugfix">
+<para lang="ru">
+при использование EPOLLEXCLUSIVE на Linux
+распределение клиентских соединений между рабочими процессами
+было неравномерным.
+</para>
+<para lang="en">
+when using EPOLLEXCLUSIVE on Linux
+client connections were unevenly distributed
+among worker processes.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+во время плавного завершения старых рабочих процессов
+nginx возвращал в ответах строку заголовка "Connection: keep-alive".
+</para>
+<para lang="en">
+nginx returned the "Connection: keep-alive" header line in responses
+during graceful shutdown of old worker processes.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+в директиве ssl_session_ticket_key при использовании TLSv1.3.
+</para>
+<para lang="en">
+in the "ssl_session_ticket_key" when using TLSv1.3.
+</para>
+</change>
+
+</changes>
+
+
 <changes ver="1.21.5" date="2021-12-28">
 
 <change type="change">
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -9,8 +9,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version      1021005
-#define NGINX_VERSION      "1.21.5"
+#define nginx_version      1021006
+#define NGINX_VERSION      "1.21.6"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #ifdef NGX_BUILD
--- a/src/core/ngx_rwlock.c
+++ b/src/core/ngx_rwlock.c
@@ -89,22 +89,10 @@ ngx_rwlock_rlock(ngx_atomic_t *lock)
 void
 ngx_rwlock_unlock(ngx_atomic_t *lock)
 {
-    ngx_atomic_uint_t  readers;
-
-    readers = *lock;
-
-    if (readers == NGX_RWLOCK_WLOCK) {
+    if (*lock == NGX_RWLOCK_WLOCK) {
         (void) ngx_atomic_cmp_set(lock, NGX_RWLOCK_WLOCK, 0);
-        return;
-    }
-
-    for ( ;; ) {
-
-        if (ngx_atomic_cmp_set(lock, readers, readers - 1)) {
-            return;
-        }
-
-        readers = *lock;
+    } else {
+        (void) ngx_atomic_fetch_add(lock, -1);
     }
 }
 
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -55,6 +55,7 @@ ngx_uint_t            ngx_accept_events;
 ngx_uint_t            ngx_accept_mutex_held;
 ngx_msec_t            ngx_accept_mutex_delay;
 ngx_int_t             ngx_accept_disabled;
+ngx_uint_t            ngx_use_exclusive_accept;
 
 
 #if (NGX_STAT_STUB)
@@ -662,6 +663,8 @@ ngx_event_process_init(ngx_cycle_t *cycl
 
 #endif
 
+    ngx_use_exclusive_accept = 0;
+
     ngx_queue_init(&ngx_posted_accept_events);
     ngx_queue_init(&ngx_posted_next_events);
     ngx_queue_init(&ngx_posted_events);
@@ -907,6 +910,8 @@ ngx_event_process_init(ngx_cycle_t *cycl
         if ((ngx_event_flags & NGX_USE_EPOLL_EVENT)
             && ccf->worker_processes > 1)
         {
+            ngx_use_exclusive_accept = 1;
+
             if (ngx_add_event(rev, NGX_READ_EVENT, NGX_EXCLUSIVE_EVENT)
                 == NGX_ERROR)
             {
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -462,6 +462,7 @@ extern ngx_uint_t             ngx_accept
 extern ngx_uint_t             ngx_accept_mutex_held;
 extern ngx_msec_t             ngx_accept_mutex_delay;
 extern ngx_int_t              ngx_accept_disabled;
+extern ngx_uint_t             ngx_use_exclusive_accept;
 
 
 #if (NGX_STAT_STUB)
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -11,6 +11,9 @@
 
 
 static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all);
+#if (NGX_HAVE_EPOLLEXCLUSIVE)
+static void ngx_reorder_accept_events(ngx_listening_t *ls);
+#endif
 static void ngx_close_accepted_connection(ngx_connection_t *c);
 
 
@@ -314,6 +317,10 @@ ngx_event_accept(ngx_event_t *ev)
         }
 
     } while (ev->available);
+
+#if (NGX_HAVE_EPOLLEXCLUSIVE)
+    ngx_reorder_accept_events(ls);
+#endif
 }
 
 
@@ -420,6 +427,57 @@ ngx_disable_accept_events(ngx_cycle_t *c
 }
 
 
+#if (NGX_HAVE_EPOLLEXCLUSIVE)
+
+static void
+ngx_reorder_accept_events(ngx_listening_t *ls)
+{
+    ngx_connection_t  *c;
+
+    /*
+     * Linux with EPOLLEXCLUSIVE usually notifies only the process which
+     * was first to add the listening socket to the epoll instance.  As
+     * a result most of the connections are handled by the first worker
+     * process.  To fix this, we re-add the socket periodically, so other
+     * workers will get a chance to accept connections.
+     */
+
+    if (!ngx_use_exclusive_accept) {
+        return;
+    }
+
+#if (NGX_HAVE_REUSEPORT)
+
+    if (ls->reuseport) {
+        return;
+    }
+
+#endif
+
+    c = ls->connection;
+
+    if (c->requests++ % 16 != 0
+        && ngx_accept_disabled <= 0)
+    {
+        return;
+    }
+
+    if (ngx_del_event(c->read, NGX_READ_EVENT, NGX_DISABLE_EVENT)
+        == NGX_ERROR)
+    {
+        return;
+    }
+
+    if (ngx_add_event(c->read, NGX_READ_EVENT, NGX_EXCLUSIVE_EVENT)
+        == NGX_ERROR)
+    {
+        return;
+    }
+}
+
+#endif
+
+
 static void
 ngx_close_accepted_connection(ngx_connection_t *c)
 {
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -1383,6 +1383,9 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_
     if (SSL_CTX_set0_tmp_dh_pkey(ssl->ctx, dh) != 1) {
         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
                       "SSL_CTX_set0_tmp_dh_pkey(\%s\") failed", file->data);
+#if (OPENSSL_VERSION_NUMBER >= 0x3000001fL)
+        EVP_PKEY_free(dh);
+#endif
         BIO_free(bio);
         return NGX_ERROR;
     }
@@ -4455,7 +4458,21 @@ ngx_ssl_session_ticket_key_callback(ngx_
             return -1;
         }
 
-        return (i == 0) ? 1 : 2 /* renew */;
+        /* renew if TLSv1.3 */
+
+#ifdef TLS1_3_VERSION
+        if (SSL_version(ssl_conn) == TLS1_3_VERSION) {
+            return 2;
+        }
+#endif
+
+        /* renew if non-default key */
+
+        if (i != 0) {
+            return 2;
+        }
+
+        return 1;
     }
 }
 
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -197,6 +197,10 @@ ngx_http_header_filter(ngx_http_request_
         }
     }
 
+    if (r->keepalive && (ngx_terminate || ngx_exiting)) {
+        r->keepalive = 0;
+    }
+
     len = sizeof("HTTP/1.x ") - 1 + sizeof(CRLF) - 1
           /* the end of the header */
           + sizeof(CRLF) - 1;