mirror of
https://github.com/slackhq/nebula.git
synced 2026-08-15 09:27:01 +02:00
8cbee0e965
On Android 11+ the app sandbox denies bind() on netlink_route_socket, so the stdlib's net.Interfaces fails with EACCES. localAddrs discarded that error and returned an empty slice, so the node advertised no underlay addresses and peers could only ever reach it at the address a lighthouse observed. A device on the same LAN as a peer was unreachable at its LAN address. Split interface enumeration behind a build-tagged seam and use github.com/wlynxg/anet on Android, which reads RTM_GETADDR from an unbound socket. Interface addresses have to come from anet as well, since net.Interface.Addrs goes back through the same denied path. Every other platform keeps the net package implementation. Stop discarding the enumeration errors, which are exceptional now that the sandbox case is handled. anet needs -ldflags=-checklinkname=0 on Go 1.23+. Nebula ships no Android binaries, so build-test-mobile is unaffected, but consumers linking Android artifacts will need the flag.
33 lines
1.2 KiB
Go
33 lines
1.2 KiB
Go
//go:build android
|
|
|
|
package nebula
|
|
|
|
import (
|
|
"net"
|
|
|
|
"github.com/wlynxg/anet"
|
|
)
|
|
|
|
// anet relies on //go:linkname and so needs -ldflags=-checklinkname=0 on Go 1.23+. Nebula ships no
|
|
// Android binaries of its own, so that burden falls on consumers linking Android artifacts.
|
|
|
|
func init() {
|
|
// anet only takes its bind-free path when it believes it is on API 30+, and detecting the running
|
|
// device's level requires cgo. Pin it so a CGO_ENABLED=0 build cannot quietly fall back to the
|
|
// denied path. The bind-free path is correct on older releases too, just unnecessary there.
|
|
anet.SetAndroidVersion(11)
|
|
}
|
|
|
|
// The app sandbox denies bind() on netlink_route_socket, so the stdlib's RTM_GETLINK enumeration
|
|
// fails with EACCES and we advertise no underlay addresses at all. anet reads RTM_GETADDR from an
|
|
// unbound socket instead, so this must not be collapsed back into net.Interfaces.
|
|
func localInterfaces() ([]net.Interface, error) {
|
|
return anet.Interfaces()
|
|
}
|
|
|
|
// net.Interface.Addrs goes back through the denied netlink path, so addresses have to come from anet
|
|
// as well. anet cannot report HardwareAddr, which localAddrs does not read.
|
|
func localInterfaceAddrs(i *net.Interface) ([]net.Addr, error) {
|
|
return anet.InterfaceAddrsByInterface(i)
|
|
}
|