From 0b2b84c89f12043af9eb554f3a98d503b15afb70 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 07:59:25 +0800 Subject: [PATCH 01/18] nil check on []ip length --- app/dns/nameserver_doh.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/dns/nameserver_doh.go b/app/dns/nameserver_doh.go index 5b471ab65fa..d81c29276ea 100644 --- a/app/dns/nameserver_doh.go +++ b/app/dns/nameserver_doh.go @@ -140,6 +140,13 @@ func (s *DoHNameServer) Cleanup() error { } for domain, record := range s.ips { + if len(record.A.IP) == 0 { + record.A = nil + } + if len(record.AAAA.IP) == 0 { + record.AAAA = nil + } + if record.A != nil && record.A.Expire.Before(now) { record.A = nil } From a860aa9b0232da19168d6cd4981015758800b2a8 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 08:07:58 +0800 Subject: [PATCH 02/18] useless --- app/dns/nameserver_doh.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/dns/nameserver_doh.go b/app/dns/nameserver_doh.go index d81c29276ea..42360a07653 100644 --- a/app/dns/nameserver_doh.go +++ b/app/dns/nameserver_doh.go @@ -162,10 +162,6 @@ func (s *DoHNameServer) Cleanup() error { } } - if len(s.ips) == 0 { - s.ips = make(map[string]record) - } - return nil } From e5bdf0da2cb9127362ddd8f7039cb7cf6a5577c7 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 08:11:14 +0800 Subject: [PATCH 03/18] typo --- app/dns/dnscommon.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dns/dnscommon.go b/app/dns/dnscommon.go index 239e04c2101..07907b1ba53 100644 --- a/app/dns/dnscommon.go +++ b/app/dns/dnscommon.go @@ -213,7 +213,7 @@ L: case dnsmessage.TypeAAAA: ans, err := parser.AAAAResource() if err != nil { - newError("failed to parse A record for domain: ", ah.Name).Base(err).WriteToLog() + newError("failed to parse AAAA record for domain: ", ah.Name).Base(err).WriteToLog() break L } ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.AAAA[:])) From b05150935b842a0f7d4a829f8c86c72425f15dbd Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 08:13:01 +0800 Subject: [PATCH 04/18] nil check on returned ips --- app/dns/dnscommon.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dns/dnscommon.go b/app/dns/dnscommon.go index 07907b1ba53..5d22adf98dd 100644 --- a/app/dns/dnscommon.go +++ b/app/dns/dnscommon.go @@ -205,14 +205,14 @@ L: switch ah.Type { case dnsmessage.TypeA: ans, err := parser.AResource() - if err != nil { + if err != nil || len(ans.A) == 0 { newError("failed to parse A record for domain: ", ah.Name).Base(err).WriteToLog() break L } ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.A[:])) case dnsmessage.TypeAAAA: ans, err := parser.AAAAResource() - if err != nil { + if err != nil || len(ans.AAAA) == 0 { newError("failed to parse AAAA record for domain: ", ah.Name).Base(err).WriteToLog() break L } From a84d5e5267c7ff6532d7ca4e8d6aebf426390b25 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 08:16:26 +0800 Subject: [PATCH 05/18] revert --- app/dns/dnscommon.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dns/dnscommon.go b/app/dns/dnscommon.go index 5d22adf98dd..07907b1ba53 100644 --- a/app/dns/dnscommon.go +++ b/app/dns/dnscommon.go @@ -205,14 +205,14 @@ L: switch ah.Type { case dnsmessage.TypeA: ans, err := parser.AResource() - if err != nil || len(ans.A) == 0 { + if err != nil { newError("failed to parse A record for domain: ", ah.Name).Base(err).WriteToLog() break L } ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.A[:])) case dnsmessage.TypeAAAA: ans, err := parser.AAAAResource() - if err != nil || len(ans.AAAA) == 0 { + if err != nil { newError("failed to parse AAAA record for domain: ", ah.Name).Base(err).WriteToLog() break L } From fa7482753ee2ba81649a14a62752daa798fd8a6a Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 08:20:42 +0800 Subject: [PATCH 06/18] check found --- app/dns/nameserver_doh.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/dns/nameserver_doh.go b/app/dns/nameserver_doh.go index 42360a07653..22fe947ae95 100644 --- a/app/dns/nameserver_doh.go +++ b/app/dns/nameserver_doh.go @@ -169,7 +169,10 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { elapsed := time.Since(req.start) s.Lock() - rec := s.ips[req.domain] + rec, found := s.ips[req.domain] + if !found { + rec = record{} + } updated := false switch req.reqType { From 12f3170b341186b2aee959e7cccac08413c5bb40 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 08:30:47 +0800 Subject: [PATCH 07/18] fix the nil check --- app/dns/nameserver_doh.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dns/nameserver_doh.go b/app/dns/nameserver_doh.go index 22fe947ae95..2e08328596c 100644 --- a/app/dns/nameserver_doh.go +++ b/app/dns/nameserver_doh.go @@ -140,10 +140,10 @@ func (s *DoHNameServer) Cleanup() error { } for domain, record := range s.ips { - if len(record.A.IP) == 0 { + if record.A != nil && len(record.A.IP) == 0 { record.A = nil } - if len(record.AAAA.IP) == 0 { + if record.AAAA != nil && len(record.AAAA.IP) == 0 { record.AAAA = nil } From 13d03f5d9ebf10c77bb4d9ff68bd60fd3b0ce602 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 08:37:46 +0800 Subject: [PATCH 08/18] fix the check found --- app/dns/nameserver_doh.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dns/nameserver_doh.go b/app/dns/nameserver_doh.go index 2e08328596c..742612f8254 100644 --- a/app/dns/nameserver_doh.go +++ b/app/dns/nameserver_doh.go @@ -177,7 +177,7 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { switch req.reqType { case dnsmessage.TypeA: - if isNewer(rec.A, ipRec) { + if rec.A == nil || isNewer(rec.A, ipRec) { rec.A = ipRec updated = true } @@ -189,7 +189,7 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { } } ipRec.IP = addr - if isNewer(rec.AAAA, ipRec) { + if rec.AAAA == nil || isNewer(rec.AAAA, ipRec) { rec.AAAA = ipRec updated = true } From a8d42898b7a29abcaaf848962ca5dacfd4a6cff4 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 08:39:42 +0800 Subject: [PATCH 09/18] revert --- app/dns/nameserver_doh.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dns/nameserver_doh.go b/app/dns/nameserver_doh.go index 742612f8254..2e08328596c 100644 --- a/app/dns/nameserver_doh.go +++ b/app/dns/nameserver_doh.go @@ -177,7 +177,7 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { switch req.reqType { case dnsmessage.TypeA: - if rec.A == nil || isNewer(rec.A, ipRec) { + if isNewer(rec.A, ipRec) { rec.A = ipRec updated = true } @@ -189,7 +189,7 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { } } ipRec.IP = addr - if rec.AAAA == nil || isNewer(rec.AAAA, ipRec) { + if isNewer(rec.AAAA, ipRec) { rec.AAAA = ipRec updated = true } From 29e35c0a061fa33c86c7ada8d9496a72f65aa5bb Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 08:45:29 +0800 Subject: [PATCH 10/18] use non-nil ips --- app/dns/nameserver_doh.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dns/nameserver_doh.go b/app/dns/nameserver_doh.go index 2e08328596c..576ac742a77 100644 --- a/app/dns/nameserver_doh.go +++ b/app/dns/nameserver_doh.go @@ -196,7 +196,7 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { } newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog() - if updated { + if updated && len(ipRec.IP) > 0 { s.ips[req.domain] = rec } switch req.reqType { From c38ff1d915d9a372f9a34a80a4791ae9b07e8dce Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 08:55:04 +0800 Subject: [PATCH 11/18] Update nameserver_quic.go --- app/dns/nameserver_quic.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/dns/nameserver_quic.go b/app/dns/nameserver_quic.go index 7854a5a3ea0..18d202f49ce 100644 --- a/app/dns/nameserver_quic.go +++ b/app/dns/nameserver_quic.go @@ -86,6 +86,13 @@ func (s *QUICNameServer) Cleanup() error { } for domain, record := range s.ips { + if record.A != nil && len(record.A.IP) == 0 { + record.A = nil + } + if record.AAAA != nil && len(record.AAAA.IP) == 0 { + record.AAAA = nil + } + if record.A != nil && record.A.Expire.Before(now) { record.A = nil } @@ -101,10 +108,6 @@ func (s *QUICNameServer) Cleanup() error { } } - if len(s.ips) == 0 { - s.ips = make(map[string]record) - } - return nil } @@ -112,7 +115,10 @@ func (s *QUICNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { elapsed := time.Since(req.start) s.Lock() - rec := s.ips[req.domain] + rec, found := s.ips[req.domain] + if !found { + rec = record{} + } updated := false switch req.reqType { @@ -136,7 +142,7 @@ func (s *QUICNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { } newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog() - if updated { + if updated && len(ipRec.IP) > 0 { s.ips[req.domain] = rec } switch req.reqType { From 409241e26473474ab74251d40ce8e2349c780db9 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 09:00:26 +0800 Subject: [PATCH 12/18] Update nameserver_tcp.go --- app/dns/nameserver_tcp.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/dns/nameserver_tcp.go b/app/dns/nameserver_tcp.go index f3987afdd80..7228991a64c 100644 --- a/app/dns/nameserver_tcp.go +++ b/app/dns/nameserver_tcp.go @@ -114,6 +114,13 @@ func (s *TCPNameServer) Cleanup() error { } for domain, record := range s.ips { + if record.A != nil && len(record.A.IP) == 0 { + record.A = nil + } + if record.AAAA != nil && len(record.AAAA.IP) == 0 { + record.AAAA = nil + } + if record.A != nil && record.A.Expire.Before(now) { record.A = nil } @@ -129,10 +136,6 @@ func (s *TCPNameServer) Cleanup() error { } } - if len(s.ips) == 0 { - s.ips = make(map[string]record) - } - return nil } @@ -140,7 +143,10 @@ func (s *TCPNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { elapsed := time.Since(req.start) s.Lock() - rec := s.ips[req.domain] + rec, found := s.ips[req.domain] + if !found { + rec = record{} + } updated := false switch req.reqType { @@ -164,7 +170,7 @@ func (s *TCPNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { } newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog() - if updated { + if updated && len(ipRec) > 0 { s.ips[req.domain] = rec } switch req.reqType { From 767dfd4356534824c5cc1d7484223335b7ff59dd Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 09:05:53 +0800 Subject: [PATCH 13/18] Update nameserver_udp.go --- app/dns/nameserver_udp.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/dns/nameserver_udp.go b/app/dns/nameserver_udp.go index 8fcc558ab65..0dab3d45946 100644 --- a/app/dns/nameserver_udp.go +++ b/app/dns/nameserver_udp.go @@ -76,6 +76,13 @@ func (s *ClassicNameServer) Cleanup() error { } for domain, record := range s.ips { + if record.A != nil && len(record.A.IP) == 0 { + record.A = nil + } + if record.AAAA != nil && len(record.AAAA.IP) == 0 { + record.AAAA = nil + } + if record.A != nil && record.A.Expire.Before(now) { record.A = nil } @@ -90,10 +97,6 @@ func (s *ClassicNameServer) Cleanup() error { } } - if len(s.ips) == 0 { - s.ips = make(map[string]record) - } - for id, req := range s.requests { if req.expire.Before(now) { delete(s.requests, id) @@ -147,7 +150,10 @@ func (s *ClassicNameServer) updateIP(domain string, newRec record) { s.Lock() newError(s.name, " updating IP records for domain:", domain).AtDebug().WriteToLog() - rec := s.ips[domain] + rec, found := s.ips[domain] + if !found { + rec = record{} + } updated := false if isNewer(rec.A, newRec.A) { @@ -159,7 +165,7 @@ func (s *ClassicNameServer) updateIP(domain string, newRec record) { updated = true } - if updated { + if updated && len(newRec.IP) > 0 { s.ips[domain] = rec } if newRec.A != nil { From d9bf2674d40f46c7f661050bdbf5713a0a20bc9c Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 09:10:41 +0800 Subject: [PATCH 14/18] Update nameserver_udp.go --- app/dns/nameserver_udp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dns/nameserver_udp.go b/app/dns/nameserver_udp.go index 0dab3d45946..f319ebc8db7 100644 --- a/app/dns/nameserver_udp.go +++ b/app/dns/nameserver_udp.go @@ -165,7 +165,7 @@ func (s *ClassicNameServer) updateIP(domain string, newRec record) { updated = true } - if updated && len(newRec.IP) > 0 { + if updated && (len(newRec.A.IP) > 0 || len(newRec.AAAA.IP) > 0) { s.ips[domain] = rec } if newRec.A != nil { From 6cc9948a2cc76da3ad861b4011db7bd46a4e719d Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 09:18:14 +0800 Subject: [PATCH 15/18] Update nameserver_tcp.go --- app/dns/nameserver_tcp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dns/nameserver_tcp.go b/app/dns/nameserver_tcp.go index 7228991a64c..f3a10714493 100644 --- a/app/dns/nameserver_tcp.go +++ b/app/dns/nameserver_tcp.go @@ -170,7 +170,7 @@ func (s *TCPNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { } newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog() - if updated && len(ipRec) > 0 { + if updated && len(ipRec.IP) > 0 { s.ips[req.domain] = rec } switch req.reqType { From a379dbd28e53bf34ab4fa76f6b3f1998546aac18 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 09:34:40 +0800 Subject: [PATCH 16/18] Update nameserver_udp.go --- app/dns/nameserver_udp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dns/nameserver_udp.go b/app/dns/nameserver_udp.go index f319ebc8db7..939ca7905c3 100644 --- a/app/dns/nameserver_udp.go +++ b/app/dns/nameserver_udp.go @@ -165,7 +165,7 @@ func (s *ClassicNameServer) updateIP(domain string, newRec record) { updated = true } - if updated && (len(newRec.A.IP) > 0 || len(newRec.AAAA.IP) > 0) { + if updated && ((newRec.A != nil && len(newRec.A.IP) > 0) || (newRec.AAAA != nil && len(newRec.AAAA.IP) > 0)) { s.ips[domain] = rec } if newRec.A != nil { From 38721723be0ed84f4bb7a51f20c737ec4f5bbe1a Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Wed, 4 Aug 2021 09:49:53 +0800 Subject: [PATCH 17/18] Update nameserver_udp.go --- app/dns/nameserver_udp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dns/nameserver_udp.go b/app/dns/nameserver_udp.go index 939ca7905c3..0252e4e04f0 100644 --- a/app/dns/nameserver_udp.go +++ b/app/dns/nameserver_udp.go @@ -149,7 +149,6 @@ func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_prot func (s *ClassicNameServer) updateIP(domain string, newRec record) { s.Lock() - newError(s.name, " updating IP records for domain:", domain).AtDebug().WriteToLog() rec, found := s.ips[domain] if !found { rec = record{} @@ -166,6 +165,7 @@ func (s *ClassicNameServer) updateIP(domain string, newRec record) { } if updated && ((newRec.A != nil && len(newRec.A.IP) > 0) || (newRec.AAAA != nil && len(newRec.AAAA.IP) > 0)) { + newError(s.name, " updating IP records for domain:", domain).AtDebug().WriteToLog() s.ips[domain] = rec } if newRec.A != nil { From b08d67f60748fc404cd6219bf3ef4f3d4c026e20 Mon Sep 17 00:00:00 2001 From: loyalsoldier <10487845+Loyalsoldier@users.noreply.github.com> Date: Tue, 10 Aug 2021 06:46:22 +0800 Subject: [PATCH 18/18] Refine DNS --- app/dns/nameserver_doh.go | 55 +++++++++++++---------------- app/dns/nameserver_quic.go | 57 +++++++++++++----------------- app/dns/nameserver_tcp.go | 61 +++++++++++++++----------------- app/dns/nameserver_udp.go | 72 ++++++++++++++++++-------------------- 4 files changed, 113 insertions(+), 132 deletions(-) diff --git a/app/dns/nameserver_doh.go b/app/dns/nameserver_doh.go index 576ac742a77..3faec7e2cd5 100644 --- a/app/dns/nameserver_doh.go +++ b/app/dns/nameserver_doh.go @@ -32,7 +32,7 @@ import ( // thus most of the DOH implementation is copied from udpns.go type DoHNameServer struct { sync.RWMutex - ips map[string]record + ips map[string]*record pub *pubsub.Service cleanup *task.Periodic reqID uint32 @@ -112,7 +112,7 @@ func NewDoHLocalNameServer(url *url.URL) *DoHNameServer { func baseDOHNameServer(url *url.URL, prefix string) *DoHNameServer { s := &DoHNameServer{ - ips: make(map[string]record), + ips: make(map[string]*record), pub: pubsub.NewService(), name: prefix + "//" + url.Host, dohURL: url.String(), @@ -140,13 +140,6 @@ func (s *DoHNameServer) Cleanup() error { } for domain, record := range s.ips { - if record.A != nil && len(record.A.IP) == 0 { - record.A = nil - } - if record.AAAA != nil && len(record.AAAA.IP) == 0 { - record.AAAA = nil - } - if record.A != nil && record.A.Expire.Before(now) { record.A = nil } @@ -162,6 +155,10 @@ func (s *DoHNameServer) Cleanup() error { } } + if len(s.ips) == 0 { + s.ips = make(map[string]*record) + } + return nil } @@ -171,7 +168,7 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { s.Lock() rec, found := s.ips[req.domain] if !found { - rec = record{} + rec = &record{} } updated := false @@ -182,7 +179,7 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { updated = true } case dnsmessage.TypeAAAA: - addr := make([]net.Address, 0) + addr := make([]net.Address, 0, len(ipRec.IP)) for _, ip := range ipRec.IP { if len(ip.IP()) == net.IPv6len { addr = append(addr, ip) @@ -196,7 +193,7 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { } newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog() - if updated && len(ipRec.IP) > 0 { + if updated { s.ips[req.domain] = rec } switch req.reqType { @@ -301,34 +298,30 @@ func (s *DoHNameServer) findIPsForDomain(domain string, option dns_feature.IPOpt return nil, errRecordNotFound } + var err4 error + var err6 error var ips []net.Address - var lastErr error - if option.IPv6Enable && record.AAAA != nil && record.AAAA.RCode == dnsmessage.RCodeSuccess { - aaaa, err := record.AAAA.getIPs() - if err != nil { - lastErr = err - } - ips = append(ips, aaaa...) - } - - if option.IPv4Enable && record.A != nil && record.A.RCode == dnsmessage.RCodeSuccess { - a, err := record.A.getIPs() - if err != nil { - lastErr = err - } - ips = append(ips, a...) + var ip6 []net.Address + + switch { + case option.IPv4Enable: + ips, err4 = record.A.getIPs() + fallthrough + case option.IPv6Enable: + ip6, err6 = record.AAAA.getIPs() + ips = append(ips, ip6...) } if len(ips) > 0 { return toNetIP(ips) } - if lastErr != nil { - return nil, lastErr + if err4 != nil { + return nil, err4 } - if (option.IPv4Enable && record.A != nil) || (option.IPv6Enable && record.AAAA != nil) { - return nil, dns_feature.ErrEmptyResponse + if err6 != nil { + return nil, err6 } return nil, errRecordNotFound diff --git a/app/dns/nameserver_quic.go b/app/dns/nameserver_quic.go index 18d202f49ce..1394dc151a6 100644 --- a/app/dns/nameserver_quic.go +++ b/app/dns/nameserver_quic.go @@ -33,12 +33,12 @@ const handshakeIdleTimeout = time.Second * 8 // QUICNameServer implemented DNS over QUIC type QUICNameServer struct { sync.RWMutex - ips map[string]record + ips map[string]*record pub *pubsub.Service cleanup *task.Periodic reqID uint32 name string - destination net.Destination + destination *net.Destination session quic.Session } @@ -57,10 +57,10 @@ func NewQUICNameServer(url *url.URL) (*QUICNameServer, error) { dest := net.UDPDestination(net.DomainAddress(url.Hostname()), port) s := &QUICNameServer{ - ips: make(map[string]record), + ips: make(map[string]*record), pub: pubsub.NewService(), name: url.String(), - destination: dest, + destination: &dest, } s.cleanup = &task.Periodic{ Interval: time.Minute, @@ -86,13 +86,6 @@ func (s *QUICNameServer) Cleanup() error { } for domain, record := range s.ips { - if record.A != nil && len(record.A.IP) == 0 { - record.A = nil - } - if record.AAAA != nil && len(record.AAAA.IP) == 0 { - record.AAAA = nil - } - if record.A != nil && record.A.Expire.Before(now) { record.A = nil } @@ -108,6 +101,10 @@ func (s *QUICNameServer) Cleanup() error { } } + if len(s.ips) == 0 { + s.ips = make(map[string]*record) + } + return nil } @@ -117,7 +114,7 @@ func (s *QUICNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { s.Lock() rec, found := s.ips[req.domain] if !found { - rec = record{} + rec = &record{} } updated := false @@ -142,7 +139,7 @@ func (s *QUICNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { } newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog() - if updated && len(ipRec.IP) > 0 { + if updated { s.ips[req.domain] = rec } switch req.reqType { @@ -238,34 +235,30 @@ func (s *QUICNameServer) findIPsForDomain(domain string, option dns_feature.IPOp return nil, errRecordNotFound } + var err4 error + var err6 error var ips []net.Address - var lastErr error - if option.IPv6Enable && record.AAAA != nil && record.AAAA.RCode == dnsmessage.RCodeSuccess { - aaaa, err := record.AAAA.getIPs() - if err != nil { - lastErr = err - } - ips = append(ips, aaaa...) - } - - if option.IPv4Enable && record.A != nil && record.A.RCode == dnsmessage.RCodeSuccess { - a, err := record.A.getIPs() - if err != nil { - lastErr = err - } - ips = append(ips, a...) + var ip6 []net.Address + + switch { + case option.IPv4Enable: + ips, err4 = record.A.getIPs() + fallthrough + case option.IPv6Enable: + ip6, err6 = record.AAAA.getIPs() + ips = append(ips, ip6...) } if len(ips) > 0 { return toNetIP(ips) } - if lastErr != nil { - return nil, lastErr + if err4 != nil { + return nil, err4 } - if (option.IPv4Enable && record.A != nil) || (option.IPv6Enable && record.AAAA != nil) { - return nil, dns_feature.ErrEmptyResponse + if err6 != nil { + return nil, err6 } return nil, errRecordNotFound diff --git a/app/dns/nameserver_tcp.go b/app/dns/nameserver_tcp.go index f3a10714493..daee2d28a20 100644 --- a/app/dns/nameserver_tcp.go +++ b/app/dns/nameserver_tcp.go @@ -29,8 +29,8 @@ import ( type TCPNameServer struct { sync.RWMutex name string - destination net.Destination - ips map[string]record + destination *net.Destination + ips map[string]*record pub *pubsub.Service cleanup *task.Periodic reqID uint32 @@ -45,7 +45,7 @@ func NewTCPNameServer(url *url.URL, dispatcher routing.Dispatcher) (*TCPNameServ } s.dial = func(ctx context.Context) (net.Conn, error) { - link, err := dispatcher.Dispatch(ctx, s.destination) + link, err := dispatcher.Dispatch(ctx, *s.destination) if err != nil { return nil, err } @@ -67,7 +67,7 @@ func NewTCPLocalNameServer(url *url.URL) (*TCPNameServer, error) { } s.dial = func(ctx context.Context) (net.Conn, error) { - return internet.DialSystem(ctx, s.destination, nil) + return internet.DialSystem(ctx, *s.destination, nil) } return s, nil @@ -85,8 +85,8 @@ func baseTCPNameServer(url *url.URL, prefix string) (*TCPNameServer, error) { dest := net.TCPDestination(net.ParseAddress(url.Hostname()), port) s := &TCPNameServer{ - destination: dest, - ips: make(map[string]record), + destination: &dest, + ips: make(map[string]*record), pub: pubsub.NewService(), name: prefix + "//" + dest.NetAddr(), } @@ -114,13 +114,6 @@ func (s *TCPNameServer) Cleanup() error { } for domain, record := range s.ips { - if record.A != nil && len(record.A.IP) == 0 { - record.A = nil - } - if record.AAAA != nil && len(record.AAAA.IP) == 0 { - record.AAAA = nil - } - if record.A != nil && record.A.Expire.Before(now) { record.A = nil } @@ -136,6 +129,10 @@ func (s *TCPNameServer) Cleanup() error { } } + if len(s.ips) == 0 { + s.ips = make(map[string]*record) + } + return nil } @@ -145,7 +142,7 @@ func (s *TCPNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { s.Lock() rec, found := s.ips[req.domain] if !found { - rec = record{} + rec = &record{} } updated := false @@ -170,7 +167,7 @@ func (s *TCPNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) { } newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog() - if updated && len(ipRec.IP) > 0 { + if updated { s.ips[req.domain] = rec } switch req.reqType { @@ -280,30 +277,30 @@ func (s *TCPNameServer) findIPsForDomain(domain string, option dns_feature.IPOpt return nil, errRecordNotFound } + var err4 error + var err6 error var ips []net.Address - var lastErr error - if option.IPv4Enable { - a, err := record.A.getIPs() - if err != nil { - lastErr = err - } - ips = append(ips, a...) - } - - if option.IPv6Enable { - aaaa, err := record.AAAA.getIPs() - if err != nil { - lastErr = err - } - ips = append(ips, aaaa...) + var ip6 []net.Address + + switch { + case option.IPv4Enable: + ips, err4 = record.A.getIPs() + fallthrough + case option.IPv6Enable: + ip6, err6 = record.AAAA.getIPs() + ips = append(ips, ip6...) } if len(ips) > 0 { return toNetIP(ips) } - if lastErr != nil { - return nil, lastErr + if err4 != nil { + return nil, err4 + } + + if err6 != nil { + return nil, err6 } return nil, dns_feature.ErrEmptyResponse diff --git a/app/dns/nameserver_udp.go b/app/dns/nameserver_udp.go index 0252e4e04f0..c53609d3693 100644 --- a/app/dns/nameserver_udp.go +++ b/app/dns/nameserver_udp.go @@ -28,9 +28,9 @@ import ( type ClassicNameServer struct { sync.RWMutex name string - address net.Destination - ips map[string]record - requests map[uint16]dnsRequest + address *net.Destination + ips map[string]*record + requests map[uint16]*dnsRequest pub *pubsub.Service udpServer *udp.Dispatcher cleanup *task.Periodic @@ -45,9 +45,9 @@ func NewClassicNameServer(address net.Destination, dispatcher routing.Dispatcher } s := &ClassicNameServer{ - address: address, - ips: make(map[string]record), - requests: make(map[uint16]dnsRequest), + address: &address, + ips: make(map[string]*record), + requests: make(map[uint16]*dnsRequest), pub: pubsub.NewService(), name: strings.ToUpper(address.String()), } @@ -76,13 +76,6 @@ func (s *ClassicNameServer) Cleanup() error { } for domain, record := range s.ips { - if record.A != nil && len(record.A.IP) == 0 { - record.A = nil - } - if record.AAAA != nil && len(record.AAAA.IP) == 0 { - record.AAAA = nil - } - if record.A != nil && record.A.Expire.Before(now) { record.A = nil } @@ -91,12 +84,17 @@ func (s *ClassicNameServer) Cleanup() error { } if record.A == nil && record.AAAA == nil { + newError(s.name, " cleanup ", domain).AtDebug().WriteToLog() delete(s.ips, domain) } else { s.ips[domain] = record } } + if len(s.ips) == 0 { + s.ips = make(map[string]*record) + } + for id, req := range s.requests { if req.expire.Before(now) { delete(s.requests, id) @@ -104,7 +102,7 @@ func (s *ClassicNameServer) Cleanup() error { } if len(s.requests) == 0 { - s.requests = make(map[uint16]dnsRequest) + s.requests = make(map[uint16]*dnsRequest) } return nil @@ -142,16 +140,16 @@ func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_prot elapsed := time.Since(req.start) newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog() if len(req.domain) > 0 && (rec.A != nil || rec.AAAA != nil) { - s.updateIP(req.domain, rec) + s.updateIP(req.domain, &rec) } } -func (s *ClassicNameServer) updateIP(domain string, newRec record) { +func (s *ClassicNameServer) updateIP(domain string, newRec *record) { s.Lock() rec, found := s.ips[domain] if !found { - rec = record{} + rec = &record{} } updated := false @@ -164,7 +162,7 @@ func (s *ClassicNameServer) updateIP(domain string, newRec record) { updated = true } - if updated && ((newRec.A != nil && len(newRec.A.IP) > 0) || (newRec.AAAA != nil && len(newRec.AAAA.IP) > 0)) { + if updated { newError(s.name, " updating IP records for domain:", domain).AtDebug().WriteToLog() s.ips[domain] = rec } @@ -188,7 +186,7 @@ func (s *ClassicNameServer) addPendingRequest(req *dnsRequest) { id := req.msg.ID req.expire = time.Now().Add(time.Second * 8) - s.requests[id] = *req + s.requests[id] = req } func (s *ClassicNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) { @@ -206,7 +204,7 @@ func (s *ClassicNameServer) sendQuery(ctx context.Context, domain string, client udpCtx = session.ContextWithContent(udpCtx, &session.Content{ Protocol: "dns", }) - s.udpServer.Dispatch(udpCtx, s.address, b) + s.udpServer.Dispatch(udpCtx, *s.address, b) } } @@ -219,30 +217,30 @@ func (s *ClassicNameServer) findIPsForDomain(domain string, option dns_feature.I return nil, errRecordNotFound } + var err4 error + var err6 error var ips []net.Address - var lastErr error - if option.IPv4Enable { - a, err := record.A.getIPs() - if err != nil { - lastErr = err - } - ips = append(ips, a...) - } - - if option.IPv6Enable { - aaaa, err := record.AAAA.getIPs() - if err != nil { - lastErr = err - } - ips = append(ips, aaaa...) + var ip6 []net.Address + + switch { + case option.IPv4Enable: + ips, err4 = record.A.getIPs() + fallthrough + case option.IPv6Enable: + ip6, err6 = record.AAAA.getIPs() + ips = append(ips, ip6...) } if len(ips) > 0 { return toNetIP(ips) } - if lastErr != nil { - return nil, lastErr + if err4 != nil { + return nil, err4 + } + + if err6 != nil { + return nil, err6 } return nil, dns_feature.ErrEmptyResponse