From 7d8dca1ffd6e713618999dcee39e729b99e3a967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Sun, 6 Sep 2026 21:09:04 +0300 Subject: [PATCH] Fix GSMTAP capture restart: recreate UDP socket on start after stop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GsmtapListener.stop() closed the UDP socket permanently, but start() only set _running=True without recreating it. Second capture session would silently spin on the dead socket (OSError → None → continue). - Add _closed flag to GsmtapReceiver, set in close() - Store bind_port in GsmtapListener for socket recreation - start() recreates GsmtapReceiver only if previous one was closed - Uses getattr for backward compat with test fakes --- simtrace2_pysniff/gsmtap.py | 2 ++ simtrace2_pysniff/server/capture.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/simtrace2_pysniff/gsmtap.py b/simtrace2_pysniff/gsmtap.py index 75e5abd..6f9e7a8 100644 --- a/simtrace2_pysniff/gsmtap.py +++ b/simtrace2_pysniff/gsmtap.py @@ -79,6 +79,7 @@ class GsmtapReceiver: self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self._sock.bind((bind_ip, bind_port)) self._sock.settimeout(1.0) + self._closed = False def read_packet(self): """Block until a GSMTAP-SIM packet arrives. @@ -109,3 +110,4 @@ class GsmtapReceiver: def close(self): self._sock.close() + self._closed = True diff --git a/simtrace2_pysniff/server/capture.py b/simtrace2_pysniff/server/capture.py index 0369904..6d0b5ae 100644 --- a/simtrace2_pysniff/server/capture.py +++ b/simtrace2_pysniff/server/capture.py @@ -34,11 +34,14 @@ def gsmtap_msg_type(sub_type): class GsmtapListener: def __init__(self, bind_port=4729): + self._bind_port = bind_port self._receiver = GsmtapReceiver(bind_port=bind_port) self._running = False self._dropped = 0 def start(self): + if getattr(self._receiver, '_closed', False): + self._receiver = GsmtapReceiver(bind_port=self._bind_port) self._running = True self._dropped = 0