command_select.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package libbox
  2. import (
  3. "encoding/binary"
  4. "net"
  5. "github.com/sagernet/sing-box/outbound"
  6. E "github.com/sagernet/sing/common/exceptions"
  7. "github.com/sagernet/sing/common/rw"
  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 = rw.WriteVString(conn, groupTag)
  20. if err != nil {
  21. return err
  22. }
  23. err = rw.WriteVString(conn, outboundTag)
  24. if err != nil {
  25. return err
  26. }
  27. return readError(conn)
  28. }
  29. func (s *CommandServer) handleSelectOutbound(conn net.Conn) error {
  30. defer conn.Close()
  31. groupTag, err := rw.ReadVString(conn)
  32. if err != nil {
  33. return err
  34. }
  35. outboundTag, err := rw.ReadVString(conn)
  36. if err != nil {
  37. return err
  38. }
  39. service := s.service
  40. if service == nil {
  41. return writeError(conn, E.New("service not ready"))
  42. }
  43. outboundGroup, isLoaded := service.instance.Router().Outbound(groupTag)
  44. if !isLoaded {
  45. return writeError(conn, E.New("selector not found: ", groupTag))
  46. }
  47. selector, isSelector := outboundGroup.(*outbound.Selector)
  48. if !isSelector {
  49. return writeError(conn, E.New("outbound is not a selector: ", groupTag))
  50. }
  51. if !selector.SelectOutbound(outboundTag) {
  52. return writeError(conn, E.New("outbound not found in selector: ", outboundTag))
  53. }
  54. return writeError(conn, nil)
  55. }