mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-30 09:18:34 +00:00
DNS: Support returning upstream TTL to clients (#4526)
Closes https://github.com/XTLS/Xray-core/issues/4527
This commit is contained in:
parent
2d3210e4b8
commit
4afe2d0cff
24 changed files with 168 additions and 157 deletions
|
@ -230,60 +230,62 @@ func (s *ClassicNameServer) sendQuery(ctx context.Context, domain string, client
|
|||
}
|
||||
}
|
||||
|
||||
func (s *ClassicNameServer) findIPsForDomain(domain string, option dns_feature.IPOption) ([]net.IP, error) {
|
||||
func (s *ClassicNameServer) findIPsForDomain(domain string, option dns_feature.IPOption) ([]net.IP, uint32, error) {
|
||||
s.RLock()
|
||||
record, found := s.ips[domain]
|
||||
s.RUnlock()
|
||||
|
||||
if !found {
|
||||
return nil, errRecordNotFound
|
||||
return nil, 0, errRecordNotFound
|
||||
}
|
||||
|
||||
var err4 error
|
||||
var err6 error
|
||||
var ips []net.Address
|
||||
var ip6 []net.Address
|
||||
var ttl uint32
|
||||
|
||||
if option.IPv4Enable {
|
||||
ips, err4 = record.A.getIPs()
|
||||
ips, ttl, err4 = record.A.getIPs()
|
||||
}
|
||||
|
||||
if option.IPv6Enable {
|
||||
ip6, err6 = record.AAAA.getIPs()
|
||||
ip6, ttl, err6 = record.AAAA.getIPs()
|
||||
ips = append(ips, ip6...)
|
||||
}
|
||||
|
||||
if len(ips) > 0 {
|
||||
return toNetIP(ips)
|
||||
netips, err := toNetIP(ips)
|
||||
return netips, ttl, err
|
||||
}
|
||||
|
||||
if err4 != nil {
|
||||
return nil, err4
|
||||
return nil, 0, err4
|
||||
}
|
||||
|
||||
if err6 != nil {
|
||||
return nil, err6
|
||||
return nil, 0, err6
|
||||
}
|
||||
|
||||
return nil, dns_feature.ErrEmptyResponse
|
||||
return nil, 0, dns_feature.ErrEmptyResponse
|
||||
}
|
||||
|
||||
// QueryIP implements Server.
|
||||
func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption, disableCache bool) ([]net.IP, error) {
|
||||
func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption, disableCache bool) ([]net.IP, uint32, error) {
|
||||
fqdn := Fqdn(domain)
|
||||
option = ResolveIpOptionOverride(s.queryStrategy, option)
|
||||
if !option.IPv4Enable && !option.IPv6Enable {
|
||||
return nil, dns_feature.ErrEmptyResponse
|
||||
return nil, 0, dns_feature.ErrEmptyResponse
|
||||
}
|
||||
|
||||
if disableCache {
|
||||
errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name)
|
||||
} else {
|
||||
ips, err := s.findIPsForDomain(fqdn, option)
|
||||
ips, ttl, err := s.findIPsForDomain(fqdn, option)
|
||||
if err == nil || err == dns_feature.ErrEmptyResponse {
|
||||
errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips)
|
||||
log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
|
||||
return ips, err
|
||||
return ips, ttl, err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,15 +319,15 @@ func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, clientIP
|
|||
start := time.Now()
|
||||
|
||||
for {
|
||||
ips, err := s.findIPsForDomain(fqdn, option)
|
||||
ips, ttl, err := s.findIPsForDomain(fqdn, option)
|
||||
if err != errRecordNotFound {
|
||||
log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSQueried, Elapsed: time.Since(start), Error: err})
|
||||
return ips, err
|
||||
return ips, ttl, err
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
return nil, 0, ctx.Err()
|
||||
case <-done:
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue