From 885f9f0acfb5927b20faea40fa215fc0d42665d2 Mon Sep 17 00:00:00 2001 From: hiddify Date: Tue, 13 Feb 2024 01:53:12 +0100 Subject: [PATCH] new: add box tester --- htest/libbox/box.go | 93 ++++++++++++++++++++++++++++++++++ htest/libbox/command_client.go | 91 +++++++++++++++++++++++++++++++++ htest/libbox/command_server.go | 34 +++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 htest/libbox/box.go create mode 100644 htest/libbox/command_client.go create mode 100644 htest/libbox/command_server.go diff --git a/htest/libbox/box.go b/htest/libbox/box.go new file mode 100644 index 0000000000..9a09addefa --- /dev/null +++ b/htest/libbox/box.go @@ -0,0 +1,93 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "os" + "os/signal" + "time" + + B "github.com/sagernet/sing-box" + "github.com/sagernet/sing-box/common/urltest" + "github.com/sagernet/sing-box/experimental/libbox" + "github.com/sagernet/sing-box/log" + "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/service" + "github.com/sagernet/sing/service/filemanager" + "github.com/sagernet/sing/service/pause" +) + +func main() { + options := option.Options{} + content, err := os.ReadFile("./hconfigs/full.json") + json.Unmarshal(content, &options) + fmt.Println(string(content)) + libbox.Setup("./hconfigs/", "./hconfigs/", "./hconfigs/", true) + ctx, cancel := context.WithCancel(context.Background()) + ctx = filemanager.WithDefault(ctx, "./hconfigs/", "./hconfigs/", os.Getuid(), os.Getgid()) + urlTestHistoryStorage := urltest.NewHistoryStorage() + ctx = service.ContextWithPtr(ctx, urlTestHistoryStorage) + + instance, err := B.New(B.Options{ + Context: ctx, + Options: options, + }) + if err != nil { + cancel() + return + } + commandServer = libbox.NewCommandServer(&CommandServerHandler{}, 100) + commandServer.Start() + service := libbox.NewBoxService( + ctx, + cancel, + instance, + service.FromContext[pause.Manager](ctx), + urlTestHistoryStorage, + ) + // instance.Start() + service.Start() + + commandServer.SetService(&service) + <-time.Tick(1 * time.Second) + fmt.Println("command group update") + + groupInfoOnlyClient := libbox.NewCommandClient( + &CommandClientHandler{ + logger: log.NewNOPFactory().NewLogger("[GroupInfoOnly Command Client]"), + }, + &libbox.CommandClientOptions{ + Command: libbox.CommandGroupInfoOnly, + StatusInterval: 3000000000, //300ms debounce + }, + ) + groupInfoOnlyClient.Connect() + groupClient := libbox.NewCommandClient( + &CommandClientHandler{ + logger: log.NewNOPFactory().NewLogger("[GroupInfoOnly Command Client]"), + }, + &libbox.CommandClientOptions{ + Command: libbox.CommandGroup, + StatusInterval: 3000000000, //300ms debounce + }, + ) + groupClient.Connect() + for i := 0; i < 4; i++ { + <-time.Tick(1000 * time.Millisecond) + fmt.Println("selecting auto") + libbox.NewStandaloneCommandClient().SelectOutbound("Select", "Auto") + <-time.Tick(1000 * time.Millisecond) + fmt.Println("selecting outbound") + libbox.NewStandaloneCommandClient().SelectOutbound("Select", "test") + } + fmt.Println("===========Finished many bounce") + <-time.Tick(20000 * time.Millisecond) + fmt.Println("===========selecting final auto") + libbox.NewStandaloneCommandClient().SelectOutbound("Select", "Auto") + + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt, os.Kill) + <-sigCh + +} diff --git a/htest/libbox/command_client.go b/htest/libbox/command_client.go new file mode 100644 index 0000000000..b0d53ffa76 --- /dev/null +++ b/htest/libbox/command_client.go @@ -0,0 +1,91 @@ +package main + +import ( + "encoding/json" + + "github.com/sagernet/sing-box/experimental/libbox" + "github.com/sagernet/sing-box/log" +) + +type CommandClientHandler struct { + logger log.Logger +} + +func (cch *CommandClientHandler) Connected() { + cch.logger.Debug("CONNECTED") +} + +func (cch *CommandClientHandler) Disconnected(message string) { + cch.logger.Debug("DISCONNECTED: ", message) +} + +func (cch *CommandClientHandler) ClearLog() { + cch.logger.Debug("clear log") +} + +func (cch *CommandClientHandler) WriteLog(message string) { + cch.logger.Debug("log: ", message) +} + +func (cch *CommandClientHandler) WriteStatus(message *libbox.StatusMessage) { + msg, _ := json.Marshal( + map[string]int64{ + "connections-in": int64(message.ConnectionsIn), + "connections-out": int64(message.ConnectionsOut), + "uplink": message.Uplink, + "downlink": message.Downlink, + "uplink-total": message.UplinkTotal, + "downlink-total": message.DownlinkTotal, + }, + ) + cch.logger.Debug("Memory: ", libbox.FormatBytes(message.Memory), ", Goroutines: ", message.Goroutines) + log.Warn(msg) +} + +func (cch *CommandClientHandler) WriteGroups(message libbox.OutboundGroupIterator) { + if message == nil { + return + } + groups := []*OutboundGroup{} + for message.HasNext() { + group := message.Next() + items := group.GetItems() + groupItems := []*OutboundGroupItem{} + for items.HasNext() { + item := items.Next() + groupItems = append(groupItems, + &OutboundGroupItem{ + Tag: item.Tag, + Type: item.Type, + URLTestTime: item.URLTestTime, + URLTestDelay: item.URLTestDelay, + }, + ) + } + groups = append(groups, &OutboundGroup{Tag: group.Tag, Type: group.Type, Selected: group.Selected, Items: groupItems}) + } + response, _ := json.Marshal(groups) + log.Warn(string(response)) +} + +func (cch *CommandClientHandler) InitializeClashMode(modeList libbox.StringIterator, currentMode string) { + cch.logger.Debug("initial clash mode: ", currentMode) +} + +func (cch *CommandClientHandler) UpdateClashMode(newMode string) { + cch.logger.Debug("update clash mode: ", newMode) +} + +type OutboundGroup struct { + Tag string `json:"tag"` + Type string `json:"type"` + Selected string `json:"selected"` + Items []*OutboundGroupItem `json:"items"` +} + +type OutboundGroupItem struct { + Tag string `json:"tag"` + Type string `json:"type"` + URLTestTime int64 `json:"url-test-time"` + URLTestDelay int32 `json:"url-test-delay"` +} diff --git a/htest/libbox/command_server.go b/htest/libbox/command_server.go new file mode 100644 index 0000000000..4ad9611bfa --- /dev/null +++ b/htest/libbox/command_server.go @@ -0,0 +1,34 @@ +package main + +import ( + "github.com/sagernet/sing-box/log" + + "github.com/sagernet/sing-box/experimental/libbox" +) + +type CommandServerHandler struct { + logger log.Logger +} + +var commandServer *libbox.CommandServer + +func (csh *CommandServerHandler) ServiceReload() error { + + if commandServer != nil { + commandServer.SetService(nil) + commandServer = nil + } + // if box != nil { + // box.Close() + // box = nil + // } + return nil +} + +func (csh *CommandServerHandler) GetSystemProxyStatus() *libbox.SystemProxyStatus { + return &libbox.SystemProxyStatus{Available: true, Enabled: false} +} + +func (csh *CommandServerHandler) SetSystemProxyEnabled(isEnabled bool) error { + return csh.ServiceReload() +}