From ceffcc0ad2126bf2a18257cffcbd823d73412c3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Thu, 14 Mar 2024 13:40:17 +0800 Subject: [PATCH] platform: Improve stop on apple platforms --- experimental/libbox/command.go | 1 + .../{command_reload.go => command_power.go} | 38 +++++++++++++++++++ experimental/libbox/command_server.go | 3 ++ experimental/libbox/service.go | 13 +++++++ 4 files changed, 55 insertions(+) rename experimental/libbox/{command_reload.go => command_power.go} (53%) diff --git a/experimental/libbox/command.go b/experimental/libbox/command.go index 0a757076..7915419d 100644 --- a/experimental/libbox/command.go +++ b/experimental/libbox/command.go @@ -4,6 +4,7 @@ const ( CommandLog int32 = iota CommandStatus CommandServiceReload + CommandServiceClose CommandCloseConnections CommandGroup CommandSelectOutbound diff --git a/experimental/libbox/command_reload.go b/experimental/libbox/command_power.go similarity index 53% rename from experimental/libbox/command_reload.go rename to experimental/libbox/command_power.go index 4c8774a7..619cb57b 100644 --- a/experimental/libbox/command_reload.go +++ b/experimental/libbox/command_power.go @@ -44,3 +44,41 @@ func (s *CommandServer) handleServiceReload(conn net.Conn) error { } return nil } + +func (c *CommandClient) ServiceClose() error { + conn, err := c.directConnect() + if err != nil { + return err + } + defer conn.Close() + err = binary.Write(conn, binary.BigEndian, uint8(CommandServiceClose)) + if err != nil { + return err + } + var hasError bool + err = binary.Read(conn, binary.BigEndian, &hasError) + if err != nil { + return nil + } + if hasError { + errorMessage, err := rw.ReadVString(conn) + if err != nil { + return nil + } + return E.New(errorMessage) + } + return nil +} + +func (s *CommandServer) handleServiceClose(conn net.Conn) error { + rErr := s.service.Close() + s.handler.PostServiceClose() + err := binary.Write(conn, binary.BigEndian, rErr != nil) + if err != nil { + return err + } + if rErr != nil { + return rw.WriteVString(conn, rErr.Error()) + } + return nil +} diff --git a/experimental/libbox/command_server.go b/experimental/libbox/command_server.go index ec68b4ca..da931ef5 100644 --- a/experimental/libbox/command_server.go +++ b/experimental/libbox/command_server.go @@ -37,6 +37,7 @@ type CommandServer struct { type CommandServerHandler interface { ServiceReload() error + PostServiceClose() GetSystemProxyStatus() *SystemProxyStatus SetSystemProxyEnabled(isEnabled bool) error } @@ -155,6 +156,8 @@ func (s *CommandServer) handleConnection(conn net.Conn) error { return s.handleStatusConn(conn) case CommandServiceReload: return s.handleServiceReload(conn) + case CommandServiceClose: + return s.handleServiceClose(conn) case CommandCloseConnections: return s.handleCloseConnections(conn) case CommandGroup: diff --git a/experimental/libbox/service.go b/experimental/libbox/service.go index a516c4c5..bfc48094 100644 --- a/experimental/libbox/service.go +++ b/experimental/libbox/service.go @@ -3,14 +3,17 @@ package libbox import ( "context" "net/netip" + "os" "runtime" runtimeDebug "runtime/debug" "syscall" + "time" "github.com/sagernet/sing-box" "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/common/process" "github.com/sagernet/sing-box/common/urltest" + C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/experimental/libbox/internal/procfs" "github.com/sagernet/sing-box/experimental/libbox/platform" "github.com/sagernet/sing-box/log" @@ -72,6 +75,16 @@ func (s *BoxService) Start() error { } func (s *BoxService) Close() error { + done := make(chan struct{}) + defer close(done) + go func() { + select { + case <-done: + return + case <-time.After(C.DefaultStopFatalTimeout): + os.Exit(1) + } + }() s.cancel() s.urlTestHistoryStorage.Close() return s.instance.Close()