1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
| package dns_test
|
| import (
| "encoding/json"
| "errors"
| "io/fs"
| "os"
| "path/filepath"
| "testing"
|
| "google.golang.org/protobuf/runtime/protoiface"
|
| "github.com/v2fly/v2ray-core/v5/app/dns"
| "github.com/v2fly/v2ray-core/v5/common"
| "github.com/v2fly/v2ray-core/v5/common/net"
| "github.com/v2fly/v2ray-core/v5/common/platform/filesystem"
| "github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist"
| _ "github.com/v2fly/v2ray-core/v5/infra/conf/geodata/standard"
| dns2 "github.com/v2fly/v2ray-core/v5/infra/conf/synthetic/dns"
| )
|
| func init() {
| const (
| geoipURL = "https://raw.githubusercontent.com/v2fly/geoip/release/geoip.dat"
| geositeURL = "https://raw.githubusercontent.com/v2fly/domain-list-community/release/dlc.dat"
| )
|
| wd, err := os.Getwd()
| common.Must(err)
|
| tempPath := filepath.Join(wd, "..", "..", "..", "..", "testing", "temp")
| geoipPath := filepath.Join(tempPath, "geoip.dat")
| geositePath := filepath.Join(tempPath, "geosite.dat")
|
| os.Setenv("v2ray.location.asset", tempPath)
|
| if _, err := os.Stat(geoipPath); err != nil && errors.Is(err, fs.ErrNotExist) {
| common.Must(os.MkdirAll(tempPath, 0o755))
| geoipBytes, err := common.FetchHTTPContent(geoipURL)
| common.Must(err)
| common.Must(filesystem.WriteFile(geoipPath, geoipBytes))
| }
| if _, err := os.Stat(geositePath); err != nil && errors.Is(err, fs.ErrNotExist) {
| common.Must(os.MkdirAll(tempPath, 0o755))
| geositeBytes, err := common.FetchHTTPContent(geositeURL)
| common.Must(err)
| common.Must(filesystem.WriteFile(geositePath, geositeBytes))
| }
| }
|
| func TestDNSConfigParsing(t *testing.T) {
| parserCreator := func() func(string) (protoiface.MessageV1, error) {
| return func(s string) (protoiface.MessageV1, error) {
| config := new(dns2.DNSConfig)
| if err := json.Unmarshal([]byte(s), config); err != nil {
| return nil, err
| }
| return config.Build()
| }
| }
|
| testassist.RunMultiTestCase(t, []testassist.TestCase{
| {
| Input: `{
| "servers": [{
| "address": "8.8.8.8",
| "clientIp": "10.0.0.1",
| "port": 5353,
| "skipFallback": true,
| "domains": ["domain:v2fly.org"]
| }],
| "hosts": {
| "v2fly.org": "127.0.0.1",
| "www.v2fly.org": ["1.2.3.4", "5.6.7.8"],
| "domain:example.com": "google.com",
| "geosite:test": ["127.0.0.1", "127.0.0.2"],
| "keyword:google": ["8.8.8.8", "8.8.4.4"],
| "regexp:.*\\.com": "8.8.4.4"
| },
| "clientIp": "10.0.0.1",
| "queryStrategy": "UseIPv4",
| "disableCache": true,
| "disableFallback": true
| }`,
| Parser: parserCreator(),
| Output: &dns.Config{
| NameServer: []*dns.NameServer{
| {
| Address: &net.Endpoint{
| Address: &net.IPOrDomain{
| Address: &net.IPOrDomain_Ip{
| Ip: []byte{8, 8, 8, 8},
| },
| },
| Network: net.Network_UDP,
| Port: 5353,
| },
| ClientIp: []byte{10, 0, 0, 1},
| SkipFallback: true,
| PrioritizedDomain: []*dns.NameServer_PriorityDomain{
| {
| Type: dns.DomainMatchingType_Subdomain,
| Domain: "v2fly.org",
| },
| },
| OriginalRules: []*dns.NameServer_OriginalRule{
| {
| Rule: "domain:v2fly.org",
| Size: 1,
| },
| },
| },
| },
| StaticHosts: []*dns.HostMapping{
| {
| Type: dns.DomainMatchingType_Subdomain,
| Domain: "example.com",
| ProxiedDomain: "google.com",
| },
| {
| Type: dns.DomainMatchingType_Full,
| Domain: "test.example.com",
| Ip: [][]byte{{127, 0, 0, 1}, {127, 0, 0, 2}},
| },
| {
| Type: dns.DomainMatchingType_Keyword,
| Domain: "google",
| Ip: [][]byte{{8, 8, 8, 8}, {8, 8, 4, 4}},
| },
| {
| Type: dns.DomainMatchingType_Regex,
| Domain: ".*\\.com",
| Ip: [][]byte{{8, 8, 4, 4}},
| },
| {
| Type: dns.DomainMatchingType_Full,
| Domain: "v2fly.org",
| Ip: [][]byte{{127, 0, 0, 1}},
| },
| {
| Type: dns.DomainMatchingType_Full,
| Domain: "www.v2fly.org",
| Ip: [][]byte{{1, 2, 3, 4}, {5, 6, 7, 8}},
| },
| },
| ClientIp: []byte{10, 0, 0, 1},
| QueryStrategy: dns.QueryStrategy_USE_IP4,
| DisableCache: true,
| DisableFallback: true,
| },
| },
| })
| }
|
|