Saggi Mizrahi has uploaded a new change for review. Change subject: protocol_acceptor: Make SSL handshake asynchronous ......................................................................
protocol_acceptor: Make SSL handshake asynchronous Change-Id: Ia8808633344389297fe026cd2219aa513f6f1dff Signed-off-by: Saggi Mizrahi <smizr...@redhat.com> --- M lib/vdsm/sslutils.py M vdsm/protocoldetector.py 2 files changed, 53 insertions(+), 19 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/57/33657/1 diff --git a/lib/vdsm/sslutils.py b/lib/vdsm/sslutils.py index 74d2bdf..505db0e 100644 --- a/lib/vdsm/sslutils.py +++ b/lib/vdsm/sslutils.py @@ -169,7 +169,7 @@ def wrapSocket(self, sock): context = self.context - return SSLSocket(SSL.Connection(context, sock=sock), self) + return SSLSocket(SSL.Connection(context, sock=sock)) class VerifyingHTTPSConnection(httplib.HTTPSConnection): diff --git a/vdsm/protocoldetector.py b/vdsm/protocoldetector.py index 7e15f9c..7d428bf 100644 --- a/vdsm/protocoldetector.py +++ b/vdsm/protocoldetector.py @@ -27,9 +27,15 @@ from M2Crypto import SSL -from vdsm.sslutils import SSLServerSocket from vdsm.utils import traceback from vdsm import utils + + +def _is_handshaking(sock): + if not hasattr(sock, "is_handshaking"): + return False + + return sock.is_handshaking class MultiProtocolAcceptor: @@ -60,8 +66,11 @@ """ log = logging.getLogger("vds.MultiProtocolAcceptor") - READ_ONLY_MASK = (select.POLLIN | select.POLLPRI | select.POLLHUP - | select.POLLERR) + READ_ONLY_MASK = (select.POLLIN | select.POLLPRI | select.POLLHUP | + select.POLLERR) + + READ_WRITE_MASK = (select.POLLIN | select.POLLPRI | + select.POLLOUT | select.POLLHUP | select.POLLERR) CLEANUP_INTERVAL = 30.0 def __init__(self, host, port, sslctx=None): @@ -113,8 +122,8 @@ self._accept_connection() else: self._handle_connection_read(fd) - else: - pass + if event & (select.POLLOUT): + self._handle_connection_write(fd) now = time.time() if now > self._next_cleanup: @@ -173,12 +182,21 @@ raise def _accept_connection(self): - try: - client_socket, _ = self._socket.accept() - except SSL.SSLError as e: - self.log.warning("Unable to accept connection due to %s", e) - else: - self._add_connection(client_socket) + client_socket, address = self._socket.accept() + if self._sslctx: + client_socket = self._sslctx.wrapSocket(client_socket) + client_socket.address = address + try: + client_socket.setup_ssl() + client_socket.set_accept_state() + except SSL.SSLError as e: + self.log.warning("Error setting up ssl: %s", e) + client_socket.close() + return + + client_socket.is_handshaking = True + + self._add_connection(client_socket) def _add_connection(self, socket): host, port = socket.getpeername() @@ -186,7 +204,10 @@ socket.setblocking(0) self._pending_connections[socket.fileno()] = (time.time(), socket) - self._poller.register(socket, self.READ_ONLY_MASK) + if _is_handshaking(socket): + self._poller.register(socket, self.READ_WRITE_MASK) + else: + self._poller.register(socket, self.READ_ONLY_MASK) def _remove_connection(self, socket): self._poller.unregister(socket) @@ -195,8 +216,27 @@ host, port = socket.getpeername() self.log.debug("Connection removed from %s:%d", host, port) + def _process_handshake(self, socket): + try: + socket.is_handshaking = (socket.accept_ssl() == 0) + except Exception as e: + self.log.debug("Error during handshake: %s", e) + socket.close() + else: + if not socket.is_hanshaking: + self._poller.modify(socket, self.READ_ONLY_MASK) + + def _handle_connection_write(self, fd): + _, client_socket = self._pending_connections[fd] + if _is_handshaking(client_socket): + self._process_handshake(client_socket) + def _handle_connection_read(self, fd): _, client_socket = self._pending_connections[fd] + if _is_handshaking(client_socket): + self._process_handshake(client_socket) + return + try: data = client_socket.recv(self._required_size, socket.MSG_PEEK) except socket.error as e: @@ -233,12 +273,6 @@ server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind(addr[0][4]) server_socket.listen(5) - - if self._sslctx: - server_socket = SSLServerSocket(raw=server_socket, - certfile=self._sslctx.cert_file, - keyfile=self._sslctx.key_file, - ca_certs=self._sslctx.ca_cert) server_socket.setblocking(0) return server_socket -- To view, visit http://gerrit.ovirt.org/33657 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia8808633344389297fe026cd2219aa513f6f1dff Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Saggi Mizrahi <smizr...@redhat.com> _______________________________________________ vdsm-patches mailing list vdsm-patches@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches