Add detailed bug report documenting a race condition in the telnet server's broadcast logic. The bug occurs when a client disconnects while the server is iterating through connections to broadcast data, causing an uncaught OSError from getpeername() call.
Key details included:
- Error logs showing OSError: [Errno 107] Transport endpoint is not connected
- Architecture diagram illustrating the telnet proxy server setup
- Root cause analysis showing the race condition timeline
- Problematic code location in telnet_server.py line 305
- Exception hierarchy explanation showing why OSError isn't caught
- Impact assessment and proposed solutions
This documentation will help track and resolve the issue where client disconnections during broadcast cause unhandled exceptions.
- Catch OSError alongside ConnectionError in connection processing to handle more network errors
- Move client_info retrieval inside try block to prevent AttributeError on failed connections
- Replace bare except with specific exceptions (OSError, ConnectionError, asyncio.TimeoutError)
- Improve error logging to include specific exception details and client information
Fixes two critical issues in telnet server when clients rapidly
connect/disconnect during broadcast operations:
1. **OSError [Errno 107]**: Transport endpoint not connected
- Root cause: getpeername() called outside try block
- Fix: Move getpeername() inside try block and catch OSError
- Expand exception handling to include OSError and TimeoutError
2. **KeyError**: Double deletion from connections dictionary
- Root cause: Connection deleted in broadcast loop, then deleted
again in top-level exception handler
- Fix: Use dict.pop(key, None) instead of del dict[key]
**Changes**:
- Line 216: Add OSError to top-level exception handler
- Line 227-228: Use pop() to avoid KeyError on double deletion
- Line 305-316: Move getpeername() inside try block, expand
exception types, use pop() for safe deletion
**Impact**:
- Prevents unhandled exceptions from propagating to asyncio event loop
- Ensures proper resource cleanup even with race conditions
- No resource leaks or zombie connections
- Long-lived clients unaffected by rapid client disconnects
**Test Script**:
- Added stress test script to reproduce the issue
- Supports IOU-L3, VPCS, and generic device types
- Rapid clients send broadcast-triggering commands (show/run/OSPF)
**Related**: Fixes bug documented in docs/bugs/telnet-server-connection-race-condition.md
Fix the path mismatch between /acl/endpoints API and actual routes:
- Users: /users/{id} → /access/users/{id}
- Groups: /groups/{id} → /access/groups/{id}
- Roles: /roles/{id} → /access/roles/{id}
This fixes the error where creating ACE entries fails with:
"Path '/groups/{id}' doesn't match any existing endpoint"
The actual routes are registered under /access/ prefix, but the
endpoints API was returning paths without the prefix.
Co-Authored-By: Yue Guobin <yueguobin@outlook.com>
Fixed IOU node suspend API to return proper HTTP 405 Method Not Allowed
error instead of misleading 204 No Content response.
Changes:
- Added HTTPException import to iou_nodes.py
- Fixed suspend_iou_node route from /stop to /suspend (bug fix)
- Changed response from 204 No Content to 405 Method Not Allowed
- Added clear error message: "Suspend is not supported for IOU nodes"
This fix ensures clients receive explicit feedback when attempting to
suspend IOU nodes, which do not support suspend functionality.
Related issue: IOU nodes previously returned 404 when suspend was called
due to incorrect route registration.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
When a Docker container with the same name already exists (e.g., from a
previous crashed GNS3 session), Docker returns a 409 Conflict error
when trying to create a new container with that name. This causes the
project open operation to fail.
This fix adds automatic cleanup of stale containers when encountering
a name conflict:
- Added DockerHttp409Error exception class
- Updated http_query to detect 409 status codes
- Modified create() to remove conflicting containers and retry
Fixes the issue where opening a project fails with:
"Docker has returned an error: 409 Conflict. The container name
'/GNS3.xxx' is already in use by container 'xxx'"