fix: revive the connection-timeout watchdog (== for =) #109

Merged
mysticalsoap merged 1 commit from fix/conn-timeout-watchdog into trunk 2026-08-20 21:33:52 -04:00
Owner

Problem

The three starting_timer handlers held self.tunnel_active == 0 — comparisons where assignments were meant — so arming the 15s watchdog never marked the tunnel pending. timeout() only kills a tunnel whose flag is still 0 when the timer fires; after a session's first successful connection the flags stayed 1, and every later hung connect/reconnect attempt just spun the cursor forever (#103). start_timer additionally reset the bypass flag whatever tunnel was starting.

Fix

  • = for == in all three handlers; the stray bypass-flag line in start_timer is deleted — each handler resets exactly its own flag.
  • kill_hop gains its missing self: with the watchdog able to reach its kill path, getattr(self, "kill_hop")() on a hung hop attempt raised TypeError inside a Qt slot, which aborts the GUI.

Behavior change, bounded: the 15-second deadline on connection attempts now actually enforces — a hung attempt gets torn down via the existing kill* paths instead of spinning. The boundaries checked: starting_timer is emitted once per openvpn spawn (tunnel.py:625), never on management reconnect events, so ping-restart recovery is never killed; dispatch_status stops the timer on any arriving status; established tunnels set their flag to 1 and are spared; the #102 tunnel_terminated guard is unaffected (the connect path already had tunnel_active = 0 via kill() before arming).

Verification

Ten new tests: arming resets exactly its own flag and starts the 15s timer (×3 roles), armed-then-fired kills the pending tunnel (×3), an established tunnel is spared (×3), and kill_hop is callable as a method. Full suite: 197 passed.

Closes #103

🤖 Generated with Claude Code

**Problem** The three `starting_timer` handlers held `self.tunnel_active == 0` — comparisons where assignments were meant — so arming the 15s watchdog never marked the tunnel pending. `timeout()` only kills a tunnel whose flag is still 0 when the timer fires; after a session's first successful connection the flags stayed 1, and every later hung connect/reconnect attempt just spun the cursor forever (#103). `start_timer` additionally reset the *bypass* flag whatever tunnel was starting. **Fix** - `=` for `==` in all three handlers; the stray bypass-flag line in `start_timer` is deleted — each handler resets exactly its own flag. - `kill_hop` gains its missing `self`: with the watchdog able to reach its kill path, `getattr(self, "kill_hop")()` on a hung hop attempt raised TypeError inside a Qt slot, which aborts the GUI. **Behavior change, bounded**: the 15-second deadline on connection attempts now actually enforces — a hung attempt gets torn down via the existing `kill*` paths instead of spinning. The boundaries checked: `starting_timer` is emitted once per openvpn spawn (tunnel.py:625), never on management reconnect events, so ping-restart recovery is never killed; `dispatch_status` stops the timer on any arriving status; established tunnels set their flag to 1 and are spared; the #102 `tunnel_terminated` guard is unaffected (the connect path already had `tunnel_active = 0` via `kill()` before arming). **Verification** Ten new tests: arming resets exactly its own flag and starts the 15s timer (×3 roles), armed-then-fired kills the pending tunnel (×3), an established tunnel is spared (×3), and `kill_hop` is callable as a method. Full suite: 197 passed. Closes #103 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix: revive the connection-timeout watchdog (== for =)
All checks were successful
ci / test (pull_request) Successful in 37s
ci / test (push) Successful in 50s
bd621377a7
starting_timer, starting_timer_hop and starting_timer_bypass held bare
comparisons where assignments were meant, so arming the watchdog never
marked the tunnel pending: after the first tunnel of a session went
active, its flag stayed 1 and timeout() -- which only kills a tunnel
whose flag is still 0 when the 15s timer fires -- never fired again. A
hung connect or reconnect attempt just spun the cursor forever.
start_timer also reset the bypass flag whatever tunnel was starting;
that line is gone, each handler resets exactly its own flag.

With the watchdog able to actually reach its kill path, kill_hop's
missing self argument became reachable too: getattr(self, "kill_hop")()
raised TypeError inside a Qt slot, which aborts the gui.

The watchdog only guards launch: starting_timer is emitted once per
openvpn spawn, never on management reconnect events, so ping-restart
recovery cannot be killed by it, and dispatch_status stops the timer on
any arriving status.

Closes #103

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mysticalsoap deleted branch fix/conn-timeout-watchdog 2026-08-20 21:33:53 -04:00
Sign in to join this conversation.
No description provided.