- Android: Dart FFI → Go c-shared (.so) in jniLibs (arm64-v8a + x86_64) - Linux: Dart FFI → Go c-shared (.so) via Docker cross-compilation (amd64) - Dart API: TsnetFlutter uses MethodChannel on iOS/macOS, FFI on Android/Linux - Add ffi package dependency for native function bindings - Build script: ./build_go.sh [ios|macos|android|linux|apple|all] - Android RegisterInterfaceGetter to bypass netlink CAP_NET_ADMIN restriction - Make TailscaleStart() idempotent and add GODEBUG=netdns=go for Android Known: Android tsnet tunnel blocked by Go stdlib net.Interfaces() netlink call — local gRPC works, Tailscale fallback needs libtailscale integration. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
40 lines
1011 B
Go
40 lines
1011 B
Go
//go:build android
|
|
|
|
package main
|
|
|
|
import (
|
|
"net"
|
|
|
|
"tailscale.com/net/netmon"
|
|
)
|
|
|
|
func init() {
|
|
// Register an alternate interface getter for Android.
|
|
// Go's net.Interfaces() uses netlink which requires CAP_NET_ADMIN,
|
|
// and /sys/class/net is restricted on modern Android.
|
|
// Provide a minimal loopback interface to satisfy tsnet's startup.
|
|
// tsnet uses userspace netstack and doesn't need real interface data.
|
|
netmon.RegisterInterfaceGetter(func() ([]netmon.Interface, error) {
|
|
return []netmon.Interface{
|
|
{
|
|
Interface: &net.Interface{
|
|
Index: 1,
|
|
MTU: 65536,
|
|
Name: "lo",
|
|
HardwareAddr: nil,
|
|
Flags: net.FlagUp | net.FlagLoopback | net.FlagRunning,
|
|
},
|
|
},
|
|
{
|
|
Interface: &net.Interface{
|
|
Index: 2,
|
|
MTU: 1500,
|
|
Name: "wlan0",
|
|
HardwareAddr: net.HardwareAddr{0x02, 0x00, 0x00, 0x00, 0x00, 0x01},
|
|
Flags: net.FlagUp | net.FlagRunning | net.FlagMulticast,
|
|
},
|
|
},
|
|
}, nil
|
|
})
|
|
}
|