From 2414b7a9688454fce8eb291b61f5f457e095bd59 Mon Sep 17 00:00:00 2001 From: Iskander Nafikov Date: Mon, 26 Jan 2026 00:27:48 +0800 Subject: [PATCH 1/6] Fix telnet keepalive options on macOS --- gns3server/utils/asyncio/telnet_server.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/gns3server/utils/asyncio/telnet_server.py b/gns3server/utils/asyncio/telnet_server.py index 50f7defc4..b13c405cd 100644 --- a/gns3server/utils/asyncio/telnet_server.py +++ b/gns3server/utils/asyncio/telnet_server.py @@ -186,15 +186,25 @@ class AsyncioTelnetServer: await writer.drain() async def run(self, network_reader, network_writer): - 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) # 60 sec keep alives, close tcp session after 4 missed # Will keep a firewall from aging out telnet console. - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60) - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 10) - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 4) + try: + # Keepalive options are platform dependent: Linux uses TCP_KEEPIDLE, + # while macOS exposes TCP_KEEPALIVE (in Python >= 3.10). + if hasattr(socket, "TCP_KEEPIDLE"): + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60) + elif hasattr(socket, "TCP_KEEPALIVE"): + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPALIVE, 60) + else: + raise AttributeError("module 'socket' has no attribute 'TCP_KEEPIDLE' or 'TCP_KEEPALIVE'") + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 10) + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 4) + except (AttributeError, OSError): + log.debug("Failed to tune TCP keepalive for telnet client; using OS defaults", exc_info=True) + #log.debug("New connection from {}".format(sock.getpeername())) # Keep track of connected clients From 833b5a9ea88eabfd6834ce98edbd7f72698c8792 Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 28 Jan 2026 16:52:30 +0800 Subject: [PATCH 2/6] Sync appliances --- gns3server/appliances/asterfusion-vAsterNOS-VPP.gns3a | 1 + 1 file changed, 1 insertion(+) diff --git a/gns3server/appliances/asterfusion-vAsterNOS-VPP.gns3a b/gns3server/appliances/asterfusion-vAsterNOS-VPP.gns3a index 3afa29fa5..d8f8ed557 100644 --- a/gns3server/appliances/asterfusion-vAsterNOS-VPP.gns3a +++ b/gns3server/appliances/asterfusion-vAsterNOS-VPP.gns3a @@ -9,6 +9,7 @@ "registry_version": 6, "status": "stable", "maintainer": "Asterfusion Product Team", + "maintainer_email": "bd@cloudswit.ch", "images": [ { "filename": "AsterNOS-VPP_V6.1-R0101P02_x86.img.gz", From 43d7e8a4376c61c6c394fdef6ac3efb3f18e961f Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 28 Jan 2026 17:00:07 +0800 Subject: [PATCH 3/6] Release v2.2.56.1 --- CHANGELOG | 6 ++++++ gns3server/crash_report.py | 2 +- gns3server/version.py | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 15c9573b3..63db2f004 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ # Change Log +## 2.2.56.1 28/01/2026 + +* Fix telnet keepalive options on macOS +* Upgrade dependencies +* Drop Python 3.8 support + ## 2.2.56 21/01/2026 * Set default location of udhcpc in "/etc/network/udhcpc". Fixes #2582 diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py index 93f503113..5898bbb7d 100644 --- a/gns3server/crash_report.py +++ b/gns3server/crash_report.py @@ -57,7 +57,7 @@ class CrashReport: Report crash to a third party service """ - DSN = "https://9b9fce29bf59d9a99c230240e1070600@o19455.ingest.us.sentry.io/38482" + DSN = "https://5bfcec70239c428d44aafef68f3eea79@o19455.ingest.us.sentry.io/38482" _instance = None def __init__(self): diff --git a/gns3server/version.py b/gns3server/version.py index 26e1d9395..b4b765e96 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,8 +23,8 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "2.2.57.dev1" -__version_info__ = (2, 2, 56, 99) +__version__ = "2.2.56.1" +__version_info__ = (2, 2, 56, 0) if "dev" in __version__: try: From ebe4fdc5b54992212ba581684edb72629117afa0 Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 28 Jan 2026 18:44:51 +0800 Subject: [PATCH 4/6] Development on 2.2.57.dev2 --- gns3server/version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gns3server/version.py b/gns3server/version.py index b4b765e96..c520f0086 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,8 +23,8 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "2.2.56.1" -__version_info__ = (2, 2, 56, 0) +__version__ = "2.2.57.dev2" +__version_info__ = (2, 2, 57, 99) if "dev" in __version__: try: From 44d4a426b505b173c4dfad54de891f2086eea7c5 Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 11 Feb 2026 16:46:21 +0800 Subject: [PATCH 5/6] Upgrade sentry-sdk and psutil dependencies --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 9c322ec53..8743cc7a0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,8 +3,8 @@ aiohttp>=3.13.3,<3.14 aiohttp-cors>=0.8.1,<0.9 aiofiles>=25.1.0,<26.0 Jinja2>=3.1.6,<3.2 -sentry-sdk>=2.50.0,<3 # optional dependency -psutil>=7.2.1 +sentry-sdk>=2.52.0,<3 # optional dependency +psutil>=7.2.2 async-timeout>=5.0.1,<5.1 # this library has effectively been upstreamed into Python 3.11+ distro>=1.9.0 py-cpuinfo>=9.0.0,<10.0 From dd87ccff4d6a080a856a6b873ea72c7fed7a9781 Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 11 Feb 2026 17:38:49 +0800 Subject: [PATCH 6/6] Upgrade pytest and jsonschema dependencies --- dev-requirements.txt | 3 ++- requirements.txt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index ece129f97..49eec2b3e 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,6 +1,7 @@ -rrequirements.txt -pytest==8.4.2 # version 8.4.2 is the last one supporting Python 3.9 +pytest==8.4.2; python_version == '3.9' # version 8.4.2 is the last one supporting Python 3.9 +pytest==9.0.2; python_version >= '3.10' flake8==7.3.0 pytest-timeout==2.4.0 pytest-aiohttp==1.1.0 diff --git a/requirements.txt b/requirements.txt index 8743cc7a0..4a55c7bfa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ -jsonschema>=4.25.1,<4.26 # version 4.25.1 is the last to support Python 3.9 +jsonschema==4.25.1; python_version == '3.9' # version 4.25.1 is the last to support Python 3.9 +jsonschema>=4.26.0,<4.27; python_version >= '3.10' aiohttp>=3.13.3,<3.14 aiohttp-cors>=0.8.1,<0.9 aiofiles>=25.1.0,<26.0