github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/testing/scenarios/reverse_test.go (about)

     1  package scenarios
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"golang.org/x/sync/errgroup"
     8  	"google.golang.org/protobuf/types/known/anypb"
     9  
    10  	core "github.com/v2fly/v2ray-core/v5"
    11  	"github.com/v2fly/v2ray-core/v5/app/log"
    12  	"github.com/v2fly/v2ray-core/v5/app/policy"
    13  	"github.com/v2fly/v2ray-core/v5/app/proxyman"
    14  	"github.com/v2fly/v2ray-core/v5/app/reverse"
    15  	"github.com/v2fly/v2ray-core/v5/app/router"
    16  	"github.com/v2fly/v2ray-core/v5/app/router/routercommon"
    17  	"github.com/v2fly/v2ray-core/v5/common"
    18  	clog "github.com/v2fly/v2ray-core/v5/common/log"
    19  	"github.com/v2fly/v2ray-core/v5/common/net"
    20  	"github.com/v2fly/v2ray-core/v5/common/protocol"
    21  	"github.com/v2fly/v2ray-core/v5/common/serial"
    22  	"github.com/v2fly/v2ray-core/v5/common/uuid"
    23  	"github.com/v2fly/v2ray-core/v5/proxy/blackhole"
    24  	"github.com/v2fly/v2ray-core/v5/proxy/dokodemo"
    25  	"github.com/v2fly/v2ray-core/v5/proxy/freedom"
    26  	"github.com/v2fly/v2ray-core/v5/proxy/vmess"
    27  	"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound"
    28  	"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound"
    29  	"github.com/v2fly/v2ray-core/v5/testing/servers/tcp"
    30  )
    31  
    32  func TestReverseProxy(t *testing.T) {
    33  	tcpServer := tcp.Server{
    34  		MsgProcessor: xor,
    35  	}
    36  	dest, err := tcpServer.Start()
    37  	common.Must(err)
    38  
    39  	defer tcpServer.Close()
    40  
    41  	userID := protocol.NewID(uuid.New())
    42  	externalPort := tcp.PickPort()
    43  	reversePort := tcp.PickPort()
    44  
    45  	serverConfig := &core.Config{
    46  		App: []*anypb.Any{
    47  			serial.ToTypedMessage(&reverse.Config{
    48  				PortalConfig: []*reverse.PortalConfig{
    49  					{
    50  						Tag:    "portal",
    51  						Domain: "test.v2fly.org",
    52  					},
    53  				},
    54  			}),
    55  			serial.ToTypedMessage(&router.Config{
    56  				Rule: []*router.RoutingRule{
    57  					{
    58  						Domain: []*routercommon.Domain{
    59  							{Type: routercommon.Domain_Full, Value: "test.v2fly.org"},
    60  						},
    61  						TargetTag: &router.RoutingRule_Tag{
    62  							Tag: "portal",
    63  						},
    64  					},
    65  					{
    66  						InboundTag: []string{"external"},
    67  						TargetTag: &router.RoutingRule_Tag{
    68  							Tag: "portal",
    69  						},
    70  					},
    71  				},
    72  			}),
    73  		},
    74  		Inbound: []*core.InboundHandlerConfig{
    75  			{
    76  				Tag: "external",
    77  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
    78  					PortRange: net.SinglePortRange(externalPort),
    79  					Listen:    net.NewIPOrDomain(net.LocalHostIP),
    80  				}),
    81  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
    82  					Address: net.NewIPOrDomain(dest.Address),
    83  					Port:    uint32(dest.Port),
    84  					NetworkList: &net.NetworkList{
    85  						Network: []net.Network{net.Network_TCP},
    86  					},
    87  				}),
    88  			},
    89  			{
    90  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
    91  					PortRange: net.SinglePortRange(reversePort),
    92  					Listen:    net.NewIPOrDomain(net.LocalHostIP),
    93  				}),
    94  				ProxySettings: serial.ToTypedMessage(&inbound.Config{
    95  					User: []*protocol.User{
    96  						{
    97  							Account: serial.ToTypedMessage(&vmess.Account{
    98  								Id:      userID.String(),
    99  								AlterId: 0,
   100  							}),
   101  						},
   102  					},
   103  				}),
   104  			},
   105  		},
   106  		Outbound: []*core.OutboundHandlerConfig{
   107  			{
   108  				ProxySettings: serial.ToTypedMessage(&blackhole.Config{}),
   109  			},
   110  		},
   111  	}
   112  
   113  	clientPort := tcp.PickPort()
   114  	clientConfig := &core.Config{
   115  		App: []*anypb.Any{
   116  			serial.ToTypedMessage(&reverse.Config{
   117  				BridgeConfig: []*reverse.BridgeConfig{
   118  					{
   119  						Tag:    "bridge",
   120  						Domain: "test.v2fly.org",
   121  					},
   122  				},
   123  			}),
   124  			serial.ToTypedMessage(&router.Config{
   125  				Rule: []*router.RoutingRule{
   126  					{
   127  						Domain: []*routercommon.Domain{
   128  							{Type: routercommon.Domain_Full, Value: "test.v2fly.org"},
   129  						},
   130  						TargetTag: &router.RoutingRule_Tag{
   131  							Tag: "reverse",
   132  						},
   133  					},
   134  					{
   135  						InboundTag: []string{"bridge"},
   136  						TargetTag: &router.RoutingRule_Tag{
   137  							Tag: "freedom",
   138  						},
   139  					},
   140  				},
   141  			}),
   142  		},
   143  		Inbound: []*core.InboundHandlerConfig{
   144  			{
   145  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   146  					PortRange: net.SinglePortRange(clientPort),
   147  					Listen:    net.NewIPOrDomain(net.LocalHostIP),
   148  				}),
   149  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
   150  					Address: net.NewIPOrDomain(dest.Address),
   151  					Port:    uint32(dest.Port),
   152  					NetworkList: &net.NetworkList{
   153  						Network: []net.Network{net.Network_TCP},
   154  					},
   155  				}),
   156  			},
   157  		},
   158  		Outbound: []*core.OutboundHandlerConfig{
   159  			{
   160  				Tag:           "freedom",
   161  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   162  			},
   163  			{
   164  				Tag: "reverse",
   165  				ProxySettings: serial.ToTypedMessage(&outbound.Config{
   166  					Receiver: []*protocol.ServerEndpoint{
   167  						{
   168  							Address: net.NewIPOrDomain(net.LocalHostIP),
   169  							Port:    uint32(reversePort),
   170  							User: []*protocol.User{
   171  								{
   172  									Account: serial.ToTypedMessage(&vmess.Account{
   173  										Id:      userID.String(),
   174  										AlterId: 0,
   175  										SecuritySettings: &protocol.SecurityConfig{
   176  											Type: protocol.SecurityType_AES128_GCM,
   177  										},
   178  									}),
   179  								},
   180  							},
   181  						},
   182  					},
   183  				}),
   184  			},
   185  		},
   186  	}
   187  
   188  	servers, err := InitializeServerConfigs(serverConfig, clientConfig)
   189  	common.Must(err)
   190  
   191  	defer CloseAllServers(servers)
   192  
   193  	var errg errgroup.Group
   194  	for i := 0; i < 32; i++ {
   195  		errg.Go(testTCPConn(externalPort, 10240*1024, time.Second*40))
   196  	}
   197  
   198  	if err := errg.Wait(); err != nil {
   199  		t.Fatal(err)
   200  	}
   201  }
   202  
   203  func TestReverseProxyLongRunning(t *testing.T) {
   204  	tcpServer := tcp.Server{
   205  		MsgProcessor: xor,
   206  	}
   207  	dest, err := tcpServer.Start()
   208  	common.Must(err)
   209  
   210  	defer tcpServer.Close()
   211  
   212  	userID := protocol.NewID(uuid.New())
   213  	externalPort := tcp.PickPort()
   214  	reversePort := tcp.PickPort()
   215  
   216  	serverConfig := &core.Config{
   217  		App: []*anypb.Any{
   218  			serial.ToTypedMessage(&log.Config{
   219  				Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},
   220  			}),
   221  			serial.ToTypedMessage(&policy.Config{
   222  				Level: map[uint32]*policy.Policy{
   223  					0: {
   224  						Timeout: &policy.Policy_Timeout{
   225  							UplinkOnly:   &policy.Second{Value: 0},
   226  							DownlinkOnly: &policy.Second{Value: 0},
   227  						},
   228  					},
   229  				},
   230  			}),
   231  			serial.ToTypedMessage(&reverse.Config{
   232  				PortalConfig: []*reverse.PortalConfig{
   233  					{
   234  						Tag:    "portal",
   235  						Domain: "test.v2fly.org",
   236  					},
   237  				},
   238  			}),
   239  			serial.ToTypedMessage(&router.Config{
   240  				Rule: []*router.RoutingRule{
   241  					{
   242  						Domain: []*routercommon.Domain{
   243  							{Type: routercommon.Domain_Full, Value: "test.v2fly.org"},
   244  						},
   245  						TargetTag: &router.RoutingRule_Tag{
   246  							Tag: "portal",
   247  						},
   248  					},
   249  					{
   250  						InboundTag: []string{"external"},
   251  						TargetTag: &router.RoutingRule_Tag{
   252  							Tag: "portal",
   253  						},
   254  					},
   255  				},
   256  			}),
   257  		},
   258  		Inbound: []*core.InboundHandlerConfig{
   259  			{
   260  				Tag: "external",
   261  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   262  					PortRange: net.SinglePortRange(externalPort),
   263  					Listen:    net.NewIPOrDomain(net.LocalHostIP),
   264  				}),
   265  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
   266  					Address: net.NewIPOrDomain(dest.Address),
   267  					Port:    uint32(dest.Port),
   268  					NetworkList: &net.NetworkList{
   269  						Network: []net.Network{net.Network_TCP},
   270  					},
   271  				}),
   272  			},
   273  			{
   274  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   275  					PortRange: net.SinglePortRange(reversePort),
   276  					Listen:    net.NewIPOrDomain(net.LocalHostIP),
   277  				}),
   278  				ProxySettings: serial.ToTypedMessage(&inbound.Config{
   279  					User: []*protocol.User{
   280  						{
   281  							Account: serial.ToTypedMessage(&vmess.Account{
   282  								Id:      userID.String(),
   283  								AlterId: 0,
   284  							}),
   285  						},
   286  					},
   287  				}),
   288  			},
   289  		},
   290  		Outbound: []*core.OutboundHandlerConfig{
   291  			{
   292  				ProxySettings: serial.ToTypedMessage(&blackhole.Config{}),
   293  			},
   294  		},
   295  	}
   296  
   297  	clientPort := tcp.PickPort()
   298  	clientConfig := &core.Config{
   299  		App: []*anypb.Any{
   300  			serial.ToTypedMessage(&log.Config{
   301  				Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},
   302  			}),
   303  			serial.ToTypedMessage(&policy.Config{
   304  				Level: map[uint32]*policy.Policy{
   305  					0: {
   306  						Timeout: &policy.Policy_Timeout{
   307  							UplinkOnly:   &policy.Second{Value: 0},
   308  							DownlinkOnly: &policy.Second{Value: 0},
   309  						},
   310  					},
   311  				},
   312  			}),
   313  			serial.ToTypedMessage(&reverse.Config{
   314  				BridgeConfig: []*reverse.BridgeConfig{
   315  					{
   316  						Tag:    "bridge",
   317  						Domain: "test.v2fly.org",
   318  					},
   319  				},
   320  			}),
   321  			serial.ToTypedMessage(&router.Config{
   322  				Rule: []*router.RoutingRule{
   323  					{
   324  						Domain: []*routercommon.Domain{
   325  							{Type: routercommon.Domain_Full, Value: "test.v2fly.org"},
   326  						},
   327  						TargetTag: &router.RoutingRule_Tag{
   328  							Tag: "reverse",
   329  						},
   330  					},
   331  					{
   332  						InboundTag: []string{"bridge"},
   333  						TargetTag: &router.RoutingRule_Tag{
   334  							Tag: "freedom",
   335  						},
   336  					},
   337  				},
   338  			}),
   339  		},
   340  		Inbound: []*core.InboundHandlerConfig{
   341  			{
   342  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   343  					PortRange: net.SinglePortRange(clientPort),
   344  					Listen:    net.NewIPOrDomain(net.LocalHostIP),
   345  				}),
   346  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
   347  					Address: net.NewIPOrDomain(dest.Address),
   348  					Port:    uint32(dest.Port),
   349  					NetworkList: &net.NetworkList{
   350  						Network: []net.Network{net.Network_TCP},
   351  					},
   352  				}),
   353  			},
   354  		},
   355  		Outbound: []*core.OutboundHandlerConfig{
   356  			{
   357  				Tag:           "freedom",
   358  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   359  			},
   360  			{
   361  				Tag: "reverse",
   362  				ProxySettings: serial.ToTypedMessage(&outbound.Config{
   363  					Receiver: []*protocol.ServerEndpoint{
   364  						{
   365  							Address: net.NewIPOrDomain(net.LocalHostIP),
   366  							Port:    uint32(reversePort),
   367  							User: []*protocol.User{
   368  								{
   369  									Account: serial.ToTypedMessage(&vmess.Account{
   370  										Id:      userID.String(),
   371  										AlterId: 0,
   372  										SecuritySettings: &protocol.SecurityConfig{
   373  											Type: protocol.SecurityType_AES128_GCM,
   374  										},
   375  									}),
   376  								},
   377  							},
   378  						},
   379  					},
   380  				}),
   381  			},
   382  		},
   383  	}
   384  
   385  	servers, err := InitializeServerConfigs(serverConfig, clientConfig)
   386  	common.Must(err)
   387  
   388  	defer CloseAllServers(servers)
   389  
   390  	for i := 0; i < 4096; i++ {
   391  		if err := testTCPConn(externalPort, 1024, time.Second*20)(); err != nil {
   392  			t.Error(err)
   393  		}
   394  	}
   395  }