mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-21 17:46:58 -05:00
feat/fix: dns query subscriptions group by A and AAAA. fix problem that empty result would poll dns server in DoH mode
This commit is contained in:
parent
4a663f2b25
commit
7f4f8091f9
@ -12,6 +12,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
dns_feature "v2ray.com/core/features/dns"
|
||||||
|
|
||||||
"golang.org/x/net/dns/dnsmessage"
|
"golang.org/x/net/dns/dnsmessage"
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
@ -213,9 +214,13 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {
|
|||||||
|
|
||||||
if updated {
|
if updated {
|
||||||
s.ips[req.domain] = rec
|
s.ips[req.domain] = rec
|
||||||
s.pub.Publish(req.domain, nil)
|
|
||||||
}
|
}
|
||||||
|
switch req.reqType {
|
||||||
|
case dnsmessage.TypeA:
|
||||||
|
s.pub.Publish(req.domain+"4", nil)
|
||||||
|
case dnsmessage.TypeAAAA:
|
||||||
|
s.pub.Publish(req.domain+"6", nil)
|
||||||
|
}
|
||||||
s.Unlock()
|
s.Unlock()
|
||||||
common.Must(s.cleanup.Start())
|
common.Must(s.cleanup.Start())
|
||||||
}
|
}
|
||||||
@ -336,12 +341,15 @@ func (s *DoHNameServer) findIPsForDomain(domain string, option IPOption) ([]net.
|
|||||||
return nil, lastErr
|
return nil, lastErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (option.IPv4Enable && record.A != nil) || (option.IPv6Enable && record.AAAA != nil) {
|
||||||
|
return nil, dns_feature.ErrEmptyResponse
|
||||||
|
}
|
||||||
|
|
||||||
return nil, errRecordNotFound
|
return nil, errRecordNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryIP is called from dns.Server->queryIPTimeout
|
// QueryIP is called from dns.Server->queryIPTimeout
|
||||||
func (s *DoHNameServer) QueryIP(ctx context.Context, domain string, option IPOption) ([]net.IP, error) {
|
func (s *DoHNameServer) QueryIP(ctx context.Context, domain string, option IPOption) ([]net.IP, error) {
|
||||||
|
|
||||||
fqdn := Fqdn(domain)
|
fqdn := Fqdn(domain)
|
||||||
|
|
||||||
ips, err := s.findIPsForDomain(fqdn, option)
|
ips, err := s.findIPsForDomain(fqdn, option)
|
||||||
@ -350,9 +358,32 @@ func (s *DoHNameServer) QueryIP(ctx context.Context, domain string, option IPOpt
|
|||||||
return ips, err
|
return ips, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sub := s.pub.Subscribe(fqdn)
|
// ipv4 and ipv6 belong to different subscription groups
|
||||||
defer sub.Close()
|
var sub4, sub6 *pubsub.Subscriber
|
||||||
|
if option.IPv4Enable {
|
||||||
|
sub4 = s.pub.Subscribe(fqdn + "4")
|
||||||
|
defer sub4.Close()
|
||||||
|
}
|
||||||
|
if option.IPv6Enable {
|
||||||
|
sub6 = s.pub.Subscribe(fqdn + "6")
|
||||||
|
defer sub6.Close()
|
||||||
|
}
|
||||||
|
done := make(chan interface{})
|
||||||
|
go func() {
|
||||||
|
if sub4 != nil {
|
||||||
|
select {
|
||||||
|
case <-sub4.Wait():
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sub6 != nil {
|
||||||
|
select {
|
||||||
|
case <-sub6.Wait():
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
s.sendQuery(ctx, fqdn, option)
|
s.sendQuery(ctx, fqdn, option)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -364,7 +395,7 @@ func (s *DoHNameServer) QueryIP(ctx context.Context, domain string, option IPOpt
|
|||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil, ctx.Err()
|
return nil, ctx.Err()
|
||||||
case <-sub.Wait():
|
case <-done:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,9 +158,13 @@ func (s *ClassicNameServer) updateIP(domain string, newRec record) {
|
|||||||
|
|
||||||
if updated {
|
if updated {
|
||||||
s.ips[domain] = rec
|
s.ips[domain] = rec
|
||||||
s.pub.Publish(domain, nil)
|
|
||||||
}
|
}
|
||||||
|
if newRec.A != nil {
|
||||||
|
s.pub.Publish(domain+"4", nil)
|
||||||
|
}
|
||||||
|
if newRec.AAAA != nil {
|
||||||
|
s.pub.Publish(domain+"6", nil)
|
||||||
|
}
|
||||||
s.Unlock()
|
s.Unlock()
|
||||||
common.Must(s.cleanup.Start())
|
common.Must(s.cleanup.Start())
|
||||||
}
|
}
|
||||||
@ -245,9 +249,32 @@ func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, option I
|
|||||||
return ips, err
|
return ips, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sub := s.pub.Subscribe(fqdn)
|
// ipv4 and ipv6 belong to different subscription groups
|
||||||
defer sub.Close()
|
var sub4, sub6 *pubsub.Subscriber
|
||||||
|
if option.IPv4Enable {
|
||||||
|
sub4 = s.pub.Subscribe(fqdn + "4")
|
||||||
|
defer sub4.Close()
|
||||||
|
}
|
||||||
|
if option.IPv6Enable {
|
||||||
|
sub6 = s.pub.Subscribe(fqdn + "6")
|
||||||
|
defer sub6.Close()
|
||||||
|
}
|
||||||
|
done := make(chan interface{})
|
||||||
|
go func() {
|
||||||
|
if sub4 != nil {
|
||||||
|
select {
|
||||||
|
case <-sub4.Wait():
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sub6 != nil {
|
||||||
|
select {
|
||||||
|
case <-sub6.Wait():
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
s.sendQuery(ctx, fqdn, option)
|
s.sendQuery(ctx, fqdn, option)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -259,7 +286,7 @@ func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, option I
|
|||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil, ctx.Err()
|
return nil, ctx.Err()
|
||||||
case <-sub.Wait():
|
case <-done:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user