feat: "!"(not) support for geosite
eg. GEOSITE,!CN,Proxy & dns.fallback-filter.geosite: ['!CN']
This commit is contained in:
parent
5fd025cbe3
commit
02d30883b6
4 changed files with 33 additions and 15 deletions
|
@ -33,9 +33,10 @@ func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) {
|
||||||
|
|
||||||
type DomainMatcher struct {
|
type DomainMatcher struct {
|
||||||
matchers strmatcher.IndexMatcher
|
matchers strmatcher.IndexMatcher
|
||||||
|
not bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMphMatcherGroup(domains []*Domain) (*DomainMatcher, error) {
|
func NewMphMatcherGroup(domains []*Domain, not bool) (*DomainMatcher, error) {
|
||||||
g := strmatcher.NewMphMatcherGroup()
|
g := strmatcher.NewMphMatcherGroup()
|
||||||
for _, d := range domains {
|
for _, d := range domains {
|
||||||
matcherType, f := matcherTypeMap[d.Type]
|
matcherType, f := matcherTypeMap[d.Type]
|
||||||
|
@ -50,11 +51,12 @@ func NewMphMatcherGroup(domains []*Domain) (*DomainMatcher, error) {
|
||||||
g.Build()
|
g.Build()
|
||||||
return &DomainMatcher{
|
return &DomainMatcher{
|
||||||
matchers: g,
|
matchers: g,
|
||||||
|
not: not,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDomainMatcher new domain matcher.
|
// NewDomainMatcher new domain matcher.
|
||||||
func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) {
|
func NewDomainMatcher(domains []*Domain, not bool) (*DomainMatcher, error) {
|
||||||
g := new(strmatcher.MatcherGroup)
|
g := new(strmatcher.MatcherGroup)
|
||||||
for _, d := range domains {
|
for _, d := range domains {
|
||||||
m, err := domainToMatcher(d)
|
m, err := domainToMatcher(d)
|
||||||
|
@ -66,11 +68,16 @@ func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) {
|
||||||
|
|
||||||
return &DomainMatcher{
|
return &DomainMatcher{
|
||||||
matchers: g,
|
matchers: g,
|
||||||
|
not: not,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DomainMatcher) ApplyDomain(domain string) bool {
|
func (m *DomainMatcher) ApplyDomain(domain string) bool {
|
||||||
return len(m.matchers.Match(strings.ToLower(domain))) > 0
|
isMatched := len(m.matchers.Match(strings.ToLower(domain))) > 0
|
||||||
|
if m.not {
|
||||||
|
isMatched = !isMatched
|
||||||
|
}
|
||||||
|
return isMatched
|
||||||
}
|
}
|
||||||
|
|
||||||
// CIDRList is an alias of []*CIDR to provide sort.Interface.
|
// CIDRList is an alias of []*CIDR to provide sort.Interface.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package geodata
|
package geodata
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/Dreamacro/clash/component/geodata/router"
|
"github.com/Dreamacro/clash/component/geodata/router"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -35,6 +36,16 @@ func Verify(name string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadGeoSiteMatcher(countryCode string) (*router.DomainMatcher, int, error) {
|
func LoadGeoSiteMatcher(countryCode string) (*router.DomainMatcher, int, error) {
|
||||||
|
if len(countryCode) == 0 {
|
||||||
|
return nil, 0, fmt.Errorf("country code could not be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
not := false
|
||||||
|
if countryCode[0] == '!' {
|
||||||
|
not = true
|
||||||
|
countryCode = countryCode[1:]
|
||||||
|
}
|
||||||
|
|
||||||
geoLoader, err := GetGeoDataLoader(geoLoaderName)
|
geoLoader, err := GetGeoDataLoader(geoLoaderName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
|
@ -50,7 +61,7 @@ func LoadGeoSiteMatcher(countryCode string) (*router.DomainMatcher, int, error)
|
||||||
matcher, err := router.NewDomainMatcher(domains)
|
matcher, err := router.NewDomainMatcher(domains)
|
||||||
mph:minimal perfect hash algorithm
|
mph:minimal perfect hash algorithm
|
||||||
*/
|
*/
|
||||||
matcher, err := router.NewMphMatcherGroup(domains)
|
matcher, err := router.NewMphMatcherGroup(domains, not)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"go.uber.org/atomic"
|
"go.uber.org/atomic"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/cache"
|
"github.com/Dreamacro/clash/common/cache"
|
||||||
|
@ -232,7 +231,7 @@ func (r *Resolver) matchPolicy(m *D.Msg) []dnsClient {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
domain := r.msgToDomain(m)
|
domain := msgToDomain(m)
|
||||||
if domain == "" {
|
if domain == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -251,7 +250,7 @@ func (r *Resolver) shouldOnlyQueryFallback(m *D.Msg) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
domain := r.msgToDomain(m)
|
domain := msgToDomain(m)
|
||||||
|
|
||||||
if domain == "" {
|
if domain == "" {
|
||||||
return false
|
return false
|
||||||
|
@ -332,14 +331,6 @@ func (r *Resolver) resolveIP(host string, dnsType uint16) (ips []netip.Addr, err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) msgToDomain(msg *D.Msg) string {
|
|
||||||
if len(msg.Question) > 0 {
|
|
||||||
return strings.TrimRight(msg.Question[0].Name, ".")
|
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Resolver) asyncExchange(ctx context.Context, client []dnsClient, msg *D.Msg) <-chan *result {
|
func (r *Resolver) asyncExchange(ctx context.Context, client []dnsClient, msg *D.Msg) <-chan *result {
|
||||||
ch := make(chan *result, 1)
|
ch := make(chan *result, 1)
|
||||||
go func() {
|
go func() {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/cache"
|
"github.com/Dreamacro/clash/common/cache"
|
||||||
|
@ -116,6 +117,14 @@ func msgToIP(msg *D.Msg) []netip.Addr {
|
||||||
return ips
|
return ips
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func msgToDomain(msg *D.Msg) string {
|
||||||
|
if len(msg.Question) > 0 {
|
||||||
|
return strings.TrimRight(msg.Question[0].Name, ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type wrapPacketConn struct {
|
type wrapPacketConn struct {
|
||||||
net.PacketConn
|
net.PacketConn
|
||||||
rAddr net.Addr
|
rAddr net.Addr
|
||||||
|
|
Loading…
Reference in a new issue