From 1a723f224d129a6aba3671c4f88ce5309ff7297d Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 28 Feb 2019 19:18:12 +0300 Subject: [PATCH] Move TLS server handshake down to connection thread When TLS handshake is performed while in `accept()` call, main thread might blocked up to network timeout effectively locking out other clients from being able to establish connection with PyKMIP server. Easy way to reproduce the problem: 1. Start PyKMIP server 2. Establish TCP connection with `nc -v 127.0.0.1 5696` 3. Attempt to connect (concurrently): `openssl s_client -host 127.0.0.1 -port 5696` Without the fix, `openssl` would be blocked (won't even do initial TLS handshake) until `nc` connection times out. --- kmip/services/server/server.py | 2 +- kmip/services/server/session.py | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/kmip/services/server/server.py b/kmip/services/server/server.py index eaa33fd..534ab61 100644 --- a/kmip/services/server/server.py +++ b/kmip/services/server/server.py @@ -295,7 +295,7 @@ class KmipServer(object): cert_reqs=ssl.CERT_REQUIRED, ssl_version=self.auth_suite.protocol, ca_certs=self.config.settings.get('ca_path'), - do_handshake_on_connect=True, + do_handshake_on_connect=False, suppress_ragged_eofs=True, ciphers=self.auth_suite.ciphers ) diff --git a/kmip/services/server/session.py b/kmip/services/server/session.py index a2d9df0..96cd839 100644 --- a/kmip/services/server/session.py +++ b/kmip/services/server/session.py @@ -97,14 +97,20 @@ class KmipSession(threading.Thread): """ self._logger.info("Starting session: {0}".format(self.name)) - while True: - try: - self._handle_message_loop() - except exceptions.ConnectionClosed as e: - break - except Exception as e: - self._logger.info("Failure handling message loop") - self._logger.exception(e) + try: + self._connection.do_handshake() + except Exception as e: + self._logger.info("Failure running TLS handshake") + self._logger.exception(e) + else: + while True: + try: + self._handle_message_loop() + except exceptions.ConnectionClosed as e: + break + except Exception as e: + self._logger.info("Failure handling message loop") + self._logger.exception(e) self._connection.shutdown(socket.SHUT_RDWR) self._connection.close()