condition_geoip_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package router_test
  2. import (
  3. "errors"
  4. "io/fs"
  5. "os"
  6. "path/filepath"
  7. "testing"
  8. "github.com/v2fly/v2ray-core/v4/app/router"
  9. "github.com/v2fly/v2ray-core/v4/common"
  10. "github.com/v2fly/v2ray-core/v4/common/geodata"
  11. "github.com/v2fly/v2ray-core/v4/common/net"
  12. "github.com/v2fly/v2ray-core/v4/common/platform"
  13. "github.com/v2fly/v2ray-core/v4/common/platform/filesystem"
  14. )
  15. func init() {
  16. wd, err := os.Getwd()
  17. common.Must(err)
  18. tempPath := filepath.Join(wd, "..", "..", "testing", "temp")
  19. geoipPath := filepath.Join(tempPath, "geoip.dat")
  20. os.Setenv("v2ray.location.asset", tempPath)
  21. if _, err := os.Stat(platform.GetAssetLocation("geoip.dat")); err != nil && errors.Is(err, fs.ErrNotExist) {
  22. if _, err := os.Stat(geoipPath); err != nil && errors.Is(err, fs.ErrNotExist) {
  23. common.Must(os.MkdirAll(tempPath, 0755))
  24. geoipBytes, err := common.FetchHTTPContent(geoipURL)
  25. common.Must(err)
  26. common.Must(filesystem.WriteFile(geoipPath, geoipBytes))
  27. }
  28. }
  29. }
  30. func TestGeoIPMatcherContainer(t *testing.T) {
  31. container := &router.GeoIPMatcherContainer{}
  32. m1, err := container.Add(&router.GeoIP{
  33. CountryCode: "CN",
  34. })
  35. common.Must(err)
  36. m2, err := container.Add(&router.GeoIP{
  37. CountryCode: "US",
  38. })
  39. common.Must(err)
  40. m3, err := container.Add(&router.GeoIP{
  41. CountryCode: "CN",
  42. })
  43. common.Must(err)
  44. if m1 != m3 {
  45. t.Error("expect same matcher for same geoip, but not")
  46. }
  47. if m1 == m2 {
  48. t.Error("expect different matcher for different geoip, but actually same")
  49. }
  50. }
  51. func TestGeoIPMatcher(t *testing.T) {
  52. cidrList := router.CIDRList{
  53. {Ip: []byte{0, 0, 0, 0}, Prefix: 8},
  54. {Ip: []byte{10, 0, 0, 0}, Prefix: 8},
  55. {Ip: []byte{100, 64, 0, 0}, Prefix: 10},
  56. {Ip: []byte{127, 0, 0, 0}, Prefix: 8},
  57. {Ip: []byte{169, 254, 0, 0}, Prefix: 16},
  58. {Ip: []byte{172, 16, 0, 0}, Prefix: 12},
  59. {Ip: []byte{192, 0, 0, 0}, Prefix: 24},
  60. {Ip: []byte{192, 0, 2, 0}, Prefix: 24},
  61. {Ip: []byte{192, 168, 0, 0}, Prefix: 16},
  62. {Ip: []byte{192, 18, 0, 0}, Prefix: 15},
  63. {Ip: []byte{198, 51, 100, 0}, Prefix: 24},
  64. {Ip: []byte{203, 0, 113, 0}, Prefix: 24},
  65. {Ip: []byte{8, 8, 8, 8}, Prefix: 32},
  66. {Ip: []byte{91, 108, 4, 0}, Prefix: 16},
  67. }
  68. matcher := &router.GeoIPMatcher{}
  69. common.Must(matcher.Init(cidrList))
  70. testCases := []struct {
  71. Input string
  72. Output bool
  73. }{
  74. {
  75. Input: "192.168.1.1",
  76. Output: true,
  77. },
  78. {
  79. Input: "192.0.0.0",
  80. Output: true,
  81. },
  82. {
  83. Input: "192.0.1.0",
  84. Output: false,
  85. }, {
  86. Input: "0.1.0.0",
  87. Output: true,
  88. },
  89. {
  90. Input: "1.0.0.1",
  91. Output: false,
  92. },
  93. {
  94. Input: "8.8.8.7",
  95. Output: false,
  96. },
  97. {
  98. Input: "8.8.8.8",
  99. Output: true,
  100. },
  101. {
  102. Input: "2001:cdba::3257:9652",
  103. Output: false,
  104. },
  105. {
  106. Input: "91.108.255.254",
  107. Output: true,
  108. },
  109. }
  110. for _, testCase := range testCases {
  111. ip := net.ParseAddress(testCase.Input).IP()
  112. actual := matcher.Match(ip)
  113. if actual != testCase.Output {
  114. t.Error("expect input", testCase.Input, "to be", testCase.Output, ", but actually", actual)
  115. }
  116. }
  117. }
  118. func TestGeoIPReverseMatcher(t *testing.T) {
  119. cidrList := router.CIDRList{
  120. {Ip: []byte{8, 8, 8, 8}, Prefix: 32},
  121. {Ip: []byte{91, 108, 4, 0}, Prefix: 16},
  122. }
  123. matcher := &router.GeoIPMatcher{}
  124. matcher.SetReverseMatch(true) // Reverse match
  125. common.Must(matcher.Init(cidrList))
  126. testCases := []struct {
  127. Input string
  128. Output bool
  129. }{
  130. {
  131. Input: "8.8.8.8",
  132. Output: false,
  133. },
  134. {
  135. Input: "2001:cdba::3257:9652",
  136. Output: true,
  137. },
  138. {
  139. Input: "91.108.255.254",
  140. Output: false,
  141. },
  142. }
  143. for _, testCase := range testCases {
  144. ip := net.ParseAddress(testCase.Input).IP()
  145. actual := matcher.Match(ip)
  146. if actual != testCase.Output {
  147. t.Error("expect input", testCase.Input, "to be", testCase.Output, ", but actually", actual)
  148. }
  149. }
  150. }
  151. func TestGeoIPMatcher4CN(t *testing.T) {
  152. ips, err := geodata.LoadIP("geoip.dat", "CN")
  153. common.Must(err)
  154. matcher := &router.GeoIPMatcher{}
  155. common.Must(matcher.Init(ips))
  156. if matcher.Match([]byte{8, 8, 8, 8}) {
  157. t.Error("expect CN geoip doesn't contain 8.8.8.8, but actually does")
  158. }
  159. }
  160. func TestGeoIPMatcher6US(t *testing.T) {
  161. ips, err := geodata.LoadIP("geoip.dat", "US")
  162. common.Must(err)
  163. matcher := &router.GeoIPMatcher{}
  164. common.Must(matcher.Init(ips))
  165. if !matcher.Match(net.ParseAddress("2001:4860:4860::8888").IP()) {
  166. t.Error("expect US geoip contain 2001:4860:4860::8888, but actually not")
  167. }
  168. }
  169. func BenchmarkGeoIPMatcher4CN(b *testing.B) {
  170. ips, err := geodata.LoadIP("geoip.dat", "CN")
  171. common.Must(err)
  172. matcher := &router.GeoIPMatcher{}
  173. common.Must(matcher.Init(ips))
  174. b.ResetTimer()
  175. for i := 0; i < b.N; i++ {
  176. _ = matcher.Match([]byte{8, 8, 8, 8})
  177. }
  178. }
  179. func BenchmarkGeoIPMatcher6US(b *testing.B) {
  180. ips, err := geodata.LoadIP("geoip.dat", "US")
  181. common.Must(err)
  182. matcher := &router.GeoIPMatcher{}
  183. common.Must(matcher.Init(ips))
  184. b.ResetTimer()
  185. for i := 0; i < b.N; i++ {
  186. _ = matcher.Match(net.ParseAddress("2001:4860:4860::8888").IP())
  187. }
  188. }