From b3a6b9173b354447d405cced071b264a0a808e03 Mon Sep 17 00:00:00 2001 From: grossmj Date: Sat, 31 Dec 2022 09:43:17 +0800 Subject: [PATCH] Fix reset console. Fixes #1619 --- gns3server/compute/base_node.py | 28 +++++++++++++++++++---- gns3server/compute/qemu/qemu_vm.py | 3 +-- gns3server/compute/vpcs/vpcs_vm.py | 3 +-- gns3server/utils/asyncio/telnet_server.py | 1 - 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py index cf171a32..65330bae 100644 --- a/gns3server/compute/base_node.py +++ b/gns3server/compute/base_node.py @@ -77,6 +77,8 @@ class BaseNode: self._allocate_aux = allocate_aux self._wrap_console = wrap_console self._wrapper_telnet_server = None + self._wrap_console_reader = None + self._wrap_console_writer = None self._internal_console_port = None self._custom_adapters = [] self._ubridge_require_privileged_access = False @@ -338,7 +340,6 @@ class BaseNode: if self._wrap_console: self._manager.port_manager.release_tcp_port(self._internal_console_port, self._project) self._internal_console_port = None - if self._aux: self._manager.port_manager.release_tcp_port(self._aux, self._project) self._aux = None @@ -376,15 +377,23 @@ class BaseNode: remaining_trial = 60 while True: try: - (reader, writer) = await asyncio.open_connection(host="127.0.0.1", port=self._internal_console_port) + (self._wrap_console_reader, self._wrap_console_writer) = await asyncio.open_connection( + host="127.0.0.1", + port=self._internal_console_port + ) break except (OSError, ConnectionRefusedError) as e: if remaining_trial <= 0: raise e await asyncio.sleep(0.1) remaining_trial -= 1 - await AsyncioTelnetServer.write_client_intro(writer, echo=True) - server = AsyncioTelnetServer(reader=reader, writer=writer, binary=True, echo=True) + await AsyncioTelnetServer.write_client_intro(self._wrap_console_writer, echo=True) + server = AsyncioTelnetServer( + reader=self._wrap_console_reader, + writer=self._wrap_console_writer, + binary=True, + echo=True + ) # warning: this will raise OSError exception if there is a problem... self._wrapper_telnet_server = await asyncio.start_server( server.run, @@ -398,8 +407,19 @@ class BaseNode: """ if self._wrapper_telnet_server: + self._wrap_console_writer.close() + await self._wrap_console_writer.wait_closed() self._wrapper_telnet_server.close() await self._wrapper_telnet_server.wait_closed() + self._wrapper_telnet_server = None + + async def reset_wrap_console(self): + """ + Reset the wrap console (restarts the Telnet proxy) + """ + + await self.stop_wrap_console() + await self.start_wrap_console() async def start_websocket_console(self, request): """ diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index 22c75159..dec57e4a 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -1572,9 +1572,8 @@ class QemuVM(BaseNode): Reset console """ - await self.stop_wrap_console() if self.is_running(): - await self.start_wrap_console() + await self.reset_wrap_console() def command(self): """ diff --git a/gns3server/compute/vpcs/vpcs_vm.py b/gns3server/compute/vpcs/vpcs_vm.py index 9b88f94f..6fa29bf2 100644 --- a/gns3server/compute/vpcs/vpcs_vm.py +++ b/gns3server/compute/vpcs/vpcs_vm.py @@ -349,9 +349,8 @@ class VPCSVM(BaseNode): Reset console """ - await self.stop_wrap_console() if self.is_running(): - await self.start_wrap_console() + await self.reset_wrap_console() @BaseNode.console_type.setter def console_type(self, new_console_type): diff --git a/gns3server/utils/asyncio/telnet_server.py b/gns3server/utils/asyncio/telnet_server.py index 373d324f..e6f85199 100644 --- a/gns3server/utils/asyncio/telnet_server.py +++ b/gns3server/utils/asyncio/telnet_server.py @@ -189,7 +189,6 @@ class AsyncioTelnetServer: sock = network_writer.get_extra_info("socket") sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #log.debug("New connection from {}".format(sock.getpeername())) # Keep track of connected clients