Welcome! Log In Create A New Profile

Advanced

[PATCH] Add support for tcp_user_timeout in http listen directive

Andy Isaacson
June 29, 2015 06:56PM
# HG changeset patch
# User Andy Isaacson <adi@orionlabs.co>
# Date 1435618451 25200
# Mon Jun 29 15:54:11 2015 -0700
# Node ID c11304760218324ea55de7250a613af8f13e431b
# Parent b95e70ae6bcdbae99a967df01e1011839f19ee0e
Add support for tcp_user_timeout in http listen directive

This commit adds support for a new tcp_user_timeout=<timeout_sec>
parameter to the listen directive. When enabled and set to a value
greater than zero, the TCP_USER_TIMEOUT sockopt is set. From tcp(7):

This specifies the maximum amount of time in milliseconds
that transmitted data may remain unacknowledged before TCP
will forcibly close the corresponding connection and return
ETIMEDOUT to the application.

Without this capability, a HTTP longpoll connection can remain active
for up to 950 seconds after the last ACK from the client.

Note that the tcp_user_timeout value is specified in (integer) seconds,
but the setsockopt API is specified in milliseconds.

This capability is similar to the systemwide configuration
net.ipv4.tcp_retries2 on Linux, but more flexible and per-socket.

diff -r b95e70ae6bcd -r c11304760218 auto/unix
--- a/auto/unix Thu Sep 05 16:53:02 2013 +0400
+++ b/auto/unix Mon Jun 29 15:54:11 2015 -0700
@@ -330,6 +330,18 @@
. auto/feature


+ngx_feature="TCP_USER_TIMEOUT"
+ngx_feature_name="NGX_HAVE_TCP_USER_TIMEOUT"
+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_USER_TIMEOUT, NULL, 0)"
+. auto/feature
+
+
ngx_feature="TCP_KEEPIDLE"
ngx_feature_name="NGX_HAVE_KEEPALIVE_TUNABLE"
ngx_feature_run=no
diff -r b95e70ae6bcd -r c11304760218 src/core/ngx_connection.h
--- a/src/core/ngx_connection.h Thu Sep 05 16:53:02 2013 +0400
+++ b/src/core/ngx_connection.h Mon Jun 29 15:54:11 2015 -0700
@@ -80,6 +80,10 @@
int setfib;
#endif

+#if (NGX_HAVE_TCP_USER_TIMEOUT)
+ int tcp_user_timeout;
+#endif
+
};


diff -r b95e70ae6bcd -r c11304760218 src/event/ngx_event_accept.c
--- a/src/event/ngx_event_accept.c Thu Sep 05 16:53:02 2013 +0400
+++ b/src/event/ngx_event_accept.c Mon Jun 29 15:54:11 2015 -0700
@@ -284,6 +284,23 @@
}
}

+#if (NGX_HAVE_TCP_USER_TIMEOUT)
+#ifdef TCP_USER_TIMEOUT
+ if (ls->tcp_user_timeout) {
+ int value = ls->tcp_user_timeout;
+
+ if (setsockopt(s, IPPROTO_TCP, TCP_USER_TIMEOUT, &value,
+ sizeof(int))
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
+ "setsockopt(TCP_USER_TIMEOUT, %d) for %V failed",
+ value, c->addr_text);
+ }
+ }
+#endif
+#endif
+
#if (NGX_DEBUG)
{

diff -r b95e70ae6bcd -r c11304760218 src/http/ngx_http.c
--- a/src/http/ngx_http.c Thu Sep 05 16:53:02 2013 +0400
+++ b/src/http/ngx_http.c Mon Jun 29 15:54:11 2015 -0700
@@ -1800,6 +1800,10 @@
ls->deferred_accept = addr->opt.deferred_accept;
#endif

+#if (NGX_HAVE_TCP_USER_TIMEOUT && defined TCP_USER_TIMEOUT)
+ ls->tcp_user_timeout = addr->opt.tcp_user_timeout;
+#endif
+
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
ls->ipv6only = addr->opt.ipv6only;
#endif
diff -r b95e70ae6bcd -r c11304760218 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Thu Sep 05 16:53:02 2013 +0400
+++ b/src/http/ngx_http_core_module.c Mon Jun 29 15:54:11 2015 -0700
@@ -4085,6 +4085,31 @@
continue;
}

+ if (ngx_strncmp(value[n].data, "tcp_user_timeout=", 17) == 0) {
+#if (NGX_HAVE_TCP_USER_TIMEOUT && defined TCP_USER_TIMEOUT)
+ int timeout_sec = ngx_atoi(value[n].data + 17, value[n].len - 17);
+
+ /*
+ * convert from seconds (in config file) to milliseconds (for
+ * setsockopt)
+ */
+ lsopt.tcp_user_timeout = timeout_sec * 1000;
+
+ if (lsopt.tcp_user_timeout < 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "Invalid tcp_user_timeout \"%V\"",
+ &value[n]);
+ return NGX_CONF_ERROR;
+ }
+#else
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "tcp_user_timeout \"%V\" is not supported on "
+ "this platform, ignored",
+ &value[n]);
+#endif
+ continue;
+ }
+
if (ngx_strcmp(value[n].data, "deferred") == 0) {
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
lsopt.deferred_accept = 1;
diff -r b95e70ae6bcd -r c11304760218 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Thu Sep 05 16:53:02 2013 +0400
+++ b/src/http/ngx_http_core_module.h Mon Jun 29 15:54:11 2015 -0700
@@ -102,6 +102,10 @@
ngx_uint_t deferred_accept;
#endif

+#if (NGX_HAVE_TCP_USER_TIMEOUT && defined TCP_USER_TIMEOUT)
+ int tcp_user_timeout;
+#endif
+
u_char addr[NGX_SOCKADDR_STRLEN + 1];
} ngx_http_listen_opt_t;


_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[PATCH] Add support for tcp_user_timeout in http listen directive

Andy Isaacson 1112 June 29, 2015 06:56PM

Re: [PATCH] Add support for tcp_user_timeout in http listen directive

Maxim Dounin 490 July 08, 2015 12:34PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 185
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready