Add address filter support for DNS rules

This commit is contained in:
世界
2024-02-03 17:45:27 +08:00
parent 234ea4261e
commit 2838e702d9
14 changed files with 282 additions and 69 deletions

View File

@@ -5,6 +5,7 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
@@ -111,6 +112,11 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
rule.sourceAddressItems = append(rule.sourceAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.GeoIP) > 0 {
item := NewGeoIPItem(router, logger, false, options.GeoIP)
rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.SourceIPCIDR) > 0 {
item, err := NewIPCIDRItem(true, options.SourceIPCIDR)
if err != nil {
@@ -119,11 +125,24 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
rule.sourceAddressItems = append(rule.sourceAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.IPCIDR) > 0 {
item, err := NewIPCIDRItem(false, options.IPCIDR)
if err != nil {
return nil, E.Cause(err, "ip_cidr")
}
rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
rule.allItems = append(rule.allItems, item)
}
if options.SourceIPIsPrivate {
item := NewIPIsPrivateItem(true)
rule.sourceAddressItems = append(rule.sourceAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
if options.IPIsPrivate {
item := NewIPIsPrivateItem(false)
rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.SourcePort) > 0 {
item := NewPortItem(true, options.SourcePort)
rule.sourcePortItems = append(rule.sourcePortItems, item)
@@ -211,6 +230,34 @@ func (r *DefaultDNSRule) RewriteTTL() *uint32 {
return r.rewriteTTL
}
func (r *DefaultDNSRule) WithAddressLimit() bool {
if len(r.destinationIPCIDRItems) > 0 {
return true
}
for _, rawRule := range r.items {
ruleSet, isRuleSet := rawRule.(*RuleSetItem)
if !isRuleSet {
continue
}
if ruleSet.ContainsIPCIDRRule() {
return true
}
}
return false
}
func (r *DefaultDNSRule) Match(metadata *adapter.InboundContext) bool {
metadata.IgnoreDestinationIPCIDRMatch = true
defer func() {
metadata.IgnoreDestinationIPCIDRMatch = false
}()
return r.abstractDefaultRule.Match(metadata)
}
func (r *DefaultDNSRule) MatchAddressLimit(metadata *adapter.InboundContext) bool {
return r.abstractDefaultRule.Match(metadata)
}
var _ adapter.DNSRule = (*LogicalDNSRule)(nil)
type LogicalDNSRule struct {
@@ -254,3 +301,47 @@ func (r *LogicalDNSRule) DisableCache() bool {
func (r *LogicalDNSRule) RewriteTTL() *uint32 {
return r.rewriteTTL
}
func (r *LogicalDNSRule) WithAddressLimit() bool {
for _, rawRule := range r.rules {
switch rule := rawRule.(type) {
case *DefaultDNSRule:
if rule.WithAddressLimit() {
return true
}
case *LogicalDNSRule:
if rule.WithAddressLimit() {
return true
}
}
}
return false
}
func (r *LogicalDNSRule) Match(metadata *adapter.InboundContext) bool {
if r.mode == C.LogicalTypeAnd {
return common.All(r.rules, func(it adapter.HeadlessRule) bool {
metadata.ResetRuleCache()
return it.(adapter.DNSRule).Match(metadata)
}) != r.invert
} else {
return common.Any(r.rules, func(it adapter.HeadlessRule) bool {
metadata.ResetRuleCache()
return it.(adapter.DNSRule).Match(metadata)
}) != r.invert
}
}
func (r *LogicalDNSRule) MatchAddressLimit(metadata *adapter.InboundContext) bool {
if r.mode == C.LogicalTypeAnd {
return common.All(r.rules, func(it adapter.HeadlessRule) bool {
metadata.ResetRuleCache()
return it.(adapter.DNSRule).MatchAddressLimit(metadata)
}) != r.invert
} else {
return common.Any(r.rules, func(it adapter.HeadlessRule) bool {
metadata.ResetRuleCache()
return it.(adapter.DNSRule).MatchAddressLimit(metadata)
}) != r.invert
}
}