diff --git a/experimental/libbox/command.go b/experimental/libbox/command.go index 28c477bb..f42b302d 100644 --- a/experimental/libbox/command.go +++ b/experimental/libbox/command.go @@ -5,6 +5,7 @@ package libbox const ( CommandLog int32 = iota CommandStatus + CommandServiceStop CommandServiceReload CommandCloseConnections ) diff --git a/experimental/libbox/command_server.go b/experimental/libbox/command_server.go index b88c65fe..a04be839 100644 --- a/experimental/libbox/command_server.go +++ b/experimental/libbox/command_server.go @@ -27,6 +27,7 @@ type CommandServer struct { } type CommandServerHandler interface { + ServiceStop() error ServiceReload() error } @@ -50,6 +51,7 @@ func (s *CommandServer) Start() error { if err != nil { return err } + s.listener = listener go s.loopConnection(listener) return nil } @@ -85,6 +87,8 @@ func (s *CommandServer) handleConnection(conn net.Conn) error { return s.handleLogConn(conn) case CommandStatus: return s.handleStatusConn(conn) + case CommandServiceStop: + return s.handleServiceStop(conn) case CommandServiceReload: return s.handleServiceReload(conn) case CommandCloseConnections: diff --git a/experimental/libbox/command_status.go b/experimental/libbox/command_status.go index 50093277..4d18063e 100644 --- a/experimental/libbox/command_status.go +++ b/experimental/libbox/command_status.go @@ -22,7 +22,7 @@ func readStatus() StatusMessage { var memStats runtime.MemStats runtime.ReadMemStats(&memStats) var message StatusMessage - message.Memory = int64(memStats.Sys - memStats.HeapReleased) + message.Memory = int64(memStats.StackInuse + memStats.HeapInuse + memStats.HeapIdle - memStats.HeapReleased) message.Goroutines = int32(runtime.NumGoroutine()) message.Connections = int32(conntrack.Count()) return message diff --git a/experimental/libbox/command_stop.go b/experimental/libbox/command_stop.go new file mode 100644 index 00000000..13048d05 --- /dev/null +++ b/experimental/libbox/command_stop.go @@ -0,0 +1,50 @@ +//go:build darwin + +package libbox + +import ( + "encoding/binary" + "net" + "runtime/debug" + + E "github.com/sagernet/sing/common/exceptions" + "github.com/sagernet/sing/common/rw" +) + +func ClientServiceStop(sharedDirectory string) error { + conn, err := clientConnect(sharedDirectory) + if err != nil { + return err + } + defer conn.Close() + err = binary.Write(conn, binary.BigEndian, uint8(CommandServiceStop)) + if err != nil { + return err + } + var hasError bool + err = binary.Read(conn, binary.BigEndian, &hasError) + if err != nil { + return err + } + if hasError { + errorMessage, err := rw.ReadVString(conn) + if err != nil { + return err + } + return E.New(errorMessage) + } + return nil +} + +func (s *CommandServer) handleServiceStop(conn net.Conn) error { + rErr := s.handler.ServiceStop() + err := binary.Write(conn, binary.BigEndian, rErr != nil) + if err != nil { + return err + } + if rErr != nil { + return rw.WriteVString(conn, rErr.Error()) + } + debug.FreeOSMemory() + return nil +} diff --git a/experimental/libbox/service.go b/experimental/libbox/service.go index b0968443..1832712d 100644 --- a/experimental/libbox/service.go +++ b/experimental/libbox/service.go @@ -3,7 +3,6 @@ package libbox import ( "context" "net/netip" - "runtime" "syscall" "github.com/sagernet/sing-box" @@ -28,7 +27,6 @@ func NewService(configContent string, platformInterface PlatformInterface) (*Box if err != nil { return nil, err } - platformInterface.WriteLog("Hello " + runtime.GOOS + "/" + runtime.GOARCH) ctx, cancel := context.WithCancel(context.Background()) instance, err := box.New(ctx, options, &platformInterfaceWrapper{platformInterface, platformInterface.UseProcFS()}) if err != nil {