[PR #3282] fix: reconnect on Linux only after network is back from suspend #3159

Open
opened 2026-10-14 21:07:55 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/amnezia-vpn/amnezia-client/pull/3282
Author: @homka122
Created: 10/14/2026
Status: 🔄 Open

Base: dev ← Head: fix/linux-reconnect-after-resume


📝 Commits (1)

  • a432dd1 fix: reconnect on Linux only after network is back from suspend

📊 Changes

1 file changed (+5 additions, -3 deletions)

View changed files

📝 client/platforms/linux/linuxnetworkwatcherworker.cpp (+5 -3)

📄 Description

Problem

On Linux, AmneziaWG has no connectivity after resuming from suspend until the user reconnects by hand.

LinuxNetworkWatcherWorker::NMStateChanged() emits wakeup when NetworkManager goes to NM_STATE_ASLEEP / NM_STATE_DISABLED, and wakeup is connected to VpnConnection::reconnectToVpn(). So the reconnect starts while the machine is going to sleep, and the new activate reaches the daemon right after resume, when Wi-Fi is not associated yet and there is no default gateway:

13:18:47 NetworkManager: sleep requested
13:18:47 LinuxNetworkWatcherWorker : NMStateChanged 10
13:18:47 Reconnect triggered. Reconnecting to the server
13:18:48 kernel: PM: suspend entry (deep)
13:18:55 kernel: PM: suspend exit
13:18:55 NetworkManager state is now DISCONNECTED
13:18:55 Command received: activate
13:18:57 LinuxRouteMonitor : Adding exclusion route for <endpoint>/32
13:18:57 getGatewayAndIface: no gateway found
13:18:57 LinuxRouteMonitor : No default gateway available, skipping exclusion route
13:18:57 WireguardGo : ERROR: (amn0) peer(...) - Failed to send handshake initiation
13:18:57 LinuxRouteMonitor : Adding route to 0.0.0.0/1
13:18:57 LinuxRouteMonitor : Adding route to 128.0.0.0/1
13:18:58 NetworkManager state is now CONNECTED_GLOBAL
13:18:58 LinuxNetworkWatcherWorker : NMStateChanged 70
13:18:58 "Reconnect triggered on Reconnecting during inappropriate state: %2; ignoring slot"

The tunnel is up with 0.0.0.0/1 + 128.0.0.0/1 via amn0 but without the /32 exclusion route to the endpoint, so the handshake packets are routed into the tunnel itself, and the kill switch blocks everything else. When the uplink does come back (CONNECTED_GLOBAL), networkChanged is ignored because the connection is still in Reconnecting, so nothing repairs the state.

Fix

Do not reconnect on ASLEEP / DISABLED; reconnect only on CONNECTED_GLOBAL. After resume the connection is still Connected, so the networkChanged at CONNECTED_GLOBAL performs a single reconnect when the default gateway exists, and the exclusion routes are installed normally. wakeup is only consumed by reconnectToVpn() on Linux, so nothing else is affected. The kill switch keeps allowDHCP / allowLAN while the old tunnel is still configured, so NetworkManager can bring the uplink back up after resume.

This is the network-watcher part of #2684, without the unrelated firewall / cgroup / routing-table changes (that PR no longer applies to dev).

Related: #3037, #2997 (same symptom, exclusion route skipped because there was no gateway at connect time, but triggered by reboot or server switching, which this PR does not address).

Testing

Reproduced on Fedora 44 (kernel 7.2, NetworkManager, Wi-Fi, S3 deep sleep) with AmneziaVPN 5.0.1.5 + AmneziaWG; the log above is from that machine. The fix has not been built locally (no Qt 6 toolchain); relying on CI for the build.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/amnezia-vpn/amnezia-client/pull/3282 **Author:** [@homka122](https://github.com/homka122) **Created:** 10/14/2026 **Status:** 🔄 Open **Base:** `dev` ← **Head:** `fix/linux-reconnect-after-resume` --- ### 📝 Commits (1) - [`a432dd1`](https://github.com/amnezia-vpn/amnezia-client/commit/a432dd1cebbf27fbc5d8b3bc93927980a1af5b07) fix: reconnect on Linux only after network is back from suspend ### 📊 Changes **1 file changed** (+5 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `client/platforms/linux/linuxnetworkwatcherworker.cpp` (+5 -3) </details> ### 📄 Description ## Problem On Linux, AmneziaWG has no connectivity after resuming from suspend until the user reconnects by hand. `LinuxNetworkWatcherWorker::NMStateChanged()` emits `wakeup` when NetworkManager goes to `NM_STATE_ASLEEP` / `NM_STATE_DISABLED`, and `wakeup` is connected to `VpnConnection::reconnectToVpn()`. So the reconnect starts while the machine is **going to sleep**, and the new `activate` reaches the daemon right after resume, when Wi-Fi is not associated yet and there is no default gateway: ``` 13:18:47 NetworkManager: sleep requested 13:18:47 LinuxNetworkWatcherWorker : NMStateChanged 10 13:18:47 Reconnect triggered. Reconnecting to the server 13:18:48 kernel: PM: suspend entry (deep) 13:18:55 kernel: PM: suspend exit 13:18:55 NetworkManager state is now DISCONNECTED 13:18:55 Command received: activate 13:18:57 LinuxRouteMonitor : Adding exclusion route for <endpoint>/32 13:18:57 getGatewayAndIface: no gateway found 13:18:57 LinuxRouteMonitor : No default gateway available, skipping exclusion route 13:18:57 WireguardGo : ERROR: (amn0) peer(...) - Failed to send handshake initiation 13:18:57 LinuxRouteMonitor : Adding route to 0.0.0.0/1 13:18:57 LinuxRouteMonitor : Adding route to 128.0.0.0/1 13:18:58 NetworkManager state is now CONNECTED_GLOBAL 13:18:58 LinuxNetworkWatcherWorker : NMStateChanged 70 13:18:58 "Reconnect triggered on Reconnecting during inappropriate state: %2; ignoring slot" ``` The tunnel is up with `0.0.0.0/1` + `128.0.0.0/1` via `amn0` but without the `/32` exclusion route to the endpoint, so the handshake packets are routed into the tunnel itself, and the kill switch blocks everything else. When the uplink does come back (`CONNECTED_GLOBAL`), `networkChanged` is ignored because the connection is still in `Reconnecting`, so nothing repairs the state. ## Fix Do not reconnect on `ASLEEP` / `DISABLED`; reconnect only on `CONNECTED_GLOBAL`. After resume the connection is still `Connected`, so the `networkChanged` at `CONNECTED_GLOBAL` performs a single reconnect when the default gateway exists, and the exclusion routes are installed normally. `wakeup` is only consumed by `reconnectToVpn()` on Linux, so nothing else is affected. The kill switch keeps `allowDHCP` / `allowLAN` while the old tunnel is still configured, so NetworkManager can bring the uplink back up after resume. This is the network-watcher part of #2684, without the unrelated firewall / cgroup / routing-table changes (that PR no longer applies to `dev`). Related: #3037, #2997 (same symptom, exclusion route skipped because there was no gateway at connect time, but triggered by reboot or server switching, which this PR does not address). ## Testing Reproduced on Fedora 44 (kernel 7.2, NetworkManager, Wi-Fi, S3 `deep` sleep) with AmneziaVPN 5.0.1.5 + AmneziaWG; the log above is from that machine. The fix has not been built locally (no Qt 6 toolchain); relying on CI for the build. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amnezia-vpn/amnezia-client#3159
No description provided.