android: handle network state changes
Opened this issue · 4 comments
Mobile phone have certain behaviors that different with server or PC/laptop: connection lost (and connected again) is not uncommon, for many reasons.
While mycelium
should already handle connection lost, there are more about it in mobile phone:
- we will save battery by stopping mycelium while the connection is lost
- it gives more visibility when things going wrong, for example when
mycelium
disconnected while we thought that it should be connected - our android log will be cleaner from unnecessary connection failure logs
Android has builtin class for this : NetworkCallback
. It can give notification for various network state changes events:
- onAvailable
- onBlockedStatusChanged
- onCapabilitiesChanged
- onLinkPropertiesChanged
- onLosing
- onLost
- onUnavailable
Some research has been done to other platform about how they handle network state event.
yggdrasil
only handle onAvailable
event
If we follow the code, it will call their Go engine
https://github.com/yggdrasil-network/yggdrasil-go/blob/v0.5.5/contrib/mobile/mobile.go#L183-L186
// Retry resets the peer connection timer and tries to dial them immediately.
func (m *Yggdrasil) RetryPeersNow() {
m.core.RetryPeersNow()
}
from the comment and quick read, looks like yggdrasil
resets all the connections.
I think this way is quite simple and reliable
I also looked at wireguard-android and found nothing so far.
But i found that wireguard-apple
do have the handles as i mentioned in #35 (comment)
To summarize, wireguard-apple
do these:
- network lost: stop
wireguard
- if network available after lost : start
wireguard
- network available when wireguard state is
started
: bump sockets:
- close existing socket
- re-open socket
- send keepalive to peers
looks like yggdrasil resets all the connections.
network available when wireguard state is started: bump sockets:
- close existing socket
- re-open socket
- send keepalive to peers
All of above things are done in their respective engine (yggdrasil-go and wireguard-go), so we might need to do that as well in mycelium
The NetworkCallback
already added and below are my observations:
- the network available and lost events are not about connected or disconnected, but more like about the interfaces (mobile, wifi, etc) up or down
- when we got network lost event, it doesn't mean that we have no connection anymore, because there might be another interface that still up. For example:
- wifi down
- mobile still active can take over - when mycelium disconnected for too long, there is no
NetworkCallback
event - wireguard-android doesn't have any NetworkCallback handler
- yggdrasil only refresh the peers when network become available, this functionality doesn't exist in mycelium
mycelium
can handle network lost -> available perfectly
For now i will push the NetworkCallback
code but only in listening mode, no specific actions taken when any events fired