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 }