command_client.go 1.4 KB

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