github.com/sagernet/sing-box@v1.9.0-rc.20/experimental/libbox/command_select.go (about)

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