mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-12-01 02:49:41 +00:00
Implement resolve(server)
This commit is contained in:
parent
99bbdb7347
commit
bff2987a73
|
@ -50,6 +50,8 @@ type InboundContext struct {
|
|||
// Deprecated
|
||||
InboundOptions option.InboundOptions
|
||||
UDPDisableDomainUnmapping bool
|
||||
DNSServer string
|
||||
|
||||
DestinationAddresses []netip.Addr
|
||||
SourceGeoIPCode 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 {
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -185,6 +185,20 @@ func (r *Router) Lookup(ctx context.Context, domain string, strategy dns.DomainS
|
|||
cached bool
|
||||
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)
|
||||
if cached {
|
||||
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)
|
||||
metadata.Destination = M.Socksaddr{}
|
||||
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 (
|
||||
transport dns.Transport
|
||||
options dns.QueryOptions
|
||||
|
@ -220,22 +248,13 @@ func (r *Router) Lookup(ctx context.Context, domain string, strategy dns.DomainS
|
|||
addressLimit = false
|
||||
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 {
|
||||
break
|
||||
}
|
||||
printResult()
|
||||
}
|
||||
}
|
||||
printResult()
|
||||
if len(responseAddrs) > 0 {
|
||||
r.dnsLogger.InfoContext(ctx, "lookup succeed for ", domain, ": ", strings.Join(F.MapToString(responseAddrs), " "))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue