condition_geoip_test.go 5.1 KB

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