-
Notifications
You must be signed in to change notification settings - Fork 12
Description
Bug Report
title: [Bug]: Socket attribute typo in BaseAgent.init causes silent broken-socket state
labels: bug
assignees: ondrej-lukas
Bug Description
In netsecgame/agents/base_agent.py, the __init__ method contains a critical typo in its socket error handler. When socket.connect() raises a socket.error, the code sets:
self.sock = None # <-- WRONG attribute nameinstead of:
self._socket = None # <-- correct attribute name used everywhere elseBecause self.sock is a completely different (newly created) attribute, self._socket is never reset to None. It continues to hold the socket object that failed to connect. Every subsequent method (communicate, make_step, register, request_game_reset, terminate_connection, __del__) guards its socket usage with if self._socket:, which will evaluate to True even on a broken connection, silently attempting I/O on an unusable socket.
Impact:
- An agent that failed to connect appears fully initialized — the caller has no way to detect the failure.
- All subsequent
communicate()/make_step()calls operate on a broken socket, causing unpredictable behavior: hangs waiting for data,BrokenPipeError, corrupted game state, or silent data loss — depending on OS-level socket behavior. - The intended fallback (
self._socket = None) to trigger safe-guards never fires. - The ghost
self.sockattribute pollutes the object namespace with a confusing, unusedNonevalue.
Affected file: netsecgame/agents/base_agent.py, line 25
Steps to Reproduce
- Instantiate
BaseAgent(or any subclass) with an unreachable host/port:agent = BaseAgent("192.0.2.1", 9999, AgentRole.Attacker) # port not open
- Observe that no exception is raised and the agent object is returned.
- Call
agent.make_step(some_action)oragent.register(). - The call blocks or raises an unexpected low-level socket error rather than failing cleanly.
Expected Behavior
When the socket fails to connect, self._socket should be set to None. All subsequent method calls should then short-circuit cleanly (the if self._socket: guards would correctly prevent any I/O). Callers should be able to detect the failed state, e.g., by checking agent.socket is None.
Fix
# netsecgame/agents/base_agent.py (__init__)
except socket.error as e:
self._logger.error(f"Socket error: {e}")
- self.sock = None # BUG: wrong attribute name
+ self._socket = None # FIX: matches the actual attributeVersion
See VERSION file in repository root.
Installation / Deployment Method
Running locally from source