Explorar o código

Add workaround for golang/go#68760

世界 hai 10 meses
pai
achega
f0b6818b4c

+ 6 - 0
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

+ 8 - 0
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",

+ 8 - 0
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

+ 5 - 0
constant/cgo_android_fix_stub.go

@@ -0,0 +1,5 @@
+//go:build !(android && debug)
+
+package constant
+
+const FixAndroidStack = false

+ 18 - 4
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)

+ 9 - 0
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

+ 24 - 11
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 {
+	s.cancel()
+	s.urlTestHistoryStorage.Close()
+	var err error
 	done := make(chan struct{})
-	defer close(done)
 	go func() {
-		select {
-		case <-done:
-			return
-		case <-time.After(C.FatalStopTimeout):
-			os.Exit(1)
-		}
+		err = s.instance.Close()
+		close(done)
 	}()
-	s.cancel()
-	s.urlTestHistoryStorage.Close()
-	return s.instance.Close()
+	select {
+	case <-done:
+		return err
+	case <-time.After(C.FatalStopTimeout):
+		os.Exit(1)
+		return nil
+	}
 }
 
 func (s *BoxService) NeedWIFIState() bool {