diff --git a/doc/manpages/account-server.conf.5 b/doc/manpages/account-server.conf.5 index 018ea4f663..f48d231a22 100644 --- a/doc/manpages/account-server.conf.5 +++ b/doc/manpages/account-server.conf.5 @@ -57,6 +57,8 @@ IP address the account server should bind to. The default is 0.0.0.0 which will it bind to all available addresses. .IP "\fBbind_port\fR" TCP port the account server should bind to. The default is 6202. +.IP "\fBkeep_idle\fR" +Value to set for socket TCP_KEEPIDLE. The default value is 600. .IP "\fBbind_timeout\fR" Timeout to bind socket. The default is 30. .IP \fBbacklog\fR diff --git a/doc/manpages/container-server.conf.5 b/doc/manpages/container-server.conf.5 index c4fb25b241..1ca31e03fa 100644 --- a/doc/manpages/container-server.conf.5 +++ b/doc/manpages/container-server.conf.5 @@ -57,6 +57,8 @@ IP address the container server should bind to. The default is 0.0.0.0 which wil it bind to all available addresses. .IP "\fBbind_port\fR" TCP port the container server should bind to. The default is 6201. +.IP "\fBkeep_idle\fR" +Value to set for socket TCP_KEEPIDLE. The default value is 600. .IP "\fBbind_timeout\fR" Timeout to bind socket. The default is 30. .IP \fBbacklog\fR diff --git a/doc/manpages/object-server.conf.5 b/doc/manpages/object-server.conf.5 index 908b5f48da..6641d4f301 100644 --- a/doc/manpages/object-server.conf.5 +++ b/doc/manpages/object-server.conf.5 @@ -57,6 +57,8 @@ IP address the object server should bind to. The default is 0.0.0.0 which will m it bind to all available addresses. .IP "\fBbind_port\fR" TCP port the object server should bind to. The default is 6200. +.IP "\fBkeep_idle\fR" +Value to set for socket TCP_KEEPIDLE. The default value is 600. .IP "\fBbind_timeout\fR" Timeout to bind socket. The default is 30. .IP \fBbacklog\fR diff --git a/doc/manpages/proxy-server.conf.5 b/doc/manpages/proxy-server.conf.5 index f77a8118ed..14b838e96a 100644 --- a/doc/manpages/proxy-server.conf.5 +++ b/doc/manpages/proxy-server.conf.5 @@ -56,6 +56,8 @@ IP address the proxy server should bind to. The default is 0.0.0.0 which will ma it bind to all available addresses. .IP "\fBbind_port\fR" TCP port the proxy server should bind to. The default is 80. +.IP "\fBkeep_idle\fR" +Value to set for socket TCP_KEEPIDLE. The default value is 600. .IP "\fBbind_timeout\fR" Timeout to bind socket. The default is 30. .IP \fBbacklog\fR diff --git a/doc/source/deployment_guide.rst b/doc/source/deployment_guide.rst index 050954ccd9..8f24ab125f 100644 --- a/doc/source/deployment_guide.rst +++ b/doc/source/deployment_guide.rst @@ -437,6 +437,7 @@ mount_check true Whether or not check if the devices to the root device bind_ip 0.0.0.0 IP Address for server to bind to bind_port 6200 Port for server to bind to +keep_idle 600 Value to set for socket TCP_KEEPIDLE bind_timeout 30 Seconds to attempt bind before giving up backlog 4096 Maximum number of allowed pending connections @@ -1032,6 +1033,7 @@ mount_check true Whether or not check if the devices to the root device bind_ip 0.0.0.0 IP Address for server to bind to bind_port 6201 Port for server to bind to +keep_idle 600 Value to set for socket TCP_KEEPIDLE bind_timeout 30 Seconds to attempt bind before giving up backlog 4096 Maximum number of allowed pending connections @@ -1385,6 +1387,7 @@ mount_check true Whether or not check if the devices to the root device bind_ip 0.0.0.0 IP Address for server to bind to bind_port 6202 Port for server to bind to +keep_idle 600 Value to set for socket TCP_KEEPIDLE bind_timeout 30 Seconds to attempt bind before giving up backlog 4096 Maximum number of allowed pending connections @@ -1731,6 +1734,7 @@ Option Default Description bind_ip 0.0.0.0 IP Address for server to bind to bind_port 80 Port for server to bind to +keep_idle 600 Value to set for socket TCP_KEEPIDLE bind_timeout 30 Seconds to attempt bind before giving up backlog 4096 Maximum number of allowed pending diff --git a/etc/account-server.conf-sample b/etc/account-server.conf-sample index 47df56ecf3..dbe13a020a 100644 --- a/etc/account-server.conf-sample +++ b/etc/account-server.conf-sample @@ -1,6 +1,7 @@ [DEFAULT] # bind_ip = 0.0.0.0 bind_port = 6202 +# keep_idle = 600 # bind_timeout = 30 # backlog = 4096 # user = swift diff --git a/etc/container-server.conf-sample b/etc/container-server.conf-sample index 1c7fdd0b64..70b0bf4f2c 100644 --- a/etc/container-server.conf-sample +++ b/etc/container-server.conf-sample @@ -1,6 +1,7 @@ [DEFAULT] # bind_ip = 0.0.0.0 bind_port = 6201 +# keep_idle = 600 # bind_timeout = 30 # backlog = 4096 # user = swift diff --git a/etc/object-server.conf-sample b/etc/object-server.conf-sample index 9babc68c3f..6cbc79a098 100644 --- a/etc/object-server.conf-sample +++ b/etc/object-server.conf-sample @@ -1,6 +1,7 @@ [DEFAULT] # bind_ip = 0.0.0.0 bind_port = 6200 +# keep_idle = 600 # bind_timeout = 30 # backlog = 4096 # user = swift diff --git a/etc/proxy-server.conf-sample b/etc/proxy-server.conf-sample index 7ad971fc5d..97208daab7 100644 --- a/etc/proxy-server.conf-sample +++ b/etc/proxy-server.conf-sample @@ -1,6 +1,7 @@ [DEFAULT] # bind_ip = 0.0.0.0 bind_port = 8080 +# keep_idle = 600 # bind_timeout = 30 # backlog = 4096 # swift_dir = /etc/swift diff --git a/swift/common/wsgi.py b/swift/common/wsgi.py index fe250d5354..b912e1c75c 100644 --- a/swift/common/wsgi.py +++ b/swift/common/wsgi.py @@ -193,6 +193,14 @@ def get_socket(conf): bind_timeout = int(conf.get('bind_timeout', 30)) retry_until = time.time() + bind_timeout warn_ssl = False + + try: + keepidle = int(conf.get('keep_idle', 600)) + if keepidle <= 0 or keepidle >= 2 ** 15 - 1: + raise ValueError() + except (ValueError, KeyError, TypeError): + raise ConfigFileError() + while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(conf.get('backlog', 4096)), @@ -214,7 +222,7 @@ def get_socket(conf): sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if hasattr(socket, 'TCP_KEEPIDLE'): - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 600) + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, keepidle) if warn_ssl: ssl_warning_message = _('WARNING: SSL should only be enabled for ' 'testing purposes. Use external SSL ' diff --git a/test/unit/common/test_wsgi.py b/test/unit/common/test_wsgi.py index c64f01d549..2a840be5f0 100644 --- a/test/unit/common/test_wsgi.py +++ b/test/unit/common/test_wsgi.py @@ -404,6 +404,39 @@ class TestWSGI(unittest.TestCase): 'keyfile': '', } self.assertEqual(wsgi.ssl.wrap_socket_called, [expected_kwargs]) + + # test keep_idle value + keepIdle_value = 700 + conf['keep_idle'] = keepIdle_value + sock = wsgi.get_socket(conf) + # assert + if hasattr(socket, 'TCP_KEEPIDLE'): + expected_socket_opts[socket.IPPROTO_TCP][ + socket.TCP_KEEPIDLE] = keepIdle_value + self.assertEqual(sock.opts, expected_socket_opts) + + # test keep_idle for str -> int conversion + keepIdle_value = '800' + conf['keep_idle'] = keepIdle_value + sock = wsgi.get_socket(conf) + # assert + if hasattr(socket, 'TCP_KEEPIDLE'): + expected_socket_opts[socket.IPPROTO_TCP][ + socket.TCP_KEEPIDLE] = int(keepIdle_value) + self.assertEqual(sock.opts, expected_socket_opts) + + # test keep_idle for negative value + conf['keep_idle'] = -600 + self.assertRaises(wsgi.ConfigFileError, wsgi.get_socket, conf) + + # test keep_idle for upperbound value + conf['keep_idle'] = 2 ** 15 + self.assertRaises(wsgi.ConfigFileError, wsgi.get_socket, conf) + + # test keep_idle for Type mismatch + conf['keep_idle'] = 'foobar' + self.assertRaises(wsgi.ConfigFileError, wsgi.get_socket, conf) + finally: wsgi.listen = old_listen wsgi.ssl = old_ssl