github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/infra/conf/router_test.go (about)

     1  package conf_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  	"time"
     9  	_ "unsafe"
    10  
    11  	"github.com/xtls/xray-core/app/router"
    12  	"github.com/xtls/xray-core/common"
    13  	"github.com/xtls/xray-core/common/net"
    14  	"github.com/xtls/xray-core/common/platform"
    15  	"github.com/xtls/xray-core/common/platform/filesystem"
    16  	"github.com/xtls/xray-core/common/serial"
    17  	. "github.com/xtls/xray-core/infra/conf"
    18  	"google.golang.org/protobuf/proto"
    19  )
    20  
    21  func init() {
    22  	wd, err := os.Getwd()
    23  	common.Must(err)
    24  
    25  	if _, err := os.Stat(platform.GetAssetLocation("geoip.dat")); err != nil && os.IsNotExist(err) {
    26  		common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(wd, "..", "..", "resources", "geoip.dat")))
    27  	}
    28  
    29  	os.Setenv("xray.location.asset", wd)
    30  }
    31  
    32  func TestToCidrList(t *testing.T) {
    33  	t.Log(os.Getenv("xray.location.asset"))
    34  
    35  	common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoiptestrouter.dat"), "geoip.dat"))
    36  
    37  	ips := StringList([]string{
    38  		"geoip:us",
    39  		"geoip:cn",
    40  		"geoip:!cn",
    41  		"ext:geoiptestrouter.dat:!cn",
    42  		"ext:geoiptestrouter.dat:ca",
    43  		"ext-ip:geoiptestrouter.dat:!cn",
    44  		"ext-ip:geoiptestrouter.dat:!ca",
    45  	})
    46  
    47  	_, err := ToCidrList(ips)
    48  	if err != nil {
    49  		t.Fatalf("Failed to parse geoip list, got %s", err)
    50  	}
    51  }
    52  
    53  func TestRouterConfig(t *testing.T) {
    54  	createParser := func() func(string) (proto.Message, error) {
    55  		return func(s string) (proto.Message, error) {
    56  			config := new(RouterConfig)
    57  			if err := json.Unmarshal([]byte(s), config); err != nil {
    58  				return nil, err
    59  			}
    60  			return config.Build()
    61  		}
    62  	}
    63  
    64  	runMultiTestCase(t, []TestCase{
    65  		{
    66  			Input: `{
    67  				"strategy": "rules",
    68  				"settings": {
    69  					"domainStrategy": "AsIs",
    70  					"rules": [
    71  						{
    72  							"type": "field",
    73  							"domain": [
    74  								"baidu.com",
    75  								"qq.com"
    76  							],
    77  							"outboundTag": "direct"
    78  						},
    79  						{
    80  							"type": "field",
    81  							"ip": [
    82  								"10.0.0.0/8",
    83  								"::1/128"
    84  							],
    85  							"outboundTag": "test"
    86  						},{
    87  							"type": "field",
    88  							"port": "53, 443, 1000-2000",
    89  							"outboundTag": "test"
    90  						},{
    91  							"type": "field",
    92  							"port": 123,
    93  							"outboundTag": "test"
    94  						}
    95  					]
    96  				},
    97  				"balancers": [
    98  					{
    99  						"tag": "b1",
   100  						"selector": ["test"],
   101  						"fallbackTag": "fall"
   102  					},
   103  					{
   104  						"tag": "b2",
   105  						"selector": ["test"],
   106  						"strategy": {
   107  							"type": "leastload",
   108  							"settings": {
   109  								"healthCheck": {
   110  									"interval": "5m0s",
   111  									"sampling": 2,
   112  									"timeout": "5s",
   113  									"destination": "dest",
   114  									"connectivity": "conn"
   115  								},
   116  								"costs": [
   117  									{
   118  										"regexp": true,
   119  										"match": "\\d+(\\.\\d+)",
   120  										"value": 5
   121  									}
   122  								],
   123  								"baselines": ["400ms", "600ms"],
   124  								"expected": 6,
   125  								"maxRTT": "1000ms",
   126  								"tolerance": 0.5
   127  							}
   128  						},
   129  						"fallbackTag": "fall"
   130  					}
   131  				]
   132  			}`,
   133  			Parser: createParser(),
   134  			Output: &router.Config{
   135  				DomainStrategy: router.Config_AsIs,
   136  				BalancingRule: []*router.BalancingRule{
   137  					{
   138  						Tag:              "b1",
   139  						OutboundSelector: []string{"test"},
   140  						Strategy:         "random",
   141  						FallbackTag:      "fall",
   142  					},
   143  					{
   144  						Tag:              "b2",
   145  						OutboundSelector: []string{"test"},
   146  						Strategy:         "leastload",
   147  						StrategySettings: serial.ToTypedMessage(&router.StrategyLeastLoadConfig{
   148  							Costs: []*router.StrategyWeight{
   149  								{
   150  									Regexp: true,
   151  									Match:  "\\d+(\\.\\d+)",
   152  									Value:  5,
   153  								},
   154  							},
   155  							Baselines: []int64{
   156  								int64(time.Duration(400) * time.Millisecond),
   157  								int64(time.Duration(600) * time.Millisecond),
   158  							},
   159  							Expected:  6,
   160  							MaxRTT:    int64(time.Duration(1000) * time.Millisecond),
   161  							Tolerance: 0.5,
   162  						}),
   163  						FallbackTag: "fall",
   164  					},
   165  				},
   166  				Rule: []*router.RoutingRule{
   167  					{
   168  						Domain: []*router.Domain{
   169  							{
   170  								Type:  router.Domain_Plain,
   171  								Value: "baidu.com",
   172  							},
   173  							{
   174  								Type:  router.Domain_Plain,
   175  								Value: "qq.com",
   176  							},
   177  						},
   178  						TargetTag: &router.RoutingRule_Tag{
   179  							Tag: "direct",
   180  						},
   181  					},
   182  					{
   183  						Geoip: []*router.GeoIP{
   184  							{
   185  								Cidr: []*router.CIDR{
   186  									{
   187  										Ip:     []byte{10, 0, 0, 0},
   188  										Prefix: 8,
   189  									},
   190  									{
   191  										Ip:     []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
   192  										Prefix: 128,
   193  									},
   194  								},
   195  							},
   196  						},
   197  						TargetTag: &router.RoutingRule_Tag{
   198  							Tag: "test",
   199  						},
   200  					},
   201  					{
   202  						PortList: &net.PortList{
   203  							Range: []*net.PortRange{
   204  								{From: 53, To: 53},
   205  								{From: 443, To: 443},
   206  								{From: 1000, To: 2000},
   207  							},
   208  						},
   209  						TargetTag: &router.RoutingRule_Tag{
   210  							Tag: "test",
   211  						},
   212  					},
   213  					{
   214  						PortList: &net.PortList{
   215  							Range: []*net.PortRange{
   216  								{From: 123, To: 123},
   217  							},
   218  						},
   219  						TargetTag: &router.RoutingRule_Tag{
   220  							Tag: "test",
   221  						},
   222  					},
   223  				},
   224  			},
   225  		},
   226  		{
   227  			Input: `{
   228  				"strategy": "rules",
   229  				"settings": {
   230  					"domainStrategy": "IPIfNonMatch",
   231  					"rules": [
   232  						{
   233  							"type": "field",
   234  							"domain": [
   235  								"baidu.com",
   236  								"qq.com"
   237  							],
   238  							"outboundTag": "direct"
   239  						},
   240  						{
   241  							"type": "field",
   242  							"ip": [
   243  								"10.0.0.0/8",
   244  								"::1/128"
   245  							],
   246  							"outboundTag": "test"
   247  						}
   248  					]
   249  				}
   250  			}`,
   251  			Parser: createParser(),
   252  			Output: &router.Config{
   253  				DomainStrategy: router.Config_IpIfNonMatch,
   254  				Rule: []*router.RoutingRule{
   255  					{
   256  						Domain: []*router.Domain{
   257  							{
   258  								Type:  router.Domain_Plain,
   259  								Value: "baidu.com",
   260  							},
   261  							{
   262  								Type:  router.Domain_Plain,
   263  								Value: "qq.com",
   264  							},
   265  						},
   266  						TargetTag: &router.RoutingRule_Tag{
   267  							Tag: "direct",
   268  						},
   269  					},
   270  					{
   271  						Geoip: []*router.GeoIP{
   272  							{
   273  								Cidr: []*router.CIDR{
   274  									{
   275  										Ip:     []byte{10, 0, 0, 0},
   276  										Prefix: 8,
   277  									},
   278  									{
   279  										Ip:     []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
   280  										Prefix: 128,
   281  									},
   282  								},
   283  							},
   284  						},
   285  						TargetTag: &router.RoutingRule_Tag{
   286  							Tag: "test",
   287  						},
   288  					},
   289  				},
   290  			},
   291  		},
   292  		{
   293  			Input: `{
   294  				"domainStrategy": "AsIs",
   295  				"rules": [
   296  					{
   297  						"type": "field",
   298  						"domain": [
   299  							"baidu.com",
   300  							"qq.com"
   301  						],
   302  						"outboundTag": "direct"
   303  					},
   304  					{
   305  						"type": "field",
   306  						"ip": [
   307  							"10.0.0.0/8",
   308  							"::1/128"
   309  						],
   310  						"outboundTag": "test"
   311  					}
   312  				]
   313  			}`,
   314  			Parser: createParser(),
   315  			Output: &router.Config{
   316  				DomainStrategy: router.Config_AsIs,
   317  				Rule: []*router.RoutingRule{
   318  					{
   319  						Domain: []*router.Domain{
   320  							{
   321  								Type:  router.Domain_Plain,
   322  								Value: "baidu.com",
   323  							},
   324  							{
   325  								Type:  router.Domain_Plain,
   326  								Value: "qq.com",
   327  							},
   328  						},
   329  						TargetTag: &router.RoutingRule_Tag{
   330  							Tag: "direct",
   331  						},
   332  					},
   333  					{
   334  						Geoip: []*router.GeoIP{
   335  							{
   336  								Cidr: []*router.CIDR{
   337  									{
   338  										Ip:     []byte{10, 0, 0, 0},
   339  										Prefix: 8,
   340  									},
   341  									{
   342  										Ip:     []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
   343  										Prefix: 128,
   344  									},
   345  								},
   346  							},
   347  						},
   348  						TargetTag: &router.RoutingRule_Tag{
   349  							Tag: "test",
   350  						},
   351  					},
   352  				},
   353  			},
   354  		},
   355  	})
   356  }