1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-22 18:17:52 -05:00

regexp support in domain matching

This commit is contained in:
Darien Raymond 2015-12-07 10:58:43 +00:00
parent 46071b9dac
commit 96aa94002a
2 changed files with 55 additions and 8 deletions

View File

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"net" "net"
"regexp"
"strings" "strings"
v2net "github.com/v2ray/v2ray-core/common/net" v2net "github.com/v2ray/v2ray-core/common/net"
@ -41,9 +42,39 @@ func (this *StringList) Len() int {
return len([]string(*this)) return len([]string(*this))
} }
type DomainMatcher interface {
Match(domain string) bool
}
type PlainDomainMatcher struct {
pattern string
}
func (this *PlainDomainMatcher) Match(domain string) bool {
return strings.Contains(this.pattern, domain)
}
type RegexpDomainMatcher struct {
pattern *regexp.Regexp
}
func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {
r, err := regexp.Compile(pattern)
if err != nil {
return nil, err
}
return &RegexpDomainMatcher{
pattern: r,
}, nil
}
func (this *RegexpDomainMatcher) Match(domain string) bool {
return this.pattern.MatchString(domain)
}
type FieldRule struct { type FieldRule struct {
Rule Rule
Domain *StringList Domain []DomainMatcher
IP []*net.IPNet IP []*net.IPNet
Port v2net.PortRange Port v2net.PortRange
Network v2net.NetworkList Network v2net.NetworkList
@ -51,13 +82,13 @@ type FieldRule struct {
func (this *FieldRule) Apply(dest v2net.Destination) bool { func (this *FieldRule) Apply(dest v2net.Destination) bool {
address := dest.Address() address := dest.Address()
if this.Domain != nil && this.Domain.Len() > 0 { if len(this.Domain) > 0 {
if !address.IsDomain() { if !address.IsDomain() {
return false return false
} }
foundMatch := false foundMatch := false
for _, domain := range *this.Domain { for _, domain := range this.Domain {
if strings.Contains(address.Domain(), domain) { if domain.Match(address.Domain()) {
foundMatch = true foundMatch = true
break break
} }
@ -117,7 +148,20 @@ func (this *FieldRule) UnmarshalJSON(data []byte) error {
hasField := false hasField := false
if rawFieldRule.Domain != nil && rawFieldRule.Domain.Len() > 0 { if rawFieldRule.Domain != nil && rawFieldRule.Domain.Len() > 0 {
this.Domain = rawFieldRule.Domain this.Domain = make([]DomainMatcher, rawFieldRule.Domain.Len())
for idx, rawDomain := range *(rawFieldRule.Domain) {
var matcher DomainMatcher
if strings.HasPrefix(rawDomain, "regexp:") {
rawMatcher, err := NewRegexpDomainMatcher(rawDomain[7:])
if err != nil {
return err
}
matcher = rawMatcher
} else {
matcher = &PlainDomainMatcher{pattern: rawDomain}
}
this.Domain[idx] = matcher
}
hasField = true hasField = true
} }

View File

@ -33,9 +33,12 @@ func TestStringListParsingString(t *testing.T) {
func TestDomainMatching(t *testing.T) { func TestDomainMatching(t *testing.T) {
v2testing.Current(t) v2testing.Current(t)
rule := &FieldRule{ rawJson := `{
Domain: NewStringList("v2ray.com"), "type": "field",
} "domain": ["google.com", "regexp:v2ray.com$"],
"tag": "test"
}`
rule := parseRule([]byte(rawJson))
dest := v2net.NewTCPDestination(v2net.DomainAddress("www.v2ray.com", 80)) dest := v2net.NewTCPDestination(v2net.DomainAddress("www.v2ray.com", 80))
assert.Bool(rule.Apply(dest)).IsTrue() assert.Bool(rule.Apply(dest)).IsTrue()
} }