def start(self): self.server_addr, self.server_port = (self._get_original_dest( self.client_socket)) # If the client tries to connect to the MiTM through the MiTM it will # lead to a loop where we make a connection to ourselves which is then # MiTM'd and then tries to connect to the MiTM and so on until we run # out of fd's and the whole thing comes crashing down, try and avoid # that. if self.server.is_remote_mitm_server(self.server_addr, self.server_port): self.logger.warning( "Client %s attempting to connect to MiTM directly, aborting connection." % (self.client_addr)) close_quietly(self.client_socket) return False self.handler.on_select() for handler in self.data_handlers: handler.on_select() try: self._start_server_connect_nonblocking() except socket.error: return False return True
def _on_server_socket_select(self, fd): client_socket, client_address = None, (None, None) try: (client_socket, client_address) = (fd.accept()) self.setup_connection(client_socket) except socket.error as e: self.logger.error("Socket error in connection startup from %s" % client_address[0]) self.logger.exception(e) util.close_quietly(client_socket)
def _on_server_socket_select(self, fd): client_socket, client_address = None, (None, None) try: (client_socket, client_address) = ( fd.accept()) self.setup_connection(client_socket) except socket.error as e: self.logger.error( "Socket error in connection startup from %s" % client_address[0]) self.logger.exception(e) util.close_quietly(client_socket)
def serve(self): last_reap = time.time() # set up the listening sockets local_server_sockets = self._create_server_sockets() for sock in local_server_sockets: self.connections[sock] = None while not self.kill: r, _, _ = select.select(self.connections.keys(), [], [], 10) for fd in r: if fd == self.kill_fd: return if fd in local_server_sockets: client_socket, client_address = None, (None, None) try: (client_socket, client_address) = (fd.accept()) self.setup_connection(client_socket) except socket.error as e: self.logger.error( "Socket error in connection startup from %s" % client_address[0]) self.logger.exception(e) util.close_quietly(client_socket) continue try: conn = self.connections[fd] except KeyError: # fd could have already been removed if the other end of the socket closed # and was handled before fd. fd has already been handled so # move along continue try: cont = conn.bridge(fd) if not cont: self.remove(conn) except Exception as e: self.logger.exception(e) self.remove(conn) # If nothing is happening and we haven't reaped in a while reap now = time.time() if (len(r) == 0 and now - last_reap > 600) or now - last_reap > 3600: for conn in set(self.connections.values()): if not isinstance(conn, self.connection_class): continue if now - conn.last_used > 3600: self.remove(conn)
def close(self, handler_initiated=True): """Close the connection. Does nothing if the connection is already closed. handler_initiated: If a handler is requesting a close versus the connection being closed by one of the endpoints. """ if self.closed: return self.closed = True close_quietly(self.server_socket) close_quietly(self.client_socket) self.handler.on_close(handler_initiated) for handler in self.data_handlers: handler.on_close(handler_initiated)
def start(self): self.server_addr, self.server_port = ( self._get_original_dest(self.client_socket)) # If the client tries to connect to the MiTM through the MiTM it will # lead to a loop where we make a connection to ourselves which is then # MiTM'd and then tries to connect to the MiTM and so on until we run # out of fd's and the whole thing comes crashing down, try and avoid # that. if self.server.is_remote_mitm_server(self.server_addr, self.server_port): self.logger.warning( "Client %s attempting to connect to MiTM directly, aborting connection." % (self.client_addr)) close_quietly(self.client_socket) return False self.handler.on_select() for handler in self.data_handlers: handler.on_select() try: self._start_server_connect_nonblocking() except socket.error: return False return True
def shutdown(self): for sock in self.read_fds | self.write_fds | self.ex_fds: util.close_quietly(sock)
def close(self): """Close the connection to the client. This also notifies all pending queries that their request has failed.""" close_quietly(self.socket) for callback in self.queries.values(): callback.fn(False)