mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-05-26 22:21:47 +03:00
refactor: DNS
This commit is contained in:
@@ -51,18 +51,6 @@ func (r *abstractDefaultRule) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *abstractDefaultRule) UpdateGeosite() error {
|
||||
for _, item := range r.allItems {
|
||||
if geositeItem, isSite := item.(*GeositeItem); isSite {
|
||||
err := geositeItem.Update()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *abstractDefaultRule) Match(metadata *adapter.InboundContext) bool {
|
||||
if len(r.allItems) == 0 {
|
||||
return true
|
||||
@@ -173,19 +161,6 @@ func (r *abstractLogicalRule) Type() string {
|
||||
return C.RuleTypeLogical
|
||||
}
|
||||
|
||||
func (r *abstractLogicalRule) UpdateGeosite() error {
|
||||
for _, rule := range common.FilterIsInstance(r.rules, func(it adapter.HeadlessRule) (adapter.Rule, bool) {
|
||||
rule, loaded := it.(adapter.Rule)
|
||||
return rule, loaded
|
||||
}) {
|
||||
err := rule.UpdateGeosite()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *abstractLogicalRule) Start() error {
|
||||
for _, rule := range common.FilterIsInstance(r.rules, func(it adapter.HeadlessRule) (interface {
|
||||
Start() error
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/sagernet/sing-box/common/sniff"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-dns"
|
||||
"github.com/sagernet/sing-tun"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
@@ -85,7 +84,7 @@ func NewRuleAction(ctx context.Context, logger logger.ContextLogger, action opti
|
||||
return sniffAction, sniffAction.build()
|
||||
case C.RuleActionTypeResolve:
|
||||
return &RuleActionResolve{
|
||||
Strategy: dns.DomainStrategy(action.ResolveOptions.Strategy),
|
||||
Strategy: C.DomainStrategy(action.ResolveOptions.Strategy),
|
||||
Server: action.ResolveOptions.Server,
|
||||
}, nil
|
||||
default:
|
||||
@@ -101,6 +100,7 @@ func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction)
|
||||
return &RuleActionDNSRoute{
|
||||
Server: action.RouteOptions.Server,
|
||||
RuleActionDNSRouteOptions: RuleActionDNSRouteOptions{
|
||||
Strategy: C.DomainStrategy(action.RouteOptions.Strategy),
|
||||
DisableCache: action.RouteOptions.DisableCache,
|
||||
RewriteTTL: action.RouteOptions.RewriteTTL,
|
||||
ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptions.ClientSubnet)),
|
||||
@@ -108,6 +108,7 @@ func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction)
|
||||
}
|
||||
case C.RuleActionTypeRouteOptions:
|
||||
return &RuleActionDNSRouteOptions{
|
||||
Strategy: C.DomainStrategy(action.RouteOptionsOptions.Strategy),
|
||||
DisableCache: action.RouteOptionsOptions.DisableCache,
|
||||
RewriteTTL: action.RouteOptionsOptions.RewriteTTL,
|
||||
ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptionsOptions.ClientSubnet)),
|
||||
@@ -214,6 +215,7 @@ func (r *RuleActionDNSRoute) String() string {
|
||||
}
|
||||
|
||||
type RuleActionDNSRouteOptions struct {
|
||||
Strategy C.DomainStrategy
|
||||
DisableCache bool
|
||||
RewriteTTL *uint32
|
||||
ClientSubnet netip.Prefix
|
||||
@@ -362,7 +364,7 @@ func (r *RuleActionSniff) String() string {
|
||||
}
|
||||
|
||||
type RuleActionResolve struct {
|
||||
Strategy dns.DomainStrategy
|
||||
Strategy C.DomainStrategy
|
||||
Server string
|
||||
}
|
||||
|
||||
@@ -371,11 +373,11 @@ func (r *RuleActionResolve) Type() string {
|
||||
}
|
||||
|
||||
func (r *RuleActionResolve) String() string {
|
||||
if r.Strategy == dns.DomainStrategyAsIS && r.Server == "" {
|
||||
if r.Strategy == C.DomainStrategyAsIS && r.Server == "" {
|
||||
return F.ToString("resolve")
|
||||
} else if r.Strategy != dns.DomainStrategyAsIS && r.Server == "" {
|
||||
} else if r.Strategy != C.DomainStrategyAsIS && r.Server == "" {
|
||||
return F.ToString("resolve(", option.DomainStrategy(r.Strategy).String(), ")")
|
||||
} else if r.Strategy == dns.DomainStrategyAsIS && r.Server != "" {
|
||||
} else if r.Strategy == C.DomainStrategyAsIS && r.Server != "" {
|
||||
return F.ToString("resolve(", r.Server, ")")
|
||||
} else {
|
||||
return F.ToString("resolve(", option.DomainStrategy(r.Strategy).String(), ",", r.Server, ")")
|
||||
|
||||
@@ -120,19 +120,13 @@ func NewDefaultRule(ctx context.Context, logger log.ContextLogger, options optio
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
}
|
||||
if len(options.Geosite) > 0 {
|
||||
item := NewGeositeItem(router, logger, options.Geosite)
|
||||
rule.destinationAddressItems = append(rule.destinationAddressItems, item)
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
return nil, E.New("geosite database is deprecated in sing-box 1.8.0 and removed in sing-box 1.12.0")
|
||||
}
|
||||
if len(options.SourceGeoIP) > 0 {
|
||||
item := NewGeoIPItem(router, logger, true, options.SourceGeoIP)
|
||||
rule.sourceAddressItems = append(rule.sourceAddressItems, item)
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
return nil, E.New("geoip database is deprecated in sing-box 1.8.0 and removed in sing-box 1.12.0")
|
||||
}
|
||||
if len(options.GeoIP) > 0 {
|
||||
item := NewGeoIPItem(router, logger, false, options.GeoIP)
|
||||
rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
return nil, E.New("geoip database is deprecated in sing-box 1.8.0 and removed in sing-box 1.12.0")
|
||||
}
|
||||
if len(options.SourceIPCIDR) > 0 {
|
||||
item, err := NewIPCIDRItem(true, options.SourceIPCIDR)
|
||||
|
||||
@@ -111,19 +111,13 @@ func NewDefaultDNSRule(ctx context.Context, logger log.ContextLogger, options op
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
}
|
||||
if len(options.Geosite) > 0 {
|
||||
item := NewGeositeItem(router, logger, options.Geosite)
|
||||
rule.destinationAddressItems = append(rule.destinationAddressItems, item)
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
return nil, E.New("geosite database is deprecated in sing-box 1.8.0 and removed in sing-box 1.12.0")
|
||||
}
|
||||
if len(options.SourceGeoIP) > 0 {
|
||||
item := NewGeoIPItem(router, logger, true, options.SourceGeoIP)
|
||||
rule.sourceAddressItems = append(rule.sourceAddressItems, item)
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
return nil, E.New("geoip database is deprecated in sing-box 1.8.0 and removed in sing-box 1.12.0")
|
||||
}
|
||||
if len(options.GeoIP) > 0 {
|
||||
item := NewGeoIPItem(router, logger, false, options.GeoIP)
|
||||
rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
return nil, E.New("geoip database is deprecated in sing-box 1.8.0 and removed in sing-box 1.12.0")
|
||||
}
|
||||
if len(options.SourceIPCIDR) > 0 {
|
||||
item, err := NewIPCIDRItem(true, options.SourceIPCIDR)
|
||||
@@ -151,6 +145,11 @@ func NewDefaultDNSRule(ctx context.Context, logger log.ContextLogger, options op
|
||||
rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
}
|
||||
if options.IPAcceptAny {
|
||||
item := NewIPAcceptAnyItem()
|
||||
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)
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
package rule
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
var _ RuleItem = (*GeoIPItem)(nil)
|
||||
|
||||
type GeoIPItem struct {
|
||||
router adapter.Router
|
||||
logger log.ContextLogger
|
||||
isSource bool
|
||||
codes []string
|
||||
codeMap map[string]bool
|
||||
}
|
||||
|
||||
func NewGeoIPItem(router adapter.Router, logger log.ContextLogger, isSource bool, codes []string) *GeoIPItem {
|
||||
codeMap := make(map[string]bool)
|
||||
for _, code := range codes {
|
||||
codeMap[code] = true
|
||||
}
|
||||
return &GeoIPItem{
|
||||
router: router,
|
||||
logger: logger,
|
||||
codes: codes,
|
||||
isSource: isSource,
|
||||
codeMap: codeMap,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *GeoIPItem) Match(metadata *adapter.InboundContext) bool {
|
||||
var geoipCode string
|
||||
if r.isSource && metadata.SourceGeoIPCode != "" {
|
||||
geoipCode = metadata.SourceGeoIPCode
|
||||
} else if !r.isSource && metadata.GeoIPCode != "" {
|
||||
geoipCode = metadata.GeoIPCode
|
||||
}
|
||||
if geoipCode != "" {
|
||||
return r.codeMap[geoipCode]
|
||||
}
|
||||
var destination netip.Addr
|
||||
if r.isSource {
|
||||
destination = metadata.Source.Addr
|
||||
} else {
|
||||
destination = metadata.Destination.Addr
|
||||
}
|
||||
if destination.IsValid() {
|
||||
return r.match(metadata, destination)
|
||||
}
|
||||
for _, destinationAddress := range metadata.DestinationAddresses {
|
||||
if r.match(metadata, destinationAddress) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *GeoIPItem) match(metadata *adapter.InboundContext, destination netip.Addr) bool {
|
||||
var geoipCode string
|
||||
geoReader := r.router.GeoIPReader()
|
||||
if !N.IsPublicAddr(destination) {
|
||||
geoipCode = "private"
|
||||
} else if geoReader != nil {
|
||||
geoipCode = geoReader.Lookup(destination)
|
||||
}
|
||||
if geoipCode == "" {
|
||||
return false
|
||||
}
|
||||
if r.isSource {
|
||||
metadata.SourceGeoIPCode = geoipCode
|
||||
} else {
|
||||
metadata.GeoIPCode = geoipCode
|
||||
}
|
||||
return r.codeMap[geoipCode]
|
||||
}
|
||||
|
||||
func (r *GeoIPItem) String() string {
|
||||
var description string
|
||||
if r.isSource {
|
||||
description = "source_geoip="
|
||||
} else {
|
||||
description = "geoip="
|
||||
}
|
||||
cLen := len(r.codes)
|
||||
if cLen == 1 {
|
||||
description += r.codes[0]
|
||||
} else if cLen > 3 {
|
||||
description += "[" + strings.Join(r.codes[:3], " ") + "...]"
|
||||
} else {
|
||||
description += "[" + strings.Join(r.codes, " ") + "]"
|
||||
}
|
||||
return description
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package rule
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
var _ RuleItem = (*GeositeItem)(nil)
|
||||
|
||||
type GeositeItem struct {
|
||||
router adapter.Router
|
||||
logger log.ContextLogger
|
||||
codes []string
|
||||
matchers []adapter.Rule
|
||||
}
|
||||
|
||||
func NewGeositeItem(router adapter.Router, logger log.ContextLogger, codes []string) *GeositeItem {
|
||||
return &GeositeItem{
|
||||
router: router,
|
||||
logger: logger,
|
||||
codes: codes,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *GeositeItem) Update() error {
|
||||
matchers := make([]adapter.Rule, 0, len(r.codes))
|
||||
for _, code := range r.codes {
|
||||
matcher, err := r.router.LoadGeosite(code)
|
||||
if err != nil {
|
||||
return E.Cause(err, "read geosite")
|
||||
}
|
||||
matchers = append(matchers, matcher)
|
||||
}
|
||||
r.matchers = matchers
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *GeositeItem) Match(metadata *adapter.InboundContext) bool {
|
||||
for _, matcher := range r.matchers {
|
||||
if matcher.Match(metadata) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *GeositeItem) String() string {
|
||||
description := "geosite="
|
||||
cLen := len(r.codes)
|
||||
if cLen == 1 {
|
||||
description += r.codes[0]
|
||||
} else if cLen > 3 {
|
||||
description += "[" + strings.Join(r.codes[:3], " ") + "...]"
|
||||
} else {
|
||||
description += "[" + strings.Join(r.codes, " ") + "]"
|
||||
}
|
||||
return description
|
||||
}
|
||||
21
route/rule/rule_item_ip_accept_any.go
Normal file
21
route/rule/rule_item_ip_accept_any.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package rule
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
)
|
||||
|
||||
var _ RuleItem = (*IPAcceptAnyItem)(nil)
|
||||
|
||||
type IPAcceptAnyItem struct{}
|
||||
|
||||
func NewIPAcceptAnyItem() *IPAcceptAnyItem {
|
||||
return &IPAcceptAnyItem{}
|
||||
}
|
||||
|
||||
func (r *IPAcceptAnyItem) Match(metadata *adapter.InboundContext) bool {
|
||||
return len(metadata.DestinationAddresses) > 0
|
||||
}
|
||||
|
||||
func (r *IPAcceptAnyItem) String() string {
|
||||
return "ip_accept_any=true"
|
||||
}
|
||||
Reference in New Issue
Block a user