diff --git a/Makefile b/Makefile index 70627aea..2bc14989 100644 --- a/Makefile +++ b/Makefile @@ -201,9 +201,15 @@ test_stdio: lib_android: go run ./cmd/internal/build_libbox -target android +lib_android_debug: + go run ./cmd/internal/build_libbox -target android -debug + lib_ios: go run ./cmd/internal/build_libbox -target ios +lib_ios_debug: + go run ./cmd/internal/build_libbox -target ios -debug + lib: go run ./cmd/internal/build_libbox -target android go run ./cmd/internal/build_libbox -target ios diff --git a/cmd/internal/build_libbox/main.go b/cmd/internal/build_libbox/main.go index e6b9bbd7..9d9151bd 100644 --- a/cmd/internal/build_libbox/main.go +++ b/cmd/internal/build_libbox/main.go @@ -80,9 +80,17 @@ func buildAndroid() { log.Fatal("java version should be openjdk 17") } + var bindTarget string + if debugEnabled { + bindTarget = "android/arm64" + } else { + bindTarget = "android" + } + args := []string{ "bind", "-v", + "-target", bindTarget, "-androidapi", "21", "-javapkg=io.nekohasekai", "-libname=box", diff --git a/constant/cgo_android_fix.go b/constant/cgo_android_fix.go new file mode 100644 index 00000000..cb4023c4 --- /dev/null +++ b/constant/cgo_android_fix.go @@ -0,0 +1,8 @@ +//go:build android && debug + +package constant + +// TODO: remove after fixed +// https://github.com/golang/go/issues/68760 + +const FixAndroidStack = true diff --git a/constant/cgo_android_fix_stub.go b/constant/cgo_android_fix_stub.go new file mode 100644 index 00000000..6145f9f5 --- /dev/null +++ b/constant/cgo_android_fix_stub.go @@ -0,0 +1,5 @@ +//go:build !(android && debug) + +package constant + +const FixAndroidStack = false diff --git a/experimental/libbox/command_client.go b/experimental/libbox/command_client.go index bd995115..a9b1c131 100644 --- a/experimental/libbox/command_client.go +++ b/experimental/libbox/command_client.go @@ -7,6 +7,7 @@ import ( "path/filepath" "time" + C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" ) @@ -113,11 +114,24 @@ func (c *CommandClient) Connect() error { if err != nil { return err } - c.handler.Connected() - c.handler.InitializeClashMode(newIterator(modeList), currentMode) + if C.FixAndroidStack { + go func() { + c.handler.Connected() + c.handler.InitializeClashMode(newIterator(modeList), currentMode) + if len(modeList) == 0 { + conn.Close() + c.handler.Disconnected(os.ErrInvalid.Error()) + } + }() + } else { + c.handler.Connected() + c.handler.InitializeClashMode(newIterator(modeList), currentMode) + if len(modeList) == 0 { + conn.Close() + c.handler.Disconnected(os.ErrInvalid.Error()) + } + } if len(modeList) == 0 { - conn.Close() - c.handler.Disconnected(os.ErrInvalid.Error()) return nil } go c.handleModeConn(conn) diff --git a/experimental/libbox/monitor.go b/experimental/libbox/monitor.go index 60fc2b8e..d0517973 100644 --- a/experimental/libbox/monitor.go +++ b/experimental/libbox/monitor.go @@ -5,6 +5,7 @@ import ( "net/netip" "sync" + C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-tun" "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" @@ -97,6 +98,14 @@ func (m *platformDefaultInterfaceMonitor) UnregisterCallback(element *list.Eleme } func (m *platformDefaultInterfaceMonitor) UpdateDefaultInterface(interfaceName string, interfaceIndex32 int32) { + if C.FixAndroidStack { + go m.updateDefaultInterface(interfaceName, interfaceIndex32) + } else { + m.updateDefaultInterface(interfaceName, interfaceIndex32) + } +} + +func (m *platformDefaultInterfaceMonitor) updateDefaultInterface(interfaceName string, interfaceIndex32 int32) { if interfaceName == "" || interfaceIndex32 == -1 { m.defaultInterfaceName = "" m.defaultInterfaceIndex = -1 diff --git a/experimental/libbox/service.go b/experimental/libbox/service.go index 20395e95..a08d5e07 100644 --- a/experimental/libbox/service.go +++ b/experimental/libbox/service.go @@ -73,23 +73,36 @@ func NewService(configContent string, platformInterface PlatformInterface) (*Box } func (s *BoxService) Start() error { - return s.instance.Start() + if C.FixAndroidStack { + var err error + done := make(chan struct{}) + go func() { + err = s.instance.Start() + close(done) + }() + <-done + return err + } else { + return s.instance.Start() + } } func (s *BoxService) Close() error { - done := make(chan struct{}) - defer close(done) - go func() { - select { - case <-done: - return - case <-time.After(C.FatalStopTimeout): - os.Exit(1) - } - }() s.cancel() s.urlTestHistoryStorage.Close() - return s.instance.Close() + var err error + done := make(chan struct{}) + go func() { + err = s.instance.Close() + close(done) + }() + select { + case <-done: + return err + case <-time.After(C.FatalStopTimeout): + os.Exit(1) + return nil + } } func (s *BoxService) NeedWIFIState() bool {