details:   
https://github.com/nginx/nginx/commit/5b8a5c08ce28639e788734b2528faad70baa113c
branches:  master
commit:    5b8a5c08ce28639e788734b2528faad70baa113c
user:      Sergey Kandaurov <pluk...@nginx.com>
date:      Mon, 26 May 2025 16:11:36 +0400
description:
Core: added support for TCP keepalive parameters on macOS.

The support first appeared in OS X Mavericks 10.9 and documented since
OS X Yosemite 10.10.

It has a subtle implementation difference from other operating systems
in that the TCP_KEEPALIVE socket option (used in place of TCP_KEEPIDLE)
isn't inherited from a listening socket to an accepted socket.

An apparent reason for this behaviour is that it might be preserved for
the sake of backward compatibility.  The TCP_KEEPALIVE socket option is
not inherited since appearance in OS X Panther 10.3, which long predates
two other TCP_KEEPINTVL and TCP_KEEPCNT socket options.

Thanks to Andy Pan for initial work.

---
 auto/os/darwin               | 16 ++++++++++++++++
 auto/unix                    | 26 ++++++++++++++------------
 src/core/ngx_connection.c    |  4 ++++
 src/event/ngx_event_accept.c | 17 +++++++++++++++++
 4 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/auto/os/darwin b/auto/os/darwin
index 429468f7f..0ede28d0a 100644
--- a/auto/os/darwin
+++ b/auto/os/darwin
@@ -118,3 +118,19 @@ ngx_feature_libs=
 ngx_feature_test="int32_t  lock = 0;
                   if (!OSAtomicCompareAndSwap32Barrier(0, 1, &lock)) return 1"
 . auto/feature
+
+
+ngx_feature="TCP_KEEPALIVE"
+ngx_feature_name="NGX_HAVE_KEEPALIVE_TUNABLE"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+                  #include <netinet/in.h>
+                  #include <netinet/tcp.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_KEEPALIVE, NULL, 0);
+                  setsockopt(0, IPPROTO_TCP, TCP_KEEPINTVL, NULL, 0);
+                  setsockopt(0, IPPROTO_TCP, TCP_KEEPCNT, NULL, 0)"
+. auto/feature
+
+NGX_KEEPALIVE_CHECKED=YES
diff --git a/auto/unix b/auto/unix
index 8bd1b1370..0dd66cfcd 100644
--- a/auto/unix
+++ b/auto/unix
@@ -508,18 +508,20 @@ ngx_feature_test="setsockopt(0, IPPROTO_TCP, 
TCP_DEFER_ACCEPT, NULL, 0)"
 . auto/feature
 
 
-ngx_feature="TCP_KEEPIDLE"
-ngx_feature_name="NGX_HAVE_KEEPALIVE_TUNABLE"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>
-                  #include <netinet/in.h>
-                  #include <netinet/tcp.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_KEEPIDLE, NULL, 0);
-                  setsockopt(0, IPPROTO_TCP, TCP_KEEPINTVL, NULL, 0);
-                  setsockopt(0, IPPROTO_TCP, TCP_KEEPCNT, NULL, 0)"
-. auto/feature
+if test -z "$NGX_KEEPALIVE_CHECKED"; then
+    ngx_feature="TCP_KEEPIDLE"
+    ngx_feature_name="NGX_HAVE_KEEPALIVE_TUNABLE"
+    ngx_feature_run=no
+    ngx_feature_incs="#include <sys/socket.h>
+                      #include <netinet/in.h>
+                      #include <netinet/tcp.h>"
+    ngx_feature_path=
+    ngx_feature_libs=
+    ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_KEEPIDLE, NULL, 0);
+                      setsockopt(0, IPPROTO_TCP, TCP_KEEPINTVL, NULL, 0);
+                      setsockopt(0, IPPROTO_TCP, TCP_KEEPCNT, NULL, 0)"
+    . auto/feature
+fi
 
 
 ngx_feature="TCP_FASTOPEN"
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index 75809d9ad..7cae295eb 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -765,6 +765,8 @@ ngx_configure_listening_sockets(ngx_cycle_t *cycle)
 
 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
 
+#if !(NGX_DARWIN)
+
         if (ls[i].keepidle) {
             value = ls[i].keepidle;
 
@@ -782,6 +784,8 @@ ngx_configure_listening_sockets(ngx_cycle_t *cycle)
             }
         }
 
+#endif
+
         if (ls[i].keepintvl) {
             value = ls[i].keepintvl;
 
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index 27038799d..033d7e021 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -203,6 +203,23 @@ ngx_event_accept(ngx_event_t *ev)
             }
         }
 
+#if (NGX_HAVE_KEEPALIVE_TUNABLE && NGX_DARWIN)
+
+        /* Darwin doesn't inherit TCP_KEEPALIVE from a listening socket */
+
+        if (ls->keepidle) {
+            if (setsockopt(s, IPPROTO_TCP, TCP_KEEPALIVE,
+                           (const void *) &ls->keepidle, sizeof(int))
+                == -1)
+            {
+                ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
+                              "setsockopt(TCP_KEEPALIVE, %d) failed, ignored",
+                              ls->keepidle);
+            }
+        }
+
+#endif
+
         *log = ls->log;
 
         c->recv = ngx_recv;
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel

Reply via email to