mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 08:31:30 +00:00
Implement resolve(server)
This commit is contained in:
parent
24db6e4e31
commit
82586eac1d
|
@ -50,6 +50,8 @@ type InboundContext struct {
|
||||||
// Deprecated
|
// Deprecated
|
||||||
InboundOptions option.InboundOptions
|
InboundOptions option.InboundOptions
|
||||||
UDPDisableDomainUnmapping bool
|
UDPDisableDomainUnmapping bool
|
||||||
|
DNSServer string
|
||||||
|
|
||||||
DestinationAddresses []netip.Addr
|
DestinationAddresses []netip.Addr
|
||||||
SourceGeoIPCode string
|
SourceGeoIPCode string
|
||||||
GeoIPCode string
|
GeoIPCode string
|
||||||
|
|
|
@ -584,7 +584,7 @@ func (r *Router) actionSniff(
|
||||||
|
|
||||||
func (r *Router) actionResolve(ctx context.Context, metadata *adapter.InboundContext, action *rule.RuleActionResolve) error {
|
func (r *Router) actionResolve(ctx context.Context, metadata *adapter.InboundContext, action *rule.RuleActionResolve) error {
|
||||||
if metadata.Destination.IsFqdn() {
|
if metadata.Destination.IsFqdn() {
|
||||||
// TODO: check if WithContext is necessary
|
metadata.DNSServer = action.Server
|
||||||
addresses, err := r.Lookup(adapter.WithContext(ctx, metadata), metadata.Destination.Fqdn, action.Strategy)
|
addresses, err := r.Lookup(adapter.WithContext(ctx, metadata), metadata.Destination.Fqdn, action.Strategy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -185,6 +185,20 @@ func (r *Router) Lookup(ctx context.Context, domain string, strategy dns.DomainS
|
||||||
cached bool
|
cached bool
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
printResult := func() {
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, dns.ErrResponseRejectedCached) {
|
||||||
|
r.dnsLogger.DebugContext(ctx, "response rejected for ", domain, " (cached)")
|
||||||
|
} else if errors.Is(err, dns.ErrResponseRejected) {
|
||||||
|
r.dnsLogger.DebugContext(ctx, "response rejected for ", domain)
|
||||||
|
} else {
|
||||||
|
r.dnsLogger.ErrorContext(ctx, E.Cause(err, "lookup failed for ", domain))
|
||||||
|
}
|
||||||
|
} else if len(responseAddrs) == 0 {
|
||||||
|
r.dnsLogger.ErrorContext(ctx, "lookup failed for ", domain, ": empty result")
|
||||||
|
err = dns.RCodeNameError
|
||||||
|
}
|
||||||
|
}
|
||||||
responseAddrs, cached = r.dnsClient.LookupCache(ctx, domain, strategy)
|
responseAddrs, cached = r.dnsClient.LookupCache(ctx, domain, strategy)
|
||||||
if cached {
|
if cached {
|
||||||
if len(responseAddrs) == 0 {
|
if len(responseAddrs) == 0 {
|
||||||
|
@ -196,6 +210,20 @@ func (r *Router) Lookup(ctx context.Context, domain string, strategy dns.DomainS
|
||||||
ctx, metadata := adapter.ExtendContext(ctx)
|
ctx, metadata := adapter.ExtendContext(ctx)
|
||||||
metadata.Destination = M.Socksaddr{}
|
metadata.Destination = M.Socksaddr{}
|
||||||
metadata.Domain = domain
|
metadata.Domain = domain
|
||||||
|
if metadata.DNSServer != "" {
|
||||||
|
transport, loaded := r.transportMap[metadata.DNSServer]
|
||||||
|
if !loaded {
|
||||||
|
return nil, E.New("transport not found: ", metadata.DNSServer)
|
||||||
|
}
|
||||||
|
if strategy == dns.DomainStrategyAsIS {
|
||||||
|
if transportDomainStrategy, loaded := r.transportDomainStrategy[transport]; loaded {
|
||||||
|
strategy = transportDomainStrategy
|
||||||
|
} else {
|
||||||
|
strategy = r.defaultDomainStrategy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responseAddrs, err = r.dnsClient.Lookup(ctx, transport, domain, dns.QueryOptions{Strategy: strategy})
|
||||||
|
} else {
|
||||||
var (
|
var (
|
||||||
transport dns.Transport
|
transport dns.Transport
|
||||||
options dns.QueryOptions
|
options dns.QueryOptions
|
||||||
|
@ -220,22 +248,13 @@ func (r *Router) Lookup(ctx context.Context, domain string, strategy dns.DomainS
|
||||||
addressLimit = false
|
addressLimit = false
|
||||||
responseAddrs, err = r.dnsClient.Lookup(dnsCtx, transport, domain, options)
|
responseAddrs, err = r.dnsClient.Lookup(dnsCtx, transport, domain, options)
|
||||||
}
|
}
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, dns.ErrResponseRejectedCached) {
|
|
||||||
r.dnsLogger.DebugContext(ctx, "response rejected for ", domain, " (cached)")
|
|
||||||
} else if errors.Is(err, dns.ErrResponseRejected) {
|
|
||||||
r.dnsLogger.DebugContext(ctx, "response rejected for ", domain)
|
|
||||||
} else {
|
|
||||||
r.dnsLogger.ErrorContext(ctx, E.Cause(err, "lookup failed for ", domain))
|
|
||||||
}
|
|
||||||
} else if len(responseAddrs) == 0 {
|
|
||||||
r.dnsLogger.ErrorContext(ctx, "lookup failed for ", domain, ": empty result")
|
|
||||||
err = dns.RCodeNameError
|
|
||||||
}
|
|
||||||
if !addressLimit || err == nil {
|
if !addressLimit || err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
printResult()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
printResult()
|
||||||
if len(responseAddrs) > 0 {
|
if len(responseAddrs) > 0 {
|
||||||
r.dnsLogger.InfoContext(ctx, "lookup succeed for ", domain, ": ", strings.Join(F.MapToString(responseAddrs), " "))
|
r.dnsLogger.InfoContext(ctx, "lookup succeed for ", domain, ": ", strings.Join(F.MapToString(responseAddrs), " "))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue