The call drops when you drive past the edge of town, and the VPN icon disappears at the same moment. It is tempting to file that as "cell tower change killed the tunnel". Two different things happened, and only one of them is about towers. A radio handover can leave your IP address, default route and session completely intact, while a genuine address change will break any tunnel that cannot move with it. Comparing how clients handle that second case is the useful exercise, because it tells you whether you are seeing a designed behaviour or a bug.

A tower change is not necessarily an address change

Mobile networks keep the packet session alive across handovers as long as the carrier's mobility anchor stays the same. The radio link changes, the tunnel does not notice, and no reconnect should appear in any log. This is the ordinary case for movement within a city.

What does change the address is a move between anchors, a switch from Wi-Fi to cellular, or a carrier-side tunnel re-establishment after a long gap. Those events replace the source address your packets carry, and a VPN peer sees a peer that has moved.

The practical consequence is that movement is not evidence. A device that travelled forty kilometres may have kept one address the whole way, and a device sitting still may have changed address twice because the network decided to. Recording the event is the only way to tell those apart.

Two designs: move the tunnel or rebuild it

Clients differ in how much they care that the outer source changed. Some bind the tunnel to the address it was built on and require a full re-establishment. Others authenticate each packet independently and simply update where they send the replies.

MechanismBehaviour after the source changesWhat the user notices
WireGuardEndpoint updated on the next authenticated packetUsually nothing; the tunnel continues
IKEv2 with MOBIKESecurity association moves to the new addressShort pause, no re-authentication
OpenVPN over UDP with floatPeer address may change without a restartMight survive, depending on timing
Client bound to one addressSession dies and is rebuiltA visible reconnect and a new authentication

The top row explains a lot of confusing reports. WireGuard has no session to break: each packet carries the index of the peer and is authenticated, so a valid packet arriving from a new address is by definition from that peer, and the recorded endpoint follows it. A client that shows "connected" continuously across a drive is telling the truth.

The bottom row is not a defect either. Rebuilding the session re-runs authentication against the current address, which is exactly what you want when the old address may now belong to somebody else.

Observe the event instead of the movement

On Android the connectivity subsystem reports network changes as events, and those are what you should correlate with the client's behaviour. The dump is verbose but the relevant parts are the default network and its address:

adb shell dumpsys connectivity | grep -E 'NetworkAgentInfo|Default network'
adb shell ip -br addr show
adb logcat -b main -s Vpn:* | head -n 40

On the server side there is a direct measurement for the roaming case. WireGuard stores the last authenticated endpoint per peer, so a change of address appears as a changed value rather than as a reconnect:

sudo wg show wg0 endpoints
sudo wg show wg0 latest-handshakes

Compare the endpoint before and after the drive. If the address and port are unchanged, the tunnel never had to do anything and the reconnect came from somewhere else, usually the application. If the endpoint changed while the handshake timestamp stayed close to its normal rekey interval, the tunnel moved rather than restarted.

A restart looks different: the handshake timestamp resets to the moment of reconnection, and the client logs an initialisation sequence rather than a quiet continuation.

When the reconnect is the correct behaviour

Treating every reconnect as a fault leads to configurations that keep dead sessions alive. A peer whose address changed because the network reallocated it should not keep receiving traffic for the old mapping, and a client that silently continues can end up sending into a black hole while the icon stays green.

Compare the two failures from a user's perspective. A reconnect costs a few seconds and a re-authentication. A stale tunnel costs an application that hangs without an error, which is much harder to explain and much more likely to be reported as "the internet is broken".

There is a policy question hiding underneath as well. During the gap between losing one path and establishing another, some clients fall back to sending traffic directly. Preventing that is a separate control from automatic recovery, and a client can be good at one and poor at the other. Decide which you need before you tune either.

Write down the observed sequence

A useful report names the event source: a default-network change with a new address, a Wi-Fi to cellular switch, or a handover with no address change at all. It then states what the client did, with the timestamp from the server side rather than from memory.

If the tunnel moved, say so and note the new endpoint family. If it re-established, note whether authentication succeeded on the first attempt and how long the gap lasted. Those three facts distinguish a healthy mobile design from a client that is thrashing between networks.

And avoid the phrase "tower change" unless the device log actually establishes it. The Android connectivity documentation describes the callbacks that distinguish availability from a default-network change, and that distinction is the one your report needs. Everything else is a story about driving.

Ingingo zihuye