make sure the client can establish a connection to the upstream dns before continuing

This commit is contained in:
dovholuknf
2021-01-20 18:15:08 -05:00
parent 83f0b36c68
commit 69fbe547fe
+26 -15
View File
@@ -202,7 +202,7 @@ type proxiedReq struct {
func proxyDNS(req *dns.Msg, peer *net.UDPAddr, serv *net.UDPConn, ipVer int) {
if len(proxiedRequests) == cap(proxiedRequests) {
log.Warn("proxiedRequests will be blocked. If this warning is continuously displayed please report")
log.Warn("proxied DNS requests will be blocked. If this warning is continuously displayed please report")
}
proxiedRequests <- &proxiedReq{
req: req,
@@ -226,8 +226,9 @@ func dnsPanicRecover(localDnsServers []net.IP, now time.Time) {
}
//close any and all existing upstream
log.Warn("recovering from DNS panic initiated")
for _, c := range dnsUpstreams {
log.Warnf("recovering from DNS panic. closing DNS proxy to: %s", c.RemoteAddr().String())
log.Warnf(" - closing DNS proxy to: %s", c.RemoteAddr().String())
_ = c.Close()
dnsUpstreams = dnsUpstreams[1:]
}
@@ -248,7 +249,7 @@ func runDNSproxy(upstreamDnsServers []string, localDnsServers []net.IP) {
FlushDNS() //do this in case the services come back in different order and the ip returned is no longer the same
log.Infof("starting DNS proxy upstream: %v, local: %v", upstreamDnsServers, localDnsServers)
domains = GetConnectionSpecificDomains()
log.Infof("ConnectionSpecificDomains: %v", domains)
log.Infof("ConnectionSpecificDomains deteted: %v", domains)
defer func() {
if err := recover(); err != nil {
log.Errorf("Recovering from panic due to DNS-related issue. %v", err)
@@ -267,18 +268,17 @@ func runDNSproxy(upstreamDnsServers []string, localDnsServers []net.IP) {
}
sAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:53", s))
if err != nil {
// fec0:0:0:ffff:: is 'legacy' from windows apparently...
// see: https://en.wikipedia.org/wiki/IPv6_address#Deprecated_and_obsolete_addresses_2
if !strings.HasPrefix(s, "fec0:0:0:ffff::") {
// fec0:0:0:ffff:: is 'legacy' from windows apparently...
// see: https://en.wikipedia.org/wiki/IPv6_address#Deprecated_and_obsolete_addresses_2
// log any errors that are NOT due to this
log.Errorf("skipping upstream due to error: %s, %v", s, err.Error())
} else {
log.Tracef("Ignoring legacy server defined as: %s", s)
}
} else {
log.Debugf("adding upstream dns server: %s", s)
log.Infof("adding upstream dns server: %s", s)
conn, err := net.DialUDP("udp", nil, sAddr)
if err != nil {
log.Debugf("skipping upstream due to dial udp issue to %s. error: %v", s, err.Error())
log.Warnf("could not add upstream DNS: %s. error: %v", s, err.Error())
} else {
dnsUpstreams = append(dnsUpstreams, conn)
log.Debugf("established upstream dns: %s", s)
@@ -286,8 +286,19 @@ func runDNSproxy(upstreamDnsServers []string, localDnsServers []net.IP) {
}
}
log.Infof("starting goroutines for all DNS proxies. Total goroutines to spawn: %d", len(dnsUpstreams))
if len(upstreamDnsServers) > 0 && len(dnsUpstreams) == 0 {
//this alomst certainly indicates the network has been disconnected for some reason.
//this happens when turning wifi off and waiting a moment - then turning wifi back on again
//might happen unplugging the ethernet from one port to another - you get the idea... if this
//happens - pause for a small amount of time and reinstitute the proxy establishing loop
log.Warnf("no upstream DNS dials succeeded. Does this computer have any network connectivity? Pausing for 500ms and trying again")
time.Sleep(500 * time.Millisecond)
goto outer
}
log.Infof("starting goroutines for all connected DNS proxies. Total goroutines to spawn: %d of %d detected DNS", len(dnsUpstreams), len(upstreamDnsServers))
for _, proxy := range dnsUpstreams {
log.Debugf("beginning DNS proxy for: %s", proxy.RemoteAddr().String())
go func(p *net.UDPConn) {
resp := make([]byte, 1024) //make a buffer which is reused
for {
@@ -295,11 +306,11 @@ func runDNSproxy(upstreamDnsServers []string, localDnsServers []net.IP) {
if err != nil {
// something is wrong with the DNS connection panic and let DNS recovery kick in
if err == io.EOF || err == os.ErrClosed || strings.HasSuffix(err.Error(), "use of closed network connection") {
log.Errorf("error receiving from ip: %v. error %v", p.RemoteAddr(), err)
return
log.Errorf("DNS proxy closed for : %s. error %v", p.RemoteAddr().String(), err)
} else {
log.Warnf("odd error: %v", err)
log.Warnf("unexpected error. DNS proxy closed for %s due to %v", p.RemoteAddr().String(), err)
}
return
} else {
if len(respChan) == cap(respChan) {
log.Warn("respChan will be blocked. If this warning is continuously displayed please report")
@@ -312,7 +323,7 @@ func runDNSproxy(upstreamDnsServers []string, localDnsServers []net.IP) {
reqs := make(map[uint32]*proxiedReq)
log.Info("Upstream DNS proxy loop begins")
log.Debug("Upstream DNS proxy loop begins")
for {
select {
case pr := <-proxiedRequests:
@@ -361,7 +372,7 @@ func runDNSproxy(upstreamDnsServers []string, localDnsServers []net.IP) {
for k, r := range reqs {
if now.After(r.exp) {
log.Debugf("a DNS request has expired - enable trace logging and reproduce this issue for more information")
log.Tracef(" expired DNS req: %s %s", dns.Type(r.req.Question[0].Qtype), r.req.Question[0].Name)
log.Tracef("service adde expired DNS req: %s %s", dns.Type(r.req.Question[0].Qtype), r.req.Question[0].Name)
delete(reqs, k)
}