From 763ef241080bcb7f9c3be800989d5b0a4f2043f5 Mon Sep 17 00:00:00 2001 From: John Fleming Date: Fri, 2 Feb 2024 22:09:31 -0500 Subject: [PATCH] Address the telnet console bug. Add wait_for for drain() call. If we're stuck on drain then the buffer isn't getting emptied. 5 seconds after drain() blocks, exception will be thrown and client will be removed from connection table and will no longer be a problem. --- gns3server/utils/asyncio/telnet_server.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/gns3server/utils/asyncio/telnet_server.py b/gns3server/utils/asyncio/telnet_server.py index b8829847..50f7defc 100644 --- a/gns3server/utils/asyncio/telnet_server.py +++ b/gns3server/utils/asyncio/telnet_server.py @@ -297,9 +297,17 @@ class AsyncioTelnetServer: reader_read = await self._get_reader(network_reader) # Replicate the output on all clients - for connection in self._connections.values(): - connection.writer.write(data) - await connection.writer.drain() + for connection_key in list(self._connections.keys()): + client_info = connection_key.get_extra_info("socket").getpeername() + connection = self._connections[connection_key] + + try: + connection.writer.write(data) + await asyncio.wait_for(connection.writer.drain(), timeout=10) + except: + log.debug(f"Timeout while sending data to client: {client_info}, closing and removing from connection table.") + connection.close() + del self._connections[connection_key] async def _read(self, cmd, buffer, location, reader): """ Reads next op from the buffer or reader"""