BasicHost's updateLocalIpAddr() fails on Android 11 (net.InterfaceAddrs returns error)

Hi all!

A bit of background: we are running an IPFS node on Android and after upgrading to the latest SDK started seeing errors like avc: denied { bind } for scontext=u:r:untrusted_app:s0:c154,c256,c512,c768 tcontext=u:r:untrusted_app:s0:c154,c256,c512,c768 tclass=netlink_route_socket permissive=0 b/155595000 app=... and {"level":"error","ts":"2021-12-15T13:26:14.324Z","logger":"basichost","caller":"basic/basic_host.go:300","msg":"failed to resolve local interface addresses","error":"route ip+net: netlinkrib: permission denied"}

So after a bit of digging we found out that this happens due to BasicHost method updateLocalIpAddr() calling manet.InterfaceMultiaddrs() (which calls net.InterfaceAddrs() which calls syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)).

Also another error comes from netroute.New(), but this is not so important if we find a solution for net.InterfaceAddrs()). Ultimately breaking changes were described here: Best practices for unique identifiers  |  Android Developers

To fix this we tried 2 approaches:

  • replicate the luni/src/main/java/java/net/NetworkInterface.java - platform/libcore - Git at Google in Go, but this approach failed because we can’t access sys/class/net on a non rooted device
  • create a go-mobile binding to a java object (in our case an interface called InterfaceAddrGetter) and pass it to go-multiaddr which worked for us, but this is far from pretty, because now we have to maintain our fork of go-multiaddr and also implement some part of logic on Android side.

The question is how you guys are planning to handle this and if the option that we chose is the most feasible way to handle such problem. If yes we can try to provide some mechanism to inject this kind of object inside libp2p to solve this problem and provide a PR.

Thanks!

About your actual issue I don’t know.

However you seem to have very similar goals as this project (providing alternate implementations to libp2p/IPFS interfaces for mobile): GitHub - ipfs-shipyard/gomobile-ipfs: IPFS and libp2p on Mobile, with Gomobile maybe you should check it out.