diff --git a/kmip/services/server/server.py b/kmip/services/server/server.py index 6c0622e..eaa33fd 100644 --- a/kmip/services/server/server.py +++ b/kmip/services/server/server.py @@ -267,6 +267,7 @@ class KmipServer(object): self._logger.info("Starting server socket handler.") # Create a TCP stream socket and configure it for immediate reuse. + socket.setdefaulttimeout(10) self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -407,6 +408,11 @@ class KmipServer(object): while self._is_serving: try: connection, address = self._socket.accept() + except socket.timeout: + # Setting the default socket timeout to break hung connections + # will cause accept to periodically raise socket.timeout. This + # is expected behavior, so ignore it and retry accept. + pass except socket.error as e: self._logger.warning( "Error detected while establishing new connection." diff --git a/kmip/tests/unit/services/server/test_server.py b/kmip/tests/unit/services/server/test_server.py index d450e09..e228747 100644 --- a/kmip/tests/unit/services/server/test_server.py +++ b/kmip/tests/unit/services/server/test_server.py @@ -485,7 +485,11 @@ class TestKmipServer(testtools.TestCase): # Test the expected behavior for a normal server/interrupt sequence s._socket.accept = mock.MagicMock( - side_effect=[('connection', 'address'), expected_error] + side_effect=[ + ('connection', 'address'), + socket.timeout, + expected_error + ] ) s.serve()