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  }