command_client.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. sharedDirectory 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. sharedDirectory: sharedDirectory,
  29. handler: handler,
  30. options: common.PtrValueOrDefault(options),
  31. }
  32. }
  33. func clientConnect(sharedDirectory string) (net.Conn, error) {
  34. return net.DialUnix("unix", nil, &net.UnixAddr{
  35. Name: filepath.Join(sharedDirectory, "command.sock"),
  36. Net: "unix",
  37. })
  38. }
  39. func (c *CommandClient) Connect() error {
  40. conn, err := clientConnect(c.sharedDirectory)
  41. if err != nil {
  42. return err
  43. }
  44. c.conn = conn
  45. err = binary.Write(conn, binary.BigEndian, uint8(c.options.Command))
  46. if err != nil {
  47. return err
  48. }
  49. switch c.options.Command {
  50. case CommandLog:
  51. c.handler.Connected()
  52. go c.handleLogConn(conn)
  53. case CommandStatus:
  54. err = binary.Write(conn, binary.BigEndian, c.options.StatusInterval)
  55. if err != nil {
  56. return E.Cause(err, "write interval")
  57. }
  58. c.handler.Connected()
  59. go c.handleStatusConn(conn)
  60. }
  61. return nil
  62. }
  63. func (c *CommandClient) Disconnect() error {
  64. return common.Close(c.conn)
  65. }