github.com/moqsien/xraycore@v1.8.5/testing/scenarios/feature_test.go (about)

     1  package scenarios
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  	"net/http"
     7  	"net/url"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/moqsien/xraycore/app/dispatcher"
    12  	"github.com/moqsien/xraycore/app/log"
    13  	"github.com/moqsien/xraycore/app/proxyman"
    14  	_ "github.com/moqsien/xraycore/app/proxyman/inbound"
    15  	_ "github.com/moqsien/xraycore/app/proxyman/outbound"
    16  	"github.com/moqsien/xraycore/app/router"
    17  	"github.com/moqsien/xraycore/common"
    18  	clog "github.com/moqsien/xraycore/common/log"
    19  	"github.com/moqsien/xraycore/common/net"
    20  	"github.com/moqsien/xraycore/common/protocol"
    21  	"github.com/moqsien/xraycore/common/serial"
    22  	"github.com/moqsien/xraycore/common/uuid"
    23  	core "github.com/moqsien/xraycore/core"
    24  	"github.com/moqsien/xraycore/proxy/blackhole"
    25  	"github.com/moqsien/xraycore/proxy/dokodemo"
    26  	"github.com/moqsien/xraycore/proxy/freedom"
    27  	v2http "github.com/moqsien/xraycore/proxy/http"
    28  	"github.com/moqsien/xraycore/proxy/socks"
    29  	"github.com/moqsien/xraycore/proxy/vmess"
    30  	"github.com/moqsien/xraycore/proxy/vmess/inbound"
    31  	"github.com/moqsien/xraycore/proxy/vmess/outbound"
    32  	"github.com/moqsien/xraycore/testing/servers/tcp"
    33  	"github.com/moqsien/xraycore/testing/servers/udp"
    34  	"github.com/moqsien/xraycore/transport/internet"
    35  	xproxy "golang.org/x/net/proxy"
    36  )
    37  
    38  func TestPassiveConnection(t *testing.T) {
    39  	tcpServer := tcp.Server{
    40  		MsgProcessor: xor,
    41  		SendFirst:    []byte("send first"),
    42  	}
    43  	dest, err := tcpServer.Start()
    44  	common.Must(err)
    45  	defer tcpServer.Close()
    46  
    47  	serverPort := tcp.PickPort()
    48  	serverConfig := &core.Config{
    49  		Inbound: []*core.InboundHandlerConfig{
    50  			{
    51  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
    52  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}},
    53  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
    54  				}),
    55  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
    56  					Address: net.NewIPOrDomain(dest.Address),
    57  					Port:    uint32(dest.Port),
    58  					NetworkList: &net.NetworkList{
    59  						Network: []net.Network{net.Network_TCP},
    60  					},
    61  				}),
    62  			},
    63  		},
    64  		Outbound: []*core.OutboundHandlerConfig{
    65  			{
    66  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
    67  			},
    68  		},
    69  	}
    70  
    71  	servers, err := InitializeServerConfigs(serverConfig)
    72  	common.Must(err)
    73  	defer CloseAllServers(servers)
    74  
    75  	conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
    76  		IP:   []byte{127, 0, 0, 1},
    77  		Port: int(serverPort),
    78  	})
    79  	common.Must(err)
    80  
    81  	{
    82  		response := make([]byte, 1024)
    83  		nBytes, err := conn.Read(response)
    84  		common.Must(err)
    85  		if string(response[:nBytes]) != "send first" {
    86  			t.Error("unexpected first response: ", string(response[:nBytes]))
    87  		}
    88  	}
    89  
    90  	if err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil {
    91  		t.Error(err)
    92  	}
    93  }
    94  
    95  func TestProxy(t *testing.T) {
    96  	tcpServer := tcp.Server{
    97  		MsgProcessor: xor,
    98  	}
    99  	dest, err := tcpServer.Start()
   100  	common.Must(err)
   101  	defer tcpServer.Close()
   102  
   103  	serverUserID := protocol.NewID(uuid.New())
   104  	serverPort := tcp.PickPort()
   105  	serverConfig := &core.Config{
   106  		Inbound: []*core.InboundHandlerConfig{
   107  			{
   108  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   109  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}},
   110  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   111  				}),
   112  				ProxySettings: serial.ToTypedMessage(&inbound.Config{
   113  					User: []*protocol.User{
   114  						{
   115  							Account: serial.ToTypedMessage(&vmess.Account{
   116  								Id: serverUserID.String(),
   117  							}),
   118  						},
   119  					},
   120  				}),
   121  			},
   122  		},
   123  		Outbound: []*core.OutboundHandlerConfig{
   124  			{
   125  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   126  			},
   127  		},
   128  	}
   129  
   130  	proxyUserID := protocol.NewID(uuid.New())
   131  	proxyPort := tcp.PickPort()
   132  	proxyConfig := &core.Config{
   133  		Inbound: []*core.InboundHandlerConfig{
   134  			{
   135  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   136  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(proxyPort)}},
   137  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   138  				}),
   139  				ProxySettings: serial.ToTypedMessage(&inbound.Config{
   140  					User: []*protocol.User{
   141  						{
   142  							Account: serial.ToTypedMessage(&vmess.Account{
   143  								Id: proxyUserID.String(),
   144  							}),
   145  						},
   146  					},
   147  				}),
   148  			},
   149  		},
   150  		Outbound: []*core.OutboundHandlerConfig{
   151  			{
   152  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   153  			},
   154  		},
   155  	}
   156  
   157  	clientPort := tcp.PickPort()
   158  	clientConfig := &core.Config{
   159  		Inbound: []*core.InboundHandlerConfig{
   160  			{
   161  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   162  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(clientPort)}},
   163  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   164  				}),
   165  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
   166  					Address: net.NewIPOrDomain(dest.Address),
   167  					Port:    uint32(dest.Port),
   168  					NetworkList: &net.NetworkList{
   169  						Network: []net.Network{net.Network_TCP},
   170  					},
   171  				}),
   172  			},
   173  		},
   174  		Outbound: []*core.OutboundHandlerConfig{
   175  			{
   176  				ProxySettings: serial.ToTypedMessage(&outbound.Config{
   177  					Receiver: []*protocol.ServerEndpoint{
   178  						{
   179  							Address: net.NewIPOrDomain(net.LocalHostIP),
   180  							Port:    uint32(serverPort),
   181  							User: []*protocol.User{
   182  								{
   183  									Account: serial.ToTypedMessage(&vmess.Account{
   184  										Id: serverUserID.String(),
   185  									}),
   186  								},
   187  							},
   188  						},
   189  					},
   190  				}),
   191  				SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
   192  					ProxySettings: &internet.ProxyConfig{
   193  						Tag: "proxy",
   194  					},
   195  				}),
   196  			},
   197  			{
   198  				Tag: "proxy",
   199  				ProxySettings: serial.ToTypedMessage(&outbound.Config{
   200  					Receiver: []*protocol.ServerEndpoint{
   201  						{
   202  							Address: net.NewIPOrDomain(net.LocalHostIP),
   203  							Port:    uint32(proxyPort),
   204  							User: []*protocol.User{
   205  								{
   206  									Account: serial.ToTypedMessage(&vmess.Account{
   207  										Id: proxyUserID.String(),
   208  									}),
   209  								},
   210  							},
   211  						},
   212  					},
   213  				}),
   214  			},
   215  		},
   216  	}
   217  
   218  	servers, err := InitializeServerConfigs(serverConfig, proxyConfig, clientConfig)
   219  	common.Must(err)
   220  	defer CloseAllServers(servers)
   221  
   222  	if err := testTCPConn(clientPort, 1024, time.Second*5)(); err != nil {
   223  		t.Error(err)
   224  	}
   225  }
   226  
   227  func TestProxyOverKCP(t *testing.T) {
   228  	tcpServer := tcp.Server{
   229  		MsgProcessor: xor,
   230  	}
   231  	dest, err := tcpServer.Start()
   232  	common.Must(err)
   233  	defer tcpServer.Close()
   234  
   235  	serverUserID := protocol.NewID(uuid.New())
   236  	serverPort := udp.PickPort()
   237  	serverConfig := &core.Config{
   238  		Inbound: []*core.InboundHandlerConfig{
   239  			{
   240  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   241  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}},
   242  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   243  					StreamSettings: &internet.StreamConfig{
   244  						Protocol: internet.TransportProtocol_MKCP,
   245  					},
   246  				}),
   247  				ProxySettings: serial.ToTypedMessage(&inbound.Config{
   248  					User: []*protocol.User{
   249  						{
   250  							Account: serial.ToTypedMessage(&vmess.Account{
   251  								Id: serverUserID.String(),
   252  							}),
   253  						},
   254  					},
   255  				}),
   256  			},
   257  		},
   258  		Outbound: []*core.OutboundHandlerConfig{
   259  			{
   260  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   261  			},
   262  		},
   263  	}
   264  
   265  	proxyUserID := protocol.NewID(uuid.New())
   266  	proxyPort := tcp.PickPort()
   267  	proxyConfig := &core.Config{
   268  		Inbound: []*core.InboundHandlerConfig{
   269  			{
   270  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   271  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(proxyPort)}},
   272  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   273  				}),
   274  				ProxySettings: serial.ToTypedMessage(&inbound.Config{
   275  					User: []*protocol.User{
   276  						{
   277  							Account: serial.ToTypedMessage(&vmess.Account{
   278  								Id: proxyUserID.String(),
   279  							}),
   280  						},
   281  					},
   282  				}),
   283  			},
   284  		},
   285  		Outbound: []*core.OutboundHandlerConfig{
   286  			{
   287  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   288  				SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
   289  					StreamSettings: &internet.StreamConfig{
   290  						Protocol: internet.TransportProtocol_MKCP,
   291  					},
   292  				}),
   293  			},
   294  		},
   295  	}
   296  
   297  	clientPort := tcp.PickPort()
   298  	clientConfig := &core.Config{
   299  		Inbound: []*core.InboundHandlerConfig{
   300  			{
   301  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   302  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(clientPort)}},
   303  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   304  				}),
   305  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
   306  					Address: net.NewIPOrDomain(dest.Address),
   307  					Port:    uint32(dest.Port),
   308  					NetworkList: &net.NetworkList{
   309  						Network: []net.Network{net.Network_TCP},
   310  					},
   311  				}),
   312  			},
   313  		},
   314  		Outbound: []*core.OutboundHandlerConfig{
   315  			{
   316  				ProxySettings: serial.ToTypedMessage(&outbound.Config{
   317  					Receiver: []*protocol.ServerEndpoint{
   318  						{
   319  							Address: net.NewIPOrDomain(net.LocalHostIP),
   320  							Port:    uint32(serverPort),
   321  							User: []*protocol.User{
   322  								{
   323  									Account: serial.ToTypedMessage(&vmess.Account{
   324  										Id: serverUserID.String(),
   325  									}),
   326  								},
   327  							},
   328  						},
   329  					},
   330  				}),
   331  				SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
   332  					ProxySettings: &internet.ProxyConfig{
   333  						Tag: "proxy",
   334  					},
   335  					StreamSettings: &internet.StreamConfig{
   336  						Protocol: internet.TransportProtocol_MKCP,
   337  					},
   338  				}),
   339  			},
   340  			{
   341  				Tag: "proxy",
   342  				ProxySettings: serial.ToTypedMessage(&outbound.Config{
   343  					Receiver: []*protocol.ServerEndpoint{
   344  						{
   345  							Address: net.NewIPOrDomain(net.LocalHostIP),
   346  							Port:    uint32(proxyPort),
   347  							User: []*protocol.User{
   348  								{
   349  									Account: serial.ToTypedMessage(&vmess.Account{
   350  										Id: proxyUserID.String(),
   351  									}),
   352  								},
   353  							},
   354  						},
   355  					},
   356  				}),
   357  			},
   358  		},
   359  	}
   360  
   361  	servers, err := InitializeServerConfigs(serverConfig, proxyConfig, clientConfig)
   362  	common.Must(err)
   363  	defer CloseAllServers(servers)
   364  
   365  	if err := testTCPConn(clientPort, 1024, time.Second*5)(); err != nil {
   366  		t.Error(err)
   367  	}
   368  }
   369  
   370  func TestBlackhole(t *testing.T) {
   371  	tcpServer := tcp.Server{
   372  		MsgProcessor: xor,
   373  	}
   374  	dest, err := tcpServer.Start()
   375  	common.Must(err)
   376  	defer tcpServer.Close()
   377  
   378  	tcpServer2 := tcp.Server{
   379  		MsgProcessor: xor,
   380  	}
   381  	dest2, err := tcpServer2.Start()
   382  	common.Must(err)
   383  	defer tcpServer2.Close()
   384  
   385  	serverPort := tcp.PickPort()
   386  	serverPort2 := tcp.PickPort()
   387  	serverConfig := &core.Config{
   388  		Inbound: []*core.InboundHandlerConfig{
   389  			{
   390  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   391  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}},
   392  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   393  				}),
   394  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
   395  					Address: net.NewIPOrDomain(dest.Address),
   396  					Port:    uint32(dest.Port),
   397  					NetworkList: &net.NetworkList{
   398  						Network: []net.Network{net.Network_TCP},
   399  					},
   400  				}),
   401  			},
   402  			{
   403  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   404  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort2)}},
   405  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   406  				}),
   407  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
   408  					Address: net.NewIPOrDomain(dest2.Address),
   409  					Port:    uint32(dest2.Port),
   410  					NetworkList: &net.NetworkList{
   411  						Network: []net.Network{net.Network_TCP},
   412  					},
   413  				}),
   414  			},
   415  		},
   416  		Outbound: []*core.OutboundHandlerConfig{
   417  			{
   418  				Tag:           "direct",
   419  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   420  			},
   421  			{
   422  				Tag:           "blocked",
   423  				ProxySettings: serial.ToTypedMessage(&blackhole.Config{}),
   424  			},
   425  		},
   426  		App: []*serial.TypedMessage{
   427  			serial.ToTypedMessage(&router.Config{
   428  				Rule: []*router.RoutingRule{
   429  					{
   430  						TargetTag: &router.RoutingRule_Tag{
   431  							Tag: "blocked",
   432  						},
   433  						PortRange: net.SinglePortRange(dest2.Port),
   434  					},
   435  				},
   436  			}),
   437  		},
   438  	}
   439  
   440  	servers, err := InitializeServerConfigs(serverConfig)
   441  	common.Must(err)
   442  	defer CloseAllServers(servers)
   443  
   444  	if err := testTCPConn(serverPort2, 1024, time.Second*5)(); err == nil {
   445  		t.Error("nil error")
   446  	}
   447  }
   448  
   449  func TestForward(t *testing.T) {
   450  	tcpServer := tcp.Server{
   451  		MsgProcessor: xor,
   452  	}
   453  	dest, err := tcpServer.Start()
   454  	common.Must(err)
   455  	defer tcpServer.Close()
   456  
   457  	serverPort := tcp.PickPort()
   458  	serverConfig := &core.Config{
   459  		Inbound: []*core.InboundHandlerConfig{
   460  			{
   461  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   462  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}},
   463  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   464  				}),
   465  				ProxySettings: serial.ToTypedMessage(&socks.ServerConfig{
   466  					AuthType: socks.AuthType_NO_AUTH,
   467  					Accounts: map[string]string{
   468  						"Test Account": "Test Password",
   469  					},
   470  					Address:    net.NewIPOrDomain(net.LocalHostIP),
   471  					UdpEnabled: false,
   472  				}),
   473  			},
   474  		},
   475  		Outbound: []*core.OutboundHandlerConfig{
   476  			{
   477  				ProxySettings: serial.ToTypedMessage(&freedom.Config{
   478  					DestinationOverride: &freedom.DestinationOverride{
   479  						Server: &protocol.ServerEndpoint{
   480  							Address: net.NewIPOrDomain(net.LocalHostIP),
   481  							Port:    uint32(dest.Port),
   482  						},
   483  					},
   484  				}),
   485  			},
   486  		},
   487  	}
   488  
   489  	servers, err := InitializeServerConfigs(serverConfig)
   490  	common.Must(err)
   491  	defer CloseAllServers(servers)
   492  
   493  	{
   494  		noAuthDialer, err := xproxy.SOCKS5("tcp", net.TCPDestination(net.LocalHostIP, serverPort).NetAddr(), nil, xproxy.Direct)
   495  		common.Must(err)
   496  		conn, err := noAuthDialer.Dial("tcp", "google.com:80")
   497  		common.Must(err)
   498  		defer conn.Close()
   499  
   500  		if err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil {
   501  			t.Error(err)
   502  		}
   503  	}
   504  }
   505  
   506  func TestUDPConnection(t *testing.T) {
   507  	udpServer := udp.Server{
   508  		MsgProcessor: xor,
   509  	}
   510  	dest, err := udpServer.Start()
   511  	common.Must(err)
   512  	defer udpServer.Close()
   513  
   514  	clientPort := udp.PickPort()
   515  	clientConfig := &core.Config{
   516  		Inbound: []*core.InboundHandlerConfig{
   517  			{
   518  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   519  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(clientPort)}},
   520  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   521  				}),
   522  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
   523  					Address: net.NewIPOrDomain(dest.Address),
   524  					Port:    uint32(dest.Port),
   525  					NetworkList: &net.NetworkList{
   526  						Network: []net.Network{net.Network_UDP},
   527  					},
   528  				}),
   529  			},
   530  		},
   531  		Outbound: []*core.OutboundHandlerConfig{
   532  			{
   533  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   534  			},
   535  		},
   536  	}
   537  
   538  	servers, err := InitializeServerConfigs(clientConfig)
   539  	common.Must(err)
   540  	defer CloseAllServers(servers)
   541  
   542  	if err := testUDPConn(clientPort, 1024, time.Second*5)(); err != nil {
   543  		t.Error(err)
   544  	}
   545  
   546  	time.Sleep(20 * time.Second)
   547  
   548  	if err := testUDPConn(clientPort, 1024, time.Second*5)(); err != nil {
   549  		t.Error(err)
   550  	}
   551  }
   552  
   553  func TestDomainSniffing(t *testing.T) {
   554  	sniffingPort := tcp.PickPort()
   555  	httpPort := tcp.PickPort()
   556  	serverConfig := &core.Config{
   557  		Inbound: []*core.InboundHandlerConfig{
   558  			{
   559  				Tag: "snif",
   560  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   561  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(sniffingPort)}},
   562  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   563  					DomainOverride: []proxyman.KnownProtocols{
   564  						proxyman.KnownProtocols_TLS,
   565  					},
   566  				}),
   567  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
   568  					Address: net.NewIPOrDomain(net.LocalHostIP),
   569  					Port:    443,
   570  					NetworkList: &net.NetworkList{
   571  						Network: []net.Network{net.Network_TCP},
   572  					},
   573  				}),
   574  			},
   575  			{
   576  				Tag: "http",
   577  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   578  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(httpPort)}},
   579  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   580  				}),
   581  				ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
   582  			},
   583  		},
   584  		Outbound: []*core.OutboundHandlerConfig{
   585  			{
   586  				Tag: "redir",
   587  				ProxySettings: serial.ToTypedMessage(&freedom.Config{
   588  					DestinationOverride: &freedom.DestinationOverride{
   589  						Server: &protocol.ServerEndpoint{
   590  							Address: net.NewIPOrDomain(net.LocalHostIP),
   591  							Port:    uint32(sniffingPort),
   592  						},
   593  					},
   594  				}),
   595  			},
   596  			{
   597  				Tag:           "direct",
   598  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   599  			},
   600  		},
   601  		App: []*serial.TypedMessage{
   602  			serial.ToTypedMessage(&router.Config{
   603  				Rule: []*router.RoutingRule{
   604  					{
   605  						TargetTag: &router.RoutingRule_Tag{
   606  							Tag: "direct",
   607  						},
   608  						InboundTag: []string{"snif"},
   609  					}, {
   610  						TargetTag: &router.RoutingRule_Tag{
   611  							Tag: "redir",
   612  						},
   613  						InboundTag: []string{"http"},
   614  					},
   615  				},
   616  			}),
   617  			serial.ToTypedMessage(&log.Config{
   618  				ErrorLogLevel: clog.Severity_Debug,
   619  				ErrorLogType:  log.LogType_Console,
   620  			}),
   621  		},
   622  	}
   623  
   624  	servers, err := InitializeServerConfigs(serverConfig)
   625  	common.Must(err)
   626  	defer CloseAllServers(servers)
   627  
   628  	{
   629  		transport := &http.Transport{
   630  			Proxy: func(req *http.Request) (*url.URL, error) {
   631  				return url.Parse("http://127.0.0.1:" + httpPort.String())
   632  			},
   633  		}
   634  
   635  		client := &http.Client{
   636  			Transport: transport,
   637  		}
   638  
   639  		resp, err := client.Get("https://www.github.com/")
   640  		common.Must(err)
   641  		if resp.StatusCode != 200 {
   642  			t.Error("unexpected status code: ", resp.StatusCode)
   643  		}
   644  		common.Must(resp.Write(io.Discard))
   645  	}
   646  }
   647  
   648  func TestDialXray(t *testing.T) {
   649  	tcpServer := tcp.Server{
   650  		MsgProcessor: xor,
   651  	}
   652  	dest, err := tcpServer.Start()
   653  	common.Must(err)
   654  	defer tcpServer.Close()
   655  
   656  	userID := protocol.NewID(uuid.New())
   657  	serverPort := tcp.PickPort()
   658  	serverConfig := &core.Config{
   659  		App: []*serial.TypedMessage{
   660  			serial.ToTypedMessage(&log.Config{
   661  				ErrorLogLevel: clog.Severity_Debug,
   662  				ErrorLogType:  log.LogType_Console,
   663  			}),
   664  		},
   665  		Inbound: []*core.InboundHandlerConfig{
   666  			{
   667  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   668  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}},
   669  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
   670  				}),
   671  				ProxySettings: serial.ToTypedMessage(&inbound.Config{
   672  					User: []*protocol.User{
   673  						{
   674  							Account: serial.ToTypedMessage(&vmess.Account{
   675  								Id: userID.String(),
   676  							}),
   677  						},
   678  					},
   679  				}),
   680  			},
   681  		},
   682  		Outbound: []*core.OutboundHandlerConfig{
   683  			{
   684  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   685  			},
   686  		},
   687  	}
   688  
   689  	clientConfig := &core.Config{
   690  		App: []*serial.TypedMessage{
   691  			serial.ToTypedMessage(&dispatcher.Config{}),
   692  			serial.ToTypedMessage(&proxyman.InboundConfig{}),
   693  			serial.ToTypedMessage(&proxyman.OutboundConfig{}),
   694  		},
   695  		Inbound: []*core.InboundHandlerConfig{},
   696  		Outbound: []*core.OutboundHandlerConfig{
   697  			{
   698  				ProxySettings: serial.ToTypedMessage(&outbound.Config{
   699  					Receiver: []*protocol.ServerEndpoint{
   700  						{
   701  							Address: net.NewIPOrDomain(net.LocalHostIP),
   702  							Port:    uint32(serverPort),
   703  							User: []*protocol.User{
   704  								{
   705  									Account: serial.ToTypedMessage(&vmess.Account{
   706  										Id: userID.String(),
   707  										SecuritySettings: &protocol.SecurityConfig{
   708  											Type: protocol.SecurityType_AES128_GCM,
   709  										},
   710  									}),
   711  								},
   712  							},
   713  						},
   714  					},
   715  				}),
   716  			},
   717  		},
   718  	}
   719  
   720  	servers, err := InitializeServerConfigs(serverConfig)
   721  	common.Must(err)
   722  	defer CloseAllServers(servers)
   723  
   724  	client, err := core.New(clientConfig)
   725  	common.Must(err)
   726  
   727  	conn, err := core.Dial(context.Background(), client, dest)
   728  	common.Must(err)
   729  	defer conn.Close()
   730  
   731  	if err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil {
   732  		t.Error(err)
   733  	}
   734  }