github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/infra/conf/v4/v2ray_test.go (about)

     1  package v4_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/golang/protobuf/proto"
     9  	"google.golang.org/protobuf/types/known/anypb"
    10  
    11  	core "github.com/v2fly/v2ray-core/v5"
    12  	"github.com/v2fly/v2ray-core/v5/app/dispatcher"
    13  	"github.com/v2fly/v2ray-core/v5/app/log"
    14  	"github.com/v2fly/v2ray-core/v5/app/proxyman"
    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/infra/conf/cfgcommon/muxcfg"
    23  	"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist"
    24  	_ "github.com/v2fly/v2ray-core/v5/infra/conf/geodata/memconservative"
    25  	_ "github.com/v2fly/v2ray-core/v5/infra/conf/geodata/standard"
    26  	v4 "github.com/v2fly/v2ray-core/v5/infra/conf/v4"
    27  	"github.com/v2fly/v2ray-core/v5/proxy/blackhole"
    28  	dns_proxy "github.com/v2fly/v2ray-core/v5/proxy/dns"
    29  	"github.com/v2fly/v2ray-core/v5/proxy/freedom"
    30  	"github.com/v2fly/v2ray-core/v5/proxy/vmess"
    31  	"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound"
    32  	"github.com/v2fly/v2ray-core/v5/transport/internet"
    33  	"github.com/v2fly/v2ray-core/v5/transport/internet/http"
    34  	"github.com/v2fly/v2ray-core/v5/transport/internet/tls"
    35  	"github.com/v2fly/v2ray-core/v5/transport/internet/websocket"
    36  )
    37  
    38  func TestV2RayConfig(t *testing.T) {
    39  	createParser := func() func(string) (proto.Message, error) {
    40  		return func(s string) (proto.Message, error) {
    41  			config := new(v4.Config)
    42  			if err := json.Unmarshal([]byte(s), config); err != nil {
    43  				return nil, err
    44  			}
    45  			return config.Build()
    46  		}
    47  	}
    48  
    49  	testassist.RunMultiTestCase(t, []testassist.TestCase{
    50  		{
    51  			Input: `{
    52  				"outbound": {
    53  					"protocol": "freedom",
    54  					"settings": {}
    55  				},
    56  				"log": {
    57  					"access": "/var/log/v2ray/access.log",
    58  					"loglevel": "error",
    59  					"error": "/var/log/v2ray/error.log"
    60  				},
    61  				"inbound": {
    62  					"streamSettings": {
    63  						"network": "ws",
    64  						"wsSettings": {
    65  							"headers": {
    66  								"host": "example.domain"
    67  							},
    68  							"path": ""
    69  						},
    70  						"tlsSettings": {
    71  							"alpn": "h2"
    72  						},
    73  						"security": "tls"
    74  					},
    75  					"protocol": "vmess",
    76  					"port": 443,
    77  					"settings": {
    78  						"clients": [
    79  							{
    80  								"alterId": 100,
    81  								"security": "aes-128-gcm",
    82  								"id": "0cdf8a45-303d-4fed-9780-29aa7f54175e"
    83  							}
    84  						]
    85  					}
    86  				},
    87  				"inbounds": [{
    88  					"streamSettings": {
    89  						"network": "ws",
    90  						"wsSettings": {
    91  							"headers": {
    92  								"host": "example.domain"
    93  							},
    94  							"path": ""
    95  						},
    96  						"tlsSettings": {
    97  							"alpn": "h2"
    98  						},
    99  						"security": "tls"
   100  					},
   101  					"protocol": "vmess",
   102  					"port": "443-500",
   103  					"allocate": {
   104  						"strategy": "random",
   105  						"concurrency": 3
   106  					},
   107  					"settings": {
   108  						"clients": [
   109  							{
   110  								"alterId": 100,
   111  								"security": "aes-128-gcm",
   112  								"id": "0cdf8a45-303d-4fed-9780-29aa7f54175e"
   113  							}
   114  						]
   115  					}
   116  				}],
   117  				"outboundDetour": [
   118  					{
   119  						"tag": "blocked",
   120  						"protocol": "blackhole"
   121  					},
   122  					{
   123  						"protocol": "dns"
   124  					}
   125  				],
   126  				"routing": {
   127  					"strategy": "rules",
   128  					"settings": {
   129  						"rules": [
   130  							{
   131  								"ip": [
   132  									"10.0.0.0/8"
   133  								],
   134  								"type": "field",
   135  								"outboundTag": "blocked"
   136  							}
   137  						]
   138  					}
   139  				},
   140  				"transport": {
   141  					"httpSettings": {
   142  						"path": "/test"
   143  					}
   144  				}
   145  			}`,
   146  			Parser: createParser(),
   147  			Output: &core.Config{
   148  				App: []*anypb.Any{
   149  					serial.ToTypedMessage(&log.Config{
   150  						Error: &log.LogSpecification{
   151  							Type:  log.LogType_File,
   152  							Level: clog.Severity_Error,
   153  							Path:  "/var/log/v2ray/error.log",
   154  						},
   155  						Access: &log.LogSpecification{
   156  							Type: log.LogType_File,
   157  							Path: "/var/log/v2ray/access.log",
   158  						},
   159  					}),
   160  					serial.ToTypedMessage(&dispatcher.Config{}),
   161  					serial.ToTypedMessage(&proxyman.InboundConfig{}),
   162  					serial.ToTypedMessage(&proxyman.OutboundConfig{}),
   163  					serial.ToTypedMessage(&router.Config{
   164  						DomainStrategy: router.DomainStrategy_AsIs,
   165  						Rule: []*router.RoutingRule{
   166  							{
   167  								Geoip: []*routercommon.GeoIP{
   168  									{
   169  										Cidr: []*routercommon.CIDR{
   170  											{
   171  												Ip:     []byte{10, 0, 0, 0},
   172  												Prefix: 8,
   173  											},
   174  										},
   175  									},
   176  								},
   177  								TargetTag: &router.RoutingRule_Tag{
   178  									Tag: "blocked",
   179  								},
   180  							},
   181  						},
   182  					}),
   183  				},
   184  				Outbound: []*core.OutboundHandlerConfig{
   185  					{
   186  						SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
   187  							StreamSettings: &internet.StreamConfig{
   188  								ProtocolName: "tcp",
   189  								TransportSettings: []*internet.TransportConfig{
   190  									{
   191  										ProtocolName: "http",
   192  										Settings: serial.ToTypedMessage(&http.Config{
   193  											Path: "/test",
   194  										}),
   195  									},
   196  								},
   197  							},
   198  						}),
   199  						ProxySettings: serial.ToTypedMessage(&freedom.Config{
   200  							DomainStrategy: freedom.Config_AS_IS,
   201  							UserLevel:      0,
   202  						}),
   203  					},
   204  					{
   205  						Tag: "blocked",
   206  						SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
   207  							StreamSettings: &internet.StreamConfig{
   208  								ProtocolName: "tcp",
   209  								TransportSettings: []*internet.TransportConfig{
   210  									{
   211  										ProtocolName: "http",
   212  										Settings: serial.ToTypedMessage(&http.Config{
   213  											Path: "/test",
   214  										}),
   215  									},
   216  								},
   217  							},
   218  						}),
   219  						ProxySettings: serial.ToTypedMessage(&blackhole.Config{}),
   220  					},
   221  					{
   222  						SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
   223  							StreamSettings: &internet.StreamConfig{
   224  								ProtocolName: "tcp",
   225  								TransportSettings: []*internet.TransportConfig{
   226  									{
   227  										ProtocolName: "http",
   228  										Settings: serial.ToTypedMessage(&http.Config{
   229  											Path: "/test",
   230  										}),
   231  									},
   232  								},
   233  							},
   234  						}),
   235  						ProxySettings: serial.ToTypedMessage(&dns_proxy.Config{
   236  							Server: &net.Endpoint{},
   237  						}),
   238  					},
   239  				},
   240  				Inbound: []*core.InboundHandlerConfig{
   241  					{
   242  						ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   243  							PortRange: &net.PortRange{
   244  								From: 443,
   245  								To:   443,
   246  							},
   247  							StreamSettings: &internet.StreamConfig{
   248  								ProtocolName: "websocket",
   249  								TransportSettings: []*internet.TransportConfig{
   250  									{
   251  										ProtocolName: "websocket",
   252  										Settings: serial.ToTypedMessage(&websocket.Config{
   253  											Header: []*websocket.Header{
   254  												{
   255  													Key:   "host",
   256  													Value: "example.domain",
   257  												},
   258  											},
   259  										}),
   260  									},
   261  									{
   262  										ProtocolName: "http",
   263  										Settings: serial.ToTypedMessage(&http.Config{
   264  											Path: "/test",
   265  										}),
   266  									},
   267  								},
   268  								SecurityType: "v2ray.core.transport.internet.tls.Config",
   269  								SecuritySettings: []*anypb.Any{
   270  									serial.ToTypedMessage(&tls.Config{
   271  										NextProtocol: []string{"h2"},
   272  									}),
   273  								},
   274  							},
   275  						}),
   276  						ProxySettings: serial.ToTypedMessage(&inbound.Config{
   277  							User: []*protocol.User{
   278  								{
   279  									Level: 0,
   280  									Account: serial.ToTypedMessage(&vmess.Account{
   281  										Id:      "0cdf8a45-303d-4fed-9780-29aa7f54175e",
   282  										AlterId: 100,
   283  										SecuritySettings: &protocol.SecurityConfig{
   284  											Type: protocol.SecurityType_AES128_GCM,
   285  										},
   286  									}),
   287  								},
   288  							},
   289  						}),
   290  					},
   291  					{
   292  						ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   293  							PortRange: &net.PortRange{
   294  								From: 443,
   295  								To:   500,
   296  							},
   297  							AllocationStrategy: &proxyman.AllocationStrategy{
   298  								Type: proxyman.AllocationStrategy_Random,
   299  								Concurrency: &proxyman.AllocationStrategy_AllocationStrategyConcurrency{
   300  									Value: 3,
   301  								},
   302  							},
   303  							StreamSettings: &internet.StreamConfig{
   304  								ProtocolName: "websocket",
   305  								TransportSettings: []*internet.TransportConfig{
   306  									{
   307  										ProtocolName: "websocket",
   308  										Settings: serial.ToTypedMessage(&websocket.Config{
   309  											Header: []*websocket.Header{
   310  												{
   311  													Key:   "host",
   312  													Value: "example.domain",
   313  												},
   314  											},
   315  										}),
   316  									},
   317  									{
   318  										ProtocolName: "http",
   319  										Settings: serial.ToTypedMessage(&http.Config{
   320  											Path: "/test",
   321  										}),
   322  									},
   323  								},
   324  								SecurityType: "v2ray.core.transport.internet.tls.Config",
   325  								SecuritySettings: []*anypb.Any{
   326  									serial.ToTypedMessage(&tls.Config{
   327  										NextProtocol: []string{"h2"},
   328  									}),
   329  								},
   330  							},
   331  						}),
   332  						ProxySettings: serial.ToTypedMessage(&inbound.Config{
   333  							User: []*protocol.User{
   334  								{
   335  									Level: 0,
   336  									Account: serial.ToTypedMessage(&vmess.Account{
   337  										Id:      "0cdf8a45-303d-4fed-9780-29aa7f54175e",
   338  										AlterId: 100,
   339  										SecuritySettings: &protocol.SecurityConfig{
   340  											Type: protocol.SecurityType_AES128_GCM,
   341  										},
   342  									}),
   343  								},
   344  							},
   345  						}),
   346  					},
   347  				},
   348  			},
   349  		},
   350  	})
   351  }
   352  
   353  func TestMuxConfig_Build(t *testing.T) {
   354  	tests := []struct {
   355  		name   string
   356  		fields string
   357  		want   *proxyman.MultiplexingConfig
   358  	}{
   359  		{"default", `{"enabled": true, "concurrency": 16}`, &proxyman.MultiplexingConfig{
   360  			Enabled:     true,
   361  			Concurrency: 16,
   362  		}},
   363  		{"empty def", `{}`, &proxyman.MultiplexingConfig{
   364  			Enabled:     false,
   365  			Concurrency: 8,
   366  		}},
   367  		{"not enable", `{"enabled": false, "concurrency": 4}`, &proxyman.MultiplexingConfig{
   368  			Enabled:     false,
   369  			Concurrency: 4,
   370  		}},
   371  		{"forbidden", `{"enabled": false, "concurrency": -1}`, nil},
   372  	}
   373  	for _, tt := range tests {
   374  		t.Run(tt.name, func(t *testing.T) {
   375  			m := &muxcfg.MuxConfig{}
   376  			common.Must(json.Unmarshal([]byte(tt.fields), m))
   377  			if got := m.Build(); !reflect.DeepEqual(got, tt.want) {
   378  				t.Errorf("MuxConfig.Build() = %v, want %v", got, tt.want)
   379  			}
   380  		})
   381  	}
   382  }