mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-27 11:01:27 +00:00
Merge remote-tracking branch 'upstream/dns-geo-reverse-match' into dns-geo
This commit is contained in:
commit
16017304b8
|
@ -44,20 +44,36 @@ func ParseDomainRule(domain string) ([]*dm.Domain, error) {
|
||||||
domainRule := new(dm.Domain)
|
domainRule := new(dm.Domain)
|
||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(domain, "regexp:"):
|
case strings.HasPrefix(domain, "regexp:"):
|
||||||
|
regexpVal := domain[7:]
|
||||||
|
if len(regexpVal) == 0 {
|
||||||
|
return nil, newError("empty regexp type of rule: ", domain)
|
||||||
|
}
|
||||||
domainRule.Type = dm.MatchingType_Regex
|
domainRule.Type = dm.MatchingType_Regex
|
||||||
domainRule.Value = domain[7:]
|
domainRule.Value = regexpVal
|
||||||
|
|
||||||
case strings.HasPrefix(domain, "domain:"):
|
case strings.HasPrefix(domain, "domain:"):
|
||||||
|
domainName := domain[7:]
|
||||||
|
if len(domainName) == 0 {
|
||||||
|
return nil, newError("empty domain type of rule: ", domain)
|
||||||
|
}
|
||||||
domainRule.Type = dm.MatchingType_Subdomain
|
domainRule.Type = dm.MatchingType_Subdomain
|
||||||
domainRule.Value = domain[7:]
|
domainRule.Value = domainName
|
||||||
|
|
||||||
case strings.HasPrefix(domain, "full:"):
|
case strings.HasPrefix(domain, "full:"):
|
||||||
|
fullVal := domain[5:]
|
||||||
|
if len(fullVal) == 0 {
|
||||||
|
return nil, newError("empty full domain type of rule: ", domain)
|
||||||
|
}
|
||||||
domainRule.Type = dm.MatchingType_Full
|
domainRule.Type = dm.MatchingType_Full
|
||||||
domainRule.Value = domain[5:]
|
domainRule.Value = fullVal
|
||||||
|
|
||||||
case strings.HasPrefix(domain, "keyword:"):
|
case strings.HasPrefix(domain, "keyword:"):
|
||||||
|
keywordVal := domain[8:]
|
||||||
|
if len(keywordVal) == 0 {
|
||||||
|
return nil, newError("empty keyword type of rule: ", domain)
|
||||||
|
}
|
||||||
domainRule.Type = dm.MatchingType_Keyword
|
domainRule.Type = dm.MatchingType_Keyword
|
||||||
domainRule.Value = domain[8:]
|
domainRule.Value = keywordVal
|
||||||
|
|
||||||
case strings.HasPrefix(domain, "dotless:"):
|
case strings.HasPrefix(domain, "dotless:"):
|
||||||
domainRule.Type = dm.MatchingType_Regex
|
domainRule.Type = dm.MatchingType_Regex
|
||||||
|
|
|
@ -92,21 +92,28 @@ func find(data, code []byte) []byte {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParaseIPList(ips []string) ([]*GeoIP, error) {
|
func ParseIPList(ips []string) ([]*GeoIP, error) {
|
||||||
var geoipList []*GeoIP
|
var geoipList []*GeoIP
|
||||||
var customCidrs []*CIDR
|
var customCidrs []*CIDR
|
||||||
|
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
if strings.HasPrefix(ip, "geoip:") {
|
if strings.HasPrefix(ip, "geoip:") {
|
||||||
country := ip[6:]
|
country := ip[6:]
|
||||||
|
isReverseMatch := false
|
||||||
|
if strings.HasPrefix(country, "!") {
|
||||||
|
country = country[1:]
|
||||||
|
isReverseMatch = true
|
||||||
|
}
|
||||||
|
|
||||||
geoipc, err := LoadGeoIP(strings.ToUpper(country))
|
geoipc, err := LoadGeoIP(strings.ToUpper(country))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("failed to load GeoIP: ", country).Base(err)
|
return nil, newError("failed to load GeoIP: ", country).Base(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
geoipList = append(geoipList, &GeoIP{
|
geoipList = append(geoipList, &GeoIP{
|
||||||
CountryCode: strings.ToUpper(country),
|
CountryCode: strings.ToUpper(country),
|
||||||
Cidr: geoipc,
|
Cidr: geoipc,
|
||||||
|
ReverseMatch: isReverseMatch,
|
||||||
})
|
})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -129,14 +136,24 @@ func ParaseIPList(ips []string) ([]*GeoIP, error) {
|
||||||
|
|
||||||
filename := kv[0]
|
filename := kv[0]
|
||||||
country := kv[1]
|
country := kv[1]
|
||||||
|
if len(filename) == 0 || len(country) == 0 {
|
||||||
|
return nil, newError("empty filename or empty country in rule")
|
||||||
|
}
|
||||||
|
|
||||||
|
isReverseMatch := false
|
||||||
|
if strings.HasPrefix(country, "!") {
|
||||||
|
country = country[1:]
|
||||||
|
isReverseMatch = true
|
||||||
|
}
|
||||||
geoipc, err := LoadIPFile(filename, strings.ToUpper(country))
|
geoipc, err := LoadIPFile(filename, strings.ToUpper(country))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("failed to load IPs: ", country, " from ", filename).Base(err)
|
return nil, newError("failed to load IPs: ", country, " from ", filename).Base(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
geoipList = append(geoipList, &GeoIP{
|
geoipList = append(geoipList, &GeoIP{
|
||||||
CountryCode: strings.ToUpper(filename + "_" + country),
|
CountryCode: strings.ToUpper(filename + "_" + country),
|
||||||
Cidr: geoipc,
|
Cidr: geoipc,
|
||||||
|
ReverseMatch: isReverseMatch,
|
||||||
})
|
})
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -15,11 +15,16 @@ type ipv6 struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GeoIPMatcher struct {
|
type GeoIPMatcher struct {
|
||||||
countryCode string
|
countryCode string
|
||||||
ip4 []uint32
|
reverseMatch bool
|
||||||
prefix4 []uint8
|
ip4 []uint32
|
||||||
ip6 []ipv6
|
prefix4 []uint8
|
||||||
prefix6 []uint8
|
ip6 []ipv6
|
||||||
|
prefix6 []uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *GeoIPMatcher) SetReverseMatch(isReverseMatch bool) {
|
||||||
|
m.reverseMatch = isReverseMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalize4(ip uint32, prefix uint8) uint32 {
|
func normalize4(ip uint32, prefix uint8) uint32 {
|
||||||
|
@ -149,8 +154,17 @@ func (m *GeoIPMatcher) match6(ip ipv6) bool {
|
||||||
func (m *GeoIPMatcher) Match(ip net.IP) bool {
|
func (m *GeoIPMatcher) Match(ip net.IP) bool {
|
||||||
switch len(ip) {
|
switch len(ip) {
|
||||||
case 4:
|
case 4:
|
||||||
|
if m.reverseMatch {
|
||||||
|
return !m.match4(binary.BigEndian.Uint32(ip))
|
||||||
|
}
|
||||||
return m.match4(binary.BigEndian.Uint32(ip))
|
return m.match4(binary.BigEndian.Uint32(ip))
|
||||||
case 16:
|
case 16:
|
||||||
|
if m.reverseMatch {
|
||||||
|
return !m.match6(ipv6{
|
||||||
|
a: binary.BigEndian.Uint64(ip[0:8]),
|
||||||
|
b: binary.BigEndian.Uint64(ip[8:16]),
|
||||||
|
})
|
||||||
|
}
|
||||||
return m.match6(ipv6{
|
return m.match6(ipv6{
|
||||||
a: binary.BigEndian.Uint64(ip[0:8]),
|
a: binary.BigEndian.Uint64(ip[0:8]),
|
||||||
b: binary.BigEndian.Uint64(ip[8:16]),
|
b: binary.BigEndian.Uint64(ip[8:16]),
|
||||||
|
@ -170,14 +184,15 @@ type GeoIPMatcherContainer struct {
|
||||||
func (c *GeoIPMatcherContainer) Add(geoip *GeoIP) (*GeoIPMatcher, error) {
|
func (c *GeoIPMatcherContainer) Add(geoip *GeoIP) (*GeoIPMatcher, error) {
|
||||||
if len(geoip.CountryCode) > 0 {
|
if len(geoip.CountryCode) > 0 {
|
||||||
for _, m := range c.matchers {
|
for _, m := range c.matchers {
|
||||||
if m.countryCode == geoip.CountryCode {
|
if m.countryCode == geoip.CountryCode && m.reverseMatch == geoip.ReverseMatch {
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m := &GeoIPMatcher{
|
m := &GeoIPMatcher{
|
||||||
countryCode: geoip.CountryCode,
|
countryCode: geoip.CountryCode,
|
||||||
|
reverseMatch: geoip.ReverseMatch,
|
||||||
}
|
}
|
||||||
if err := m.Init(geoip.Cidr); err != nil {
|
if err := m.Init(geoip.Cidr); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.25.0
|
// protoc-gen-go v1.25.0
|
||||||
// protoc v3.15.6
|
// protoc v3.15.7
|
||||||
// source: common/matcher/geoip/geoip.proto
|
// source: common/matcher/geoip/geoip.proto
|
||||||
|
|
||||||
package geoip
|
package geoip
|
||||||
|
@ -88,8 +88,9 @@ type GeoIP struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
CountryCode string `protobuf:"bytes,1,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"`
|
CountryCode string `protobuf:"bytes,1,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"`
|
||||||
Cidr []*CIDR `protobuf:"bytes,2,rep,name=cidr,proto3" json:"cidr,omitempty"`
|
Cidr []*CIDR `protobuf:"bytes,2,rep,name=cidr,proto3" json:"cidr,omitempty"`
|
||||||
|
ReverseMatch bool `protobuf:"varint,3,opt,name=reverse_match,json=reverseMatch,proto3" json:"reverse_match,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GeoIP) Reset() {
|
func (x *GeoIP) Reset() {
|
||||||
|
@ -138,6 +139,13 @@ func (x *GeoIP) GetCidr() []*CIDR {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *GeoIP) GetReverseMatch() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.ReverseMatch
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type GeoIPList struct {
|
type GeoIPList struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
|
@ -194,25 +202,27 @@ var file_common_matcher_geoip_geoip_proto_rawDesc = []byte{
|
||||||
0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x22, 0x2e, 0x0a,
|
0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x22, 0x2e, 0x0a,
|
||||||
0x04, 0x43, 0x49, 0x44, 0x52, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28,
|
0x04, 0x43, 0x49, 0x44, 0x52, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||||
0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18,
|
0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18,
|
||||||
0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0x5f, 0x0a,
|
0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0x84, 0x01,
|
||||||
0x05, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72,
|
0x0a, 0x05, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||||
0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f,
|
0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63,
|
||||||
0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x63, 0x69, 0x64,
|
0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x63, 0x69,
|
||||||
0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63,
|
0x64, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
|
||||||
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65,
|
|
||||||
0x6f, 0x69, 0x70, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x22, 0x43,
|
|
||||||
0x0a, 0x09, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x05, 0x65,
|
|
||||||
0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61,
|
|
||||||
0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72,
|
|
||||||
0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x65, 0x6e,
|
|
||||||
0x74, 0x72, 0x79, 0x42, 0x6d, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
|
|
||||||
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67,
|
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67,
|
||||||
0x65, 0x6f, 0x69, 0x70, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
0x65, 0x6f, 0x69, 0x70, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x12,
|
||||||
0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72,
|
0x23, 0x0a, 0x0d, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68,
|
||||||
0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72,
|
0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4d,
|
||||||
0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0xaa, 0x02, 0x19, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x43, 0x6f,
|
0x61, 0x74, 0x63, 0x68, 0x22, 0x43, 0x0a, 0x09, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73,
|
||||||
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f,
|
0x74, 0x12, 0x36, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
|
||||||
0x49, 0x50, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d,
|
||||||
|
0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x47, 0x65, 0x6f,
|
||||||
|
0x49, 0x50, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x6d, 0x0a, 0x1d, 0x63, 0x6f, 0x6d,
|
||||||
|
0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74,
|
||||||
|
0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69,
|
||||||
|
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72,
|
||||||
|
0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d,
|
||||||
|
0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0xaa, 0x02, 0x19, 0x58,
|
||||||
|
0x72, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68,
|
||||||
|
0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -18,6 +18,7 @@ message CIDR {
|
||||||
message GeoIP {
|
message GeoIP {
|
||||||
string country_code = 1;
|
string country_code = 1;
|
||||||
repeated CIDR cidr = 2;
|
repeated CIDR cidr = 2;
|
||||||
|
bool reverse_match =3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GeoIPList {
|
message GeoIPList {
|
||||||
|
|
|
@ -5,12 +5,12 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
. "github.com/xtls/xray-core/common/matcher/geoip"
|
. "github.com/xtls/xray-core/common/matcher/geoip"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/common/platform"
|
"github.com/xtls/xray-core/common/platform"
|
||||||
"github.com/xtls/xray-core/common/platform/filesystem"
|
"github.com/xtls/xray-core/common/platform/filesystem"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -20,11 +20,31 @@ func init() {
|
||||||
if _, err := os.Stat(platform.GetAssetLocation("geoip.dat")); err != nil && os.IsNotExist(err) {
|
if _, err := os.Stat(platform.GetAssetLocation("geoip.dat")); err != nil && os.IsNotExist(err) {
|
||||||
common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(wd, "..", "..", "..", "resources", "geoip.dat")))
|
common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(wd, "..", "..", "..", "resources", "geoip.dat")))
|
||||||
}
|
}
|
||||||
|
if _, err := os.Stat(platform.GetAssetLocation("geoiptestrouter.dat")); err != nil && os.IsNotExist(err) {
|
||||||
|
common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoiptestrouter.dat"), filepath.Join(wd, "..", "..", "..", "resources", "geoip.dat")))
|
||||||
|
}
|
||||||
if _, err := os.Stat(platform.GetAssetLocation("geosite.dat")); err != nil && os.IsNotExist(err) {
|
if _, err := os.Stat(platform.GetAssetLocation("geosite.dat")); err != nil && os.IsNotExist(err) {
|
||||||
common.Must(filesystem.CopyFile(platform.GetAssetLocation("geosite.dat"), filepath.Join(wd, "..", "..", "..", "resources", "geosite.dat")))
|
common.Must(filesystem.CopyFile(platform.GetAssetLocation("geosite.dat"), filepath.Join(wd, "..", "..", "..", "resources", "geosite.dat")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseIPList(t *testing.T) {
|
||||||
|
ips := []string{
|
||||||
|
"geoip:us",
|
||||||
|
"geoip:cn",
|
||||||
|
"geoip:!cn",
|
||||||
|
"ext:geoiptestrouter.dat:!cn",
|
||||||
|
"ext:geoiptestrouter.dat:ca",
|
||||||
|
"ext-ip:geoiptestrouter.dat:!cn",
|
||||||
|
"ext-ip:geoiptestrouter.dat:!ca",
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := ParseIPList(ips)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to parse geoip list, got %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGeoIPMatcherContainer(t *testing.T) {
|
func TestGeoIPMatcherContainer(t *testing.T) {
|
||||||
container := &GeoIPMatcherContainer{}
|
container := &GeoIPMatcherContainer{}
|
||||||
|
|
||||||
|
@ -123,6 +143,42 @@ func TestGeoIPMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGeoIPReverseMatcher(t *testing.T) {
|
||||||
|
cidrList := CIDRList{
|
||||||
|
{Ip: []byte{8, 8, 8, 8}, Prefix: 32},
|
||||||
|
{Ip: []byte{91, 108, 4, 0}, Prefix: 16},
|
||||||
|
}
|
||||||
|
matcher := &GeoIPMatcher{}
|
||||||
|
matcher.SetReverseMatch(true) // Reverse match
|
||||||
|
common.Must(matcher.Init(cidrList))
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
Input string
|
||||||
|
Output bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Input: "8.8.8.8",
|
||||||
|
Output: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Input: "2001:cdba::3257:9652",
|
||||||
|
Output: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Input: "91.108.255.254",
|
||||||
|
Output: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
ip := net.ParseAddress(testCase.Input).IP()
|
||||||
|
actual := matcher.Match(ip)
|
||||||
|
if actual != testCase.Output {
|
||||||
|
t.Error("expect input", testCase.Input, "to be", testCase.Output, ", but actually", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGeoIPMatcher4CN(t *testing.T) {
|
func TestGeoIPMatcher4CN(t *testing.T) {
|
||||||
ips, err := loadGeoIP("CN")
|
ips, err := loadGeoIP("CN")
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package geosite
|
package geosite
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
type AttributeList struct {
|
type AttributeList struct {
|
||||||
matcher []AttributeMatcher
|
matcher []AttributeMatcher
|
||||||
}
|
}
|
||||||
|
@ -25,7 +27,7 @@ type BooleanMatcher string
|
||||||
|
|
||||||
func (m BooleanMatcher) Match(domain *Domain) bool {
|
func (m BooleanMatcher) Match(domain *Domain) bool {
|
||||||
for _, attr := range domain.Attribute {
|
for _, attr := range domain.Attribute {
|
||||||
if attr.Key == string(m) {
|
if strings.EqualFold(attr.GetKey(), string(m)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
geoipList, err := geoip.ParaseIPList(c.ExpectIPs)
|
geoipList, err := geoip.ParseIPList(c.ExpectIPs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("invalid IP rule: ", c.ExpectIPs).Base(err)
|
return nil, newError("invalid IP rule: ", c.ExpectIPs).Base(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,7 +203,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if rawFieldRule.IP != nil {
|
if rawFieldRule.IP != nil {
|
||||||
geoipList, err := geoip.ParaseIPList(*rawFieldRule.IP)
|
geoipList, err := geoip.ParseIPList(*rawFieldRule.IP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if rawFieldRule.SourceIP != nil {
|
if rawFieldRule.SourceIP != nil {
|
||||||
geoipList, err := geoip.ParaseIPList(*rawFieldRule.SourceIP)
|
geoipList, err := geoip.ParseIPList(*rawFieldRule.SourceIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -261,21 +261,21 @@ func ParseRule(msg json.RawMessage) (*router.RoutingRule, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("invalid router rule").Base(err)
|
return nil, newError("invalid router rule").Base(err)
|
||||||
}
|
}
|
||||||
if rawRule.Type == "field" {
|
if strings.EqualFold(rawRule.Type, "field") {
|
||||||
fieldrule, err := parseFieldRule(msg)
|
fieldrule, err := parseFieldRule(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("invalid field rule").Base(err)
|
return nil, newError("invalid field rule").Base(err)
|
||||||
}
|
}
|
||||||
return fieldrule, nil
|
return fieldrule, nil
|
||||||
}
|
}
|
||||||
if rawRule.Type == "chinaip" {
|
if strings.EqualFold(rawRule.Type, "chinaip") {
|
||||||
chinaiprule, err := parseChinaIPRule(msg)
|
chinaiprule, err := parseChinaIPRule(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("invalid chinaip rule").Base(err)
|
return nil, newError("invalid chinaip rule").Base(err)
|
||||||
}
|
}
|
||||||
return chinaiprule, nil
|
return chinaiprule, nil
|
||||||
}
|
}
|
||||||
if rawRule.Type == "chinasites" {
|
if strings.EqualFold(rawRule.Type, "chinasites") {
|
||||||
chinasitesrule, err := parseChinaSitesRule(msg)
|
chinasitesrule, err := parseChinaSitesRule(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("invalid chinasites rule").Base(err)
|
return nil, newError("invalid chinasites rule").Base(err)
|
||||||
|
|
|
@ -101,7 +101,7 @@ func (c *SniffingConfig) Build() (*proxyman.SniffingConfig, error) {
|
||||||
|
|
||||||
var exIP []*geoip.GeoIP
|
var exIP []*geoip.GeoIP
|
||||||
if c.IPsExcluded != nil {
|
if c.IPsExcluded != nil {
|
||||||
exip, err := geoip.ParaseIPList(*c.IPsExcluded)
|
exip, err := geoip.ParseIPList(*c.IPsExcluded)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("failed to parse excluded ip").Base(err)
|
return nil, newError("failed to parse excluded ip").Base(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue