github.com/sagernet/sing-box@v1.9.0-rc.20/cmd/sing-box/cmd_tools_connect.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  
     7  	"github.com/sagernet/sing-box/log"
     8  	"github.com/sagernet/sing/common"
     9  	"github.com/sagernet/sing/common/bufio"
    10  	E "github.com/sagernet/sing/common/exceptions"
    11  	M "github.com/sagernet/sing/common/metadata"
    12  	N "github.com/sagernet/sing/common/network"
    13  	"github.com/sagernet/sing/common/task"
    14  
    15  	"github.com/spf13/cobra"
    16  )
    17  
    18  var commandConnectFlagNetwork string
    19  
    20  var commandConnect = &cobra.Command{
    21  	Use:   "connect <address>",
    22  	Short: "Connect to an address",
    23  	Args:  cobra.ExactArgs(1),
    24  	Run: func(cmd *cobra.Command, args []string) {
    25  		err := connect(args[0])
    26  		if err != nil {
    27  			log.Fatal(err)
    28  		}
    29  	},
    30  }
    31  
    32  func init() {
    33  	commandConnect.Flags().StringVarP(&commandConnectFlagNetwork, "network", "n", "tcp", "network type")
    34  	commandTools.AddCommand(commandConnect)
    35  }
    36  
    37  func connect(address string) error {
    38  	switch N.NetworkName(commandConnectFlagNetwork) {
    39  	case N.NetworkTCP, N.NetworkUDP:
    40  	default:
    41  		return E.Cause(N.ErrUnknownNetwork, commandConnectFlagNetwork)
    42  	}
    43  	instance, err := createPreStartedClient()
    44  	if err != nil {
    45  		return err
    46  	}
    47  	defer instance.Close()
    48  	dialer, err := createDialer(instance, commandConnectFlagNetwork, commandToolsFlagOutbound)
    49  	if err != nil {
    50  		return err
    51  	}
    52  	conn, err := dialer.DialContext(context.Background(), commandConnectFlagNetwork, M.ParseSocksaddr(address))
    53  	if err != nil {
    54  		return E.Cause(err, "connect to server")
    55  	}
    56  	var group task.Group
    57  	group.Append("upload", func(ctx context.Context) error {
    58  		return common.Error(bufio.Copy(conn, os.Stdin))
    59  	})
    60  	group.Append("download", func(ctx context.Context) error {
    61  		return common.Error(bufio.Copy(os.Stdout, conn))
    62  	})
    63  	group.Cleanup(func() {
    64  		conn.Close()
    65  	})
    66  	err = group.Run(context.Background())
    67  	if E.IsClosed(err) {
    68  		log.Info(err)
    69  	} else {
    70  		log.Error(err)
    71  	}
    72  	return nil
    73  }