vpn: dump wg transfer counters + routes on handshake timeout for diagnosis
This commit is contained in:
+21
-3
@@ -220,7 +220,7 @@ def down(cfg) -> None:
|
|||||||
_sudo(["rm", "-rf", f"/etc/netns/{ns}"])
|
_sudo(["rm", "-rf", f"/etc/netns/{ns}"])
|
||||||
|
|
||||||
|
|
||||||
def wait_for_handshake(cfg, timeout: float = 15.0) -> bool:
|
def wait_for_handshake(cfg, timeout: float = 20.0) -> bool:
|
||||||
import time
|
import time
|
||||||
deadline = time.monotonic() + timeout
|
deadline = time.monotonic() + timeout
|
||||||
while time.monotonic() < deadline:
|
while time.monotonic() < deadline:
|
||||||
@@ -230,6 +230,20 @@ def wait_for_handshake(cfg, timeout: float = 15.0) -> bool:
|
|||||||
return has_handshake(cfg)
|
return has_handshake(cfg)
|
||||||
|
|
||||||
|
|
||||||
|
def _diagnose(cfg) -> str:
|
||||||
|
"""Collect tunnel state to explain why a handshake isn't happening."""
|
||||||
|
ns, iface = netns_name(cfg), iface_name(cfg)
|
||||||
|
parts = []
|
||||||
|
for title, args in (
|
||||||
|
("wg", ["ip", "netns", "exec", ns, "wg", "show", iface]),
|
||||||
|
("routes", ["ip", "netns", "exec", ns, "ip", "route", "show", "default"]),
|
||||||
|
("rules", ["ip", "netns", "exec", ns, "ip", "rule", "show"]),
|
||||||
|
):
|
||||||
|
rc, out = _sudo_out(args)
|
||||||
|
parts.append(f"--- {title} ---\n{out or '(none)'}")
|
||||||
|
return "\n".join(parts)
|
||||||
|
|
||||||
|
|
||||||
def ensure_up(cfg) -> None:
|
def ensure_up(cfg) -> None:
|
||||||
if has_handshake(cfg):
|
if has_handshake(cfg):
|
||||||
return
|
return
|
||||||
@@ -237,11 +251,15 @@ def ensure_up(cfg) -> None:
|
|||||||
down(cfg) # converge from any stale half-configured state
|
down(cfg) # converge from any stale half-configured state
|
||||||
up(cfg)
|
up(cfg)
|
||||||
if not wait_for_handshake(cfg):
|
if not wait_for_handshake(cfg):
|
||||||
|
log.error("no WireGuard handshake within timeout — tunnel state:\n%s",
|
||||||
|
_diagnose(cfg))
|
||||||
down(cfg)
|
down(cfg)
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"WireGuard tunnel came up but no handshake was established — "
|
"WireGuard tunnel came up but no handshake was established — "
|
||||||
"check the endpoint/reachability and that the tunnel is actually "
|
"see tunnel state above. If 'transfer' shows sent bytes but 0 "
|
||||||
"active. Refusing to download over a dead tunnel."
|
"received, the endpoint is unreachable (try a different Mullvad "
|
||||||
|
"server); if 0 sent, the namespace has no route out. "
|
||||||
|
"Refusing to download over a dead tunnel."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user