threefoldtech/myceliumflut

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

https://github.com/yggdrasil-network/yggdrasil-android/blob/aa94ccad26435de615cfbae4ae13740e12db1040/app/src/main/java/eu/neilalexander/yggdrasil/NetworkStateCallback.kt#L15-L35

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