command_select.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package libbox
  2. import (
  3. "encoding/binary"
  4. "net"
  5. "github.com/sagernet/sing-box/protocol/group"
  6. E "github.com/sagernet/sing/common/exceptions"
  7. "github.com/sagernet/sing/common/varbin"
  8. )
  9. func (c *CommandClient) SelectOutbound(groupTag string, outboundTag string) error {
  10. conn, err := c.directConnect()
  11. if err != nil {
  12. return err
  13. }
  14. defer conn.Close()
  15. err = binary.Write(conn, binary.BigEndian, uint8(CommandSelectOutbound))
  16. if err != nil {
  17. return err
  18. }
  19. err = varbin.Write(conn, binary.BigEndian, groupTag)
  20. if err != nil {
  21. return err
  22. }
  23. err = varbin.Write(conn, binary.BigEndian, outboundTag)
  24. if err != nil {
  25. return err
  26. }
  27. return readError(conn)
  28. }
  29. func (s *CommandServer) handleSelectOutbound(conn net.Conn) error {
  30. groupTag, err := varbin.ReadValue[string](conn, binary.BigEndian)
  31. if err != nil {
  32. return err
  33. }
  34. outboundTag, err := varbin.ReadValue[string](conn, binary.BigEndian)
  35. if err != nil {
  36. return err
  37. }
  38. service := s.service
  39. if service == nil {
  40. return writeError(conn, E.New("service not ready"))
  41. }
  42. outboundGroup, isLoaded := service.instance.Outbound().Outbound(groupTag)
  43. if !isLoaded {
  44. return writeError(conn, E.New("selector not found: ", groupTag))
  45. }
  46. selector, isSelector := outboundGroup.(*group.Selector)
  47. if !isSelector {
  48. return writeError(conn, E.New("outbound is not a selector: ", groupTag))
  49. }
  50. if !selector.SelectOutbound(outboundTag) {
  51. return writeError(conn, E.New("outbound not found in selector: ", outboundTag))
  52. }
  53. return writeError(conn, nil)
  54. }