github.com/sagernet/sing-box@v1.2.7/experimental/libbox/command_client.go (about) 1 package libbox 2 3 import ( 4 "encoding/binary" 5 "net" 6 "path/filepath" 7 8 "github.com/sagernet/sing/common" 9 E "github.com/sagernet/sing/common/exceptions" 10 ) 11 12 type CommandClient struct { 13 sharedDirectory string 14 handler CommandClientHandler 15 conn net.Conn 16 options CommandClientOptions 17 } 18 19 type CommandClientOptions struct { 20 Command int32 21 StatusInterval int64 22 } 23 24 type CommandClientHandler interface { 25 Connected() 26 Disconnected(message string) 27 WriteLog(message string) 28 WriteStatus(message *StatusMessage) 29 } 30 31 func NewCommandClient(sharedDirectory string, handler CommandClientHandler, options *CommandClientOptions) *CommandClient { 32 return &CommandClient{ 33 sharedDirectory: sharedDirectory, 34 handler: handler, 35 options: common.PtrValueOrDefault(options), 36 } 37 } 38 39 func clientConnect(sharedDirectory string) (net.Conn, error) { 40 return net.DialUnix("unix", nil, &net.UnixAddr{ 41 Name: filepath.Join(sharedDirectory, "command.sock"), 42 Net: "unix", 43 }) 44 } 45 46 func (c *CommandClient) Connect() error { 47 common.Close(c.conn) 48 conn, err := clientConnect(c.sharedDirectory) 49 if err != nil { 50 return err 51 } 52 c.conn = conn 53 err = binary.Write(conn, binary.BigEndian, uint8(c.options.Command)) 54 if err != nil { 55 return err 56 } 57 switch c.options.Command { 58 case CommandLog: 59 c.handler.Connected() 60 go c.handleLogConn(conn) 61 case CommandStatus: 62 err = binary.Write(conn, binary.BigEndian, c.options.StatusInterval) 63 if err != nil { 64 return E.Cause(err, "write interval") 65 } 66 c.handler.Connected() 67 go c.handleStatusConn(conn) 68 } 69 return nil 70 } 71 72 func (c *CommandClient) Disconnect() error { 73 return common.Close(c.conn) 74 }