github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/testing/scenarios/dokodemo_test.go (about)

     1  package scenarios
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/xmplusdev/xmcore/app/log"
     8  	"github.com/xmplusdev/xmcore/app/proxyman"
     9  	"github.com/xmplusdev/xmcore/common"
    10  	clog "github.com/xmplusdev/xmcore/common/log"
    11  	"github.com/xmplusdev/xmcore/common/net"
    12  	"github.com/xmplusdev/xmcore/common/protocol"
    13  	"github.com/xmplusdev/xmcore/common/serial"
    14  	"github.com/xmplusdev/xmcore/common/uuid"
    15  	"github.com/xmplusdev/xmcore/core"
    16  	"github.com/xmplusdev/xmcore/proxy/dokodemo"
    17  	"github.com/xmplusdev/xmcore/proxy/freedom"
    18  	"github.com/xmplusdev/xmcore/proxy/vmess"
    19  	"github.com/xmplusdev/xmcore/proxy/vmess/inbound"
    20  	"github.com/xmplusdev/xmcore/proxy/vmess/outbound"
    21  	"github.com/xmplusdev/xmcore/testing/servers/tcp"
    22  	"github.com/xmplusdev/xmcore/testing/servers/udp"
    23  	"golang.org/x/sync/errgroup"
    24  )
    25  
    26  func TestDokodemoTCP(t *testing.T) {
    27  	tcpServer := tcp.Server{
    28  		MsgProcessor: xor,
    29  	}
    30  	dest, err := tcpServer.Start()
    31  	common.Must(err)
    32  	defer tcpServer.Close()
    33  
    34  	userID := protocol.NewID(uuid.New())
    35  	serverPort := tcp.PickPort()
    36  	serverConfig := &core.Config{
    37  		App: []*serial.TypedMessage{
    38  			serial.ToTypedMessage(&log.Config{
    39  				ErrorLogLevel: clog.Severity_Debug,
    40  				ErrorLogType:  log.LogType_Console,
    41  			}),
    42  		},
    43  		Inbound: []*core.InboundHandlerConfig{
    44  			{
    45  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
    46  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}},
    47  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
    48  				}),
    49  				ProxySettings: serial.ToTypedMessage(&inbound.Config{
    50  					User: []*protocol.User{
    51  						{
    52  							Account: serial.ToTypedMessage(&vmess.Account{
    53  								Id: userID.String(),
    54  							}),
    55  						},
    56  					},
    57  				}),
    58  			},
    59  		},
    60  		Outbound: []*core.OutboundHandlerConfig{
    61  			{
    62  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
    63  			},
    64  		},
    65  	}
    66  	server, err := InitializeServerConfig(serverConfig)
    67  	common.Must(err)
    68  	defer CloseServer(server)
    69  
    70  	clientPortRange := uint32(5)
    71  	retry := 1
    72  	clientPort := uint32(tcp.PickPort())
    73  	for {
    74  		clientConfig := &core.Config{
    75  			App: []*serial.TypedMessage{
    76  				serial.ToTypedMessage(&log.Config{
    77  					ErrorLogLevel: clog.Severity_Debug,
    78  					ErrorLogType:  log.LogType_Console,
    79  				}),
    80  			},
    81  			Inbound: []*core.InboundHandlerConfig{
    82  				{
    83  					ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
    84  						PortList: &net.PortList{Range: []*net.PortRange{{From: clientPort, To: clientPort + clientPortRange}}},
    85  						Listen:   net.NewIPOrDomain(net.LocalHostIP),
    86  					}),
    87  					ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
    88  						Address: net.NewIPOrDomain(dest.Address),
    89  						Port:    uint32(dest.Port),
    90  						NetworkList: &net.NetworkList{
    91  							Network: []net.Network{net.Network_TCP},
    92  						},
    93  					}),
    94  				},
    95  			},
    96  			Outbound: []*core.OutboundHandlerConfig{
    97  				{
    98  					ProxySettings: serial.ToTypedMessage(&outbound.Config{
    99  						Receiver: []*protocol.ServerEndpoint{
   100  							{
   101  								Address: net.NewIPOrDomain(net.LocalHostIP),
   102  								Port:    uint32(serverPort),
   103  								User: []*protocol.User{
   104  									{
   105  										Account: serial.ToTypedMessage(&vmess.Account{
   106  											Id: userID.String(),
   107  										}),
   108  									},
   109  								},
   110  							},
   111  						},
   112  					}),
   113  				},
   114  			},
   115  		}
   116  
   117  		server, _ := InitializeServerConfig(clientConfig)
   118  		if server != nil && WaitConnAvailableWithTest(t, testTCPConn(net.Port(clientPort), 1024, time.Second*2)) {
   119  			defer CloseServer(server)
   120  			break
   121  		}
   122  		retry++
   123  		if retry > 5 {
   124  			t.Fatal("All attempts failed to start client")
   125  		}
   126  		clientPort = uint32(tcp.PickPort())
   127  	}
   128  
   129  	for port := clientPort; port <= clientPort+clientPortRange; port++ {
   130  		if err := testTCPConn(net.Port(port), 1024, time.Second*2)(); err != nil {
   131  			t.Error(err)
   132  		}
   133  	}
   134  }
   135  
   136  func TestDokodemoUDP(t *testing.T) {
   137  	udpServer := udp.Server{
   138  		MsgProcessor: xor,
   139  	}
   140  	dest, err := udpServer.Start()
   141  	common.Must(err)
   142  	defer udpServer.Close()
   143  
   144  	userID := protocol.NewID(uuid.New())
   145  	serverPort := tcp.PickPort()
   146  	serverConfig := &core.Config{
   147  		Inbound: []*core.InboundHandlerConfig{
   148  			{
   149  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   150  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}},
   151  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   152  				}),
   153  				ProxySettings: serial.ToTypedMessage(&inbound.Config{
   154  					User: []*protocol.User{
   155  						{
   156  							Account: serial.ToTypedMessage(&vmess.Account{
   157  								Id: userID.String(),
   158  							}),
   159  						},
   160  					},
   161  				}),
   162  			},
   163  		},
   164  		Outbound: []*core.OutboundHandlerConfig{
   165  			{
   166  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   167  			},
   168  		},
   169  	}
   170  	server, err := InitializeServerConfig(serverConfig)
   171  	common.Must(err)
   172  	defer CloseServer(server)
   173  
   174  	clientPortRange := uint32(3)
   175  	retry := 1
   176  	clientPort := uint32(udp.PickPort())
   177  	for {
   178  		clientConfig := &core.Config{
   179  			Inbound: []*core.InboundHandlerConfig{
   180  				{
   181  					ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   182  						PortList: &net.PortList{Range: []*net.PortRange{{From: clientPort, To: clientPort + clientPortRange}}},
   183  						Listen:   net.NewIPOrDomain(net.LocalHostIP),
   184  					}),
   185  					ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
   186  						Address: net.NewIPOrDomain(dest.Address),
   187  						Port:    uint32(dest.Port),
   188  						NetworkList: &net.NetworkList{
   189  							Network: []net.Network{net.Network_UDP},
   190  						},
   191  					}),
   192  				},
   193  			},
   194  			Outbound: []*core.OutboundHandlerConfig{
   195  				{
   196  					ProxySettings: serial.ToTypedMessage(&outbound.Config{
   197  						Receiver: []*protocol.ServerEndpoint{
   198  							{
   199  								Address: net.NewIPOrDomain(net.LocalHostIP),
   200  								Port:    uint32(serverPort),
   201  								User: []*protocol.User{
   202  									{
   203  										Account: serial.ToTypedMessage(&vmess.Account{
   204  											Id: userID.String(),
   205  										}),
   206  									},
   207  								},
   208  							},
   209  						},
   210  					}),
   211  				},
   212  			},
   213  		}
   214  
   215  		server, _ := InitializeServerConfig(clientConfig)
   216  		if server != nil && WaitConnAvailableWithTest(t, testUDPConn(net.Port(clientPort), 1024, time.Second*2)) {
   217  			defer CloseServer(server)
   218  			break
   219  		}
   220  		retry++
   221  		if retry > 5 {
   222  			t.Fatal("All attempts failed to start client")
   223  		}
   224  		clientPort = uint32(udp.PickPort())
   225  	}
   226  
   227  	var errg errgroup.Group
   228  	for port := clientPort; port <= clientPort+clientPortRange; port++ {
   229  		errg.Go(testUDPConn(net.Port(port), 1024, time.Second*5))
   230  	}
   231  	if err := errg.Wait(); err != nil {
   232  		t.Error(err)
   233  	}
   234  }