mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-22 10:08:15 -05:00
regexp support in domain matching
This commit is contained in:
parent
46071b9dac
commit
96aa94002a
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user