condition_geoip_test.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package router_test
  2. import (
  3. "os"
  4. "path/filepath"
  5. "testing"
  6. proto "github.com/golang/protobuf/proto"
  7. "v2ray.com/core/app/router"
  8. "v2ray.com/core/common"
  9. "v2ray.com/core/common/net"
  10. "v2ray.com/core/common/platform"
  11. "v2ray.com/ext/sysio"
  12. )
  13. func TestGeoIPMatcherContainer(t *testing.T) {
  14. container := &router.GeoIPMatcherContainer{}
  15. m1, err := container.Add(&router.GeoIP{
  16. CountryCode: "CN",
  17. })
  18. common.Must(err)
  19. m2, err := container.Add(&router.GeoIP{
  20. CountryCode: "US",
  21. })
  22. common.Must(err)
  23. m3, err := container.Add(&router.GeoIP{
  24. CountryCode: "CN",
  25. })
  26. common.Must(err)
  27. if m1 != m3 {
  28. t.Error("expect same matcher for same geoip, but not")
  29. }
  30. if m1 == m2 {
  31. t.Error("expect different matcher for different geoip, but actually same")
  32. }
  33. }
  34. func TestGeoIPMatcher(t *testing.T) {
  35. cidrList := router.CIDRList{
  36. {Ip: []byte{0, 0, 0, 0}, Prefix: 8},
  37. {Ip: []byte{10, 0, 0, 0}, Prefix: 8},
  38. {Ip: []byte{100, 64, 0, 0}, Prefix: 10},
  39. {Ip: []byte{127, 0, 0, 0}, Prefix: 8},
  40. {Ip: []byte{169, 254, 0, 0}, Prefix: 16},
  41. {Ip: []byte{172, 16, 0, 0}, Prefix: 12},
  42. {Ip: []byte{192, 0, 0, 0}, Prefix: 24},
  43. {Ip: []byte{192, 0, 2, 0}, Prefix: 24},
  44. {Ip: []byte{192, 168, 0, 0}, Prefix: 16},
  45. {Ip: []byte{192, 18, 0, 0}, Prefix: 15},
  46. {Ip: []byte{198, 51, 100, 0}, Prefix: 24},
  47. {Ip: []byte{203, 0, 113, 0}, Prefix: 24},
  48. {Ip: []byte{8, 8, 8, 8}, Prefix: 32},
  49. {Ip: []byte{91, 108, 4, 0}, Prefix: 16},
  50. }
  51. matcher := &router.GeoIPMatcher{}
  52. common.Must(matcher.Init(cidrList))
  53. testCases := []struct {
  54. Input string
  55. Output bool
  56. }{
  57. {
  58. Input: "192.168.1.1",
  59. Output: true,
  60. },
  61. {
  62. Input: "192.0.0.0",
  63. Output: true,
  64. },
  65. {
  66. Input: "192.0.1.0",
  67. Output: false,
  68. }, {
  69. Input: "0.1.0.0",
  70. Output: true,
  71. },
  72. {
  73. Input: "1.0.0.1",
  74. Output: false,
  75. },
  76. {
  77. Input: "8.8.8.7",
  78. Output: false,
  79. },
  80. {
  81. Input: "8.8.8.8",
  82. Output: true,
  83. },
  84. {
  85. Input: "2001:cdba::3257:9652",
  86. Output: false,
  87. },
  88. {
  89. Input: "91.108.255.254",
  90. Output: true,
  91. },
  92. }
  93. for _, testCase := range testCases {
  94. ip := net.ParseAddress(testCase.Input).IP()
  95. actual := matcher.Match(ip)
  96. if actual != testCase.Output {
  97. t.Error("expect input", testCase.Input, "to be", testCase.Output, ", but actually", actual)
  98. }
  99. }
  100. }
  101. func TestGeoIPMatcher4CN(t *testing.T) {
  102. common.Must(sysio.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", "release", "config", "geoip.dat")))
  103. ips, err := loadGeoIP("CN")
  104. common.Must(err)
  105. matcher := &router.GeoIPMatcher{}
  106. common.Must(matcher.Init(ips))
  107. if matcher.Match([]byte{8, 8, 8, 8}) {
  108. t.Error("expect CN geoip doesn't contain 8.8.8.8, but actually does")
  109. }
  110. }
  111. func TestGeoIPMatcher6US(t *testing.T) {
  112. common.Must(sysio.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", "release", "config", "geoip.dat")))
  113. ips, err := loadGeoIP("US")
  114. common.Must(err)
  115. matcher := &router.GeoIPMatcher{}
  116. common.Must(matcher.Init(ips))
  117. if !matcher.Match(net.ParseAddress("2001:4860:4860::8888").IP()) {
  118. t.Error("expect US geoip contain 2001:4860:4860::8888, but actually not")
  119. }
  120. }
  121. func loadGeoIP(country string) ([]*router.CIDR, error) {
  122. geoipBytes, err := sysio.ReadAsset("geoip.dat")
  123. if err != nil {
  124. return nil, err
  125. }
  126. var geoipList router.GeoIPList
  127. if err := proto.Unmarshal(geoipBytes, &geoipList); err != nil {
  128. return nil, err
  129. }
  130. for _, geoip := range geoipList.Entry {
  131. if geoip.CountryCode == country {
  132. return geoip.Cidr, nil
  133. }
  134. }
  135. panic("country not found: " + country)
  136. }
  137. func BenchmarkGeoIPMatcher4CN(b *testing.B) {
  138. common.Must(sysio.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", "release", "config", "geoip.dat")))
  139. ips, err := loadGeoIP("CN")
  140. common.Must(err)
  141. matcher := &router.GeoIPMatcher{}
  142. common.Must(matcher.Init(ips))
  143. b.ResetTimer()
  144. for i := 0; i < b.N; i++ {
  145. _ = matcher.Match([]byte{8, 8, 8, 8})
  146. }
  147. }
  148. func BenchmarkGeoIPMatcher6US(b *testing.B) {
  149. common.Must(sysio.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", "release", "config", "geoip.dat")))
  150. ips, err := loadGeoIP("US")
  151. common.Must(err)
  152. matcher := &router.GeoIPMatcher{}
  153. common.Must(matcher.Init(ips))
  154. b.ResetTimer()
  155. for i := 0; i < b.N; i++ {
  156. _ = matcher.Match(net.ParseAddress("2001:4860:4860::8888").IP())
  157. }
  158. }