mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-15 21:00:27 +00:00
Add query_client_subnet and query_dnssec DNS rule items and remove_client_subnet DNS route action option
This commit is contained in:
+12
-6
@@ -107,12 +107,15 @@ func (k dnsCacheKey) persistentName() string {
|
||||
}
|
||||
|
||||
func (c *Client) newCacheKey(transport adapter.DNSTransport, question dns.Question, message *dns.Msg, options adapter.DNSQueryOptions) dnsCacheKey {
|
||||
clientSubnet := options.ClientSubnet
|
||||
if !clientSubnet.IsValid() {
|
||||
clientSubnet = c.clientSubnet
|
||||
}
|
||||
if !clientSubnet.IsValid() {
|
||||
clientSubnet = clientSubnetFromMessage(message)
|
||||
var clientSubnet netip.Prefix
|
||||
if !options.RemoveClientSubnet {
|
||||
clientSubnet = options.ClientSubnet
|
||||
if !clientSubnet.IsValid() {
|
||||
clientSubnet = c.clientSubnet
|
||||
}
|
||||
if !clientSubnet.IsValid() {
|
||||
clientSubnet = clientSubnetFromMessage(message)
|
||||
}
|
||||
}
|
||||
return dnsCacheKey{
|
||||
Question: question,
|
||||
@@ -679,6 +682,9 @@ func (c *Client) backgroundRefreshDNS(transport adapter.DNSTransport, key dnsCac
|
||||
}
|
||||
|
||||
func (c *Client) prepareExchangeMessage(message *dns.Msg, options adapter.DNSQueryOptions) *dns.Msg {
|
||||
if options.RemoveClientSubnet {
|
||||
return removeClientSubnet(message)
|
||||
}
|
||||
clientSubnet := options.ClientSubnet
|
||||
if !clientSubnet.IsValid() {
|
||||
clientSubnet = c.clientSubnet
|
||||
|
||||
@@ -2,6 +2,9 @@ package dns
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"slices"
|
||||
|
||||
"github.com/sagernet/sing/common"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
@@ -25,12 +28,37 @@ func clientSubnetFromMessage(message *dns.Msg) netip.Prefix {
|
||||
if !addressLoaded {
|
||||
return netip.Prefix{}
|
||||
}
|
||||
return netip.PrefixFrom(address, int(subnetOption.SourceNetmask))
|
||||
return netip.PrefixFrom(address.Unmap(), int(subnetOption.SourceNetmask))
|
||||
}
|
||||
}
|
||||
return netip.Prefix{}
|
||||
}
|
||||
|
||||
func removeClientSubnet(message *dns.Msg) *dns.Msg {
|
||||
if !slices.ContainsFunc(message.Extra, func(record dns.RR) bool {
|
||||
optRecord, isOPTRecord := record.(*dns.OPT)
|
||||
if !isOPTRecord {
|
||||
return false
|
||||
}
|
||||
return slices.ContainsFunc(optRecord.Option, func(option dns.EDNS0) bool {
|
||||
return option.Option() == dns.EDNS0SUBNET
|
||||
})
|
||||
}) {
|
||||
return message
|
||||
}
|
||||
message = message.Copy()
|
||||
for _, record := range message.Extra {
|
||||
optRecord, isOPTRecord := record.(*dns.OPT)
|
||||
if !isOPTRecord {
|
||||
continue
|
||||
}
|
||||
optRecord.Option = common.Filter(optRecord.Option, func(option dns.EDNS0) bool {
|
||||
return option.Option() != dns.EDNS0SUBNET
|
||||
})
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
func setClientSubnet(message *dns.Msg, clientSubnet netip.Prefix, clone bool) *dns.Msg {
|
||||
var (
|
||||
optRecord *dns.OPT
|
||||
|
||||
@@ -326,6 +326,11 @@ func (r *Router) matchDNS(ctx context.Context, rules []adapter.DNSRule, allowFak
|
||||
}
|
||||
if action.ClientSubnet.IsValid() {
|
||||
options.ClientSubnet = action.ClientSubnet
|
||||
options.RemoveClientSubnet = false
|
||||
}
|
||||
if action.RemoveClientSubnet {
|
||||
options.ClientSubnet = netip.Prefix{}
|
||||
options.RemoveClientSubnet = true
|
||||
}
|
||||
return transport, currentRule, currentRuleIndex
|
||||
case *R.RuleActionDNSRouteOptions:
|
||||
@@ -343,6 +348,11 @@ func (r *Router) matchDNS(ctx context.Context, rules []adapter.DNSRule, allowFak
|
||||
}
|
||||
if action.ClientSubnet.IsValid() {
|
||||
options.ClientSubnet = action.ClientSubnet
|
||||
options.RemoveClientSubnet = false
|
||||
}
|
||||
if action.RemoveClientSubnet {
|
||||
options.ClientSubnet = netip.Prefix{}
|
||||
options.RemoveClientSubnet = true
|
||||
}
|
||||
case *R.RuleActionReject:
|
||||
return nil, currentRule, currentRuleIndex
|
||||
@@ -373,6 +383,11 @@ func (r *Router) applyDNSRouteOptions(options *adapter.DNSQueryOptions, routeOpt
|
||||
}
|
||||
if routeOptions.ClientSubnet.IsValid() {
|
||||
options.ClientSubnet = routeOptions.ClientSubnet
|
||||
options.RemoveClientSubnet = false
|
||||
}
|
||||
if routeOptions.RemoveClientSubnet {
|
||||
options.ClientSubnet = netip.Prefix{}
|
||||
options.RemoveClientSubnet = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -945,6 +960,8 @@ func (r *Router) resolveLookupStrategy(options adapter.DNSQueryOptions) C.Domain
|
||||
func withLookupQueryMetadata(ctx context.Context, qType uint16) context.Context {
|
||||
ctx, metadata := adapter.ExtendContext(ctx)
|
||||
metadata.QueryType = qType
|
||||
metadata.QueryClientSubnet = netip.Prefix{}
|
||||
metadata.QueryDNSSEC = false
|
||||
metadata.IPVersion = 0
|
||||
switch qType {
|
||||
case mDNS.TypeA:
|
||||
@@ -1069,6 +1086,9 @@ func (r *Router) prepareExchange(ctx context.Context, message *mDNS.Msg) (*dnsEx
|
||||
metadata.IPVersion = 6
|
||||
}
|
||||
metadata.Domain = FqdnToDomain(message.Question[0].Name)
|
||||
metadata.QueryClientSubnet = clientSubnetFromMessage(message)
|
||||
edns0Option := message.IsEdns0()
|
||||
metadata.QueryDNSSEC = edns0Option != nil && edns0Option.Do()
|
||||
return &dnsExchangeContext{
|
||||
ctx: ctx,
|
||||
rules: rules,
|
||||
|
||||
Reference in New Issue
Block a user