From 2474adb2c59a883e76de40bb098c954061aced5a Mon Sep 17 00:00:00 2001 From: Alvaro Saurin Date: Thu, 9 Apr 2015 15:58:40 +0200 Subject: [PATCH 1/4] Do not modify the TTL stored in the cache when getting a reply from the cache --- nameserver/cache.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/nameserver/cache.go b/nameserver/cache.go index a27226d4..38d1515b 100644 --- a/nameserver/cache.go +++ b/nameserver/cache.go @@ -93,31 +93,33 @@ func (e *cacheEntry) getReply(request *dns.Msg, maxLen int, now time.Time) (*dns } if e.ReplyLen >= maxLen { - Debug.Printf("[cache] returning truncated reponse: %d > %d", e.ReplyLen, maxLen) + Debug.Printf("[cache msgid %d] returning truncated reponse: %d > %d", request.MsgHdr.Id, e.ReplyLen, maxLen) return makeTruncatedReply(request), nil } // create a copy of the reply, with values for this particular query - reply := e.reply + reply := e.reply.Copy() reply.SetReply(request) - reply.Rcode = e.reply.Rcode - reply.Authoritative = true // adjust the TTLs passedSecs := uint32(now.Sub(e.putTime).Seconds()) for _, rr := range reply.Answer { - ttl := rr.Header().Ttl + hdr := rr.Header() + ttl := hdr.Ttl if passedSecs < ttl { - rr.Header().Ttl = ttl - passedSecs + hdr.Ttl = ttl - passedSecs } else { - rr.Header().Ttl = 0 + return nil, nil // it is expired: do not spend more time and return nil... } } + reply.Rcode = e.reply.Rcode + reply.Authoritative = true + // shuffle the values, etc... reply.Answer = shuffleAnswers(reply.Answer) - return &reply, nil + return reply, nil } func (e cacheEntry) hasExpired(now time.Time) bool { From 186481052de59816f06053a4d2271a8168c3d10a Mon Sep 17 00:00:00 2001 From: Alvaro Saurin Date: Thu, 9 Apr 2015 15:59:59 +0200 Subject: [PATCH 2/4] Catch unsupported queries by using the cache --- nameserver/server.go | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/nameserver/server.go b/nameserver/server.go index ff05be72..f7ba7817 100644 --- a/nameserver/server.go +++ b/nameserver/server.go @@ -223,14 +223,6 @@ func (s *DNSServer) queryHandler(proto dnsProtocol) dns.HandlerFunc { lookups := []Lookup{s.Zone, s.mdnsCli} Debug.Printf("Query: %+v", q) - if q.Qtype != dns.TypeA { - Debug.Printf("[dns msgid %d] Unsuported query type %s", r.MsgHdr.Id, dns.TypeToString[q.Qtype]) - m := makeDNSNotImplResponse(r) - s.cache.Put(r, m, negLocalTTL, 0, now) - w.WriteMsg(m) - return - } - reply, err := s.cache.Get(r, maxLen, time.Now()) if err != nil { if err == errNoLocalReplies { @@ -248,6 +240,16 @@ func (s *DNSServer) queryHandler(proto dnsProtocol) dns.HandlerFunc { w.WriteMsg(reply) return } + + // catch unsupported queries + if q.Qtype != dns.TypeA { + Debug.Printf("[dns msgid %d] Unsuported query type %s", r.MsgHdr.Id, dns.TypeToString[q.Qtype]) + m := makeDNSNotImplResponse(r) + s.cache.Put(r, m, negLocalTTL, 0, now) + w.WriteMsg(m) + return + } + for _, lookup := range lookups { if ip, err := lookup.LookupName(q.Name); err == nil { m := makeAddressReply(r, &q, []net.IP{ip}) @@ -275,17 +277,8 @@ func (s *DNSServer) rdnsHandler(proto dnsProtocol) dns.HandlerFunc { q := r.Question[0] lookups := []Lookup{s.Zone, s.mdnsCli} maxLen := getMaxReplyLen(r, proto) - Debug.Printf("Reverse query: %+v", q) - - if q.Qtype != dns.TypePTR { - Warning.Printf("[dns msgid %d] Unexpected reverse query type %s: %+v", - r.MsgHdr.Id, dns.TypeToString[q.Qtype], q) - m := makeDNSNotImplResponse(r) - s.cache.Put(r, m, negLocalTTL, 0, now) - w.WriteMsg(m) - return - } + Debug.Printf("Reverse query: %+v", q) reply, err := s.cache.Get(r, maxLen, time.Now()) if err != nil { if err == errNoLocalReplies { @@ -303,6 +296,17 @@ func (s *DNSServer) rdnsHandler(proto dnsProtocol) dns.HandlerFunc { w.WriteMsg(reply) return } + + // catch unsupported queries + if q.Qtype != dns.TypePTR { + Warning.Printf("[dns msgid %d] Unexpected reverse query type %s: %+v", + r.MsgHdr.Id, dns.TypeToString[q.Qtype], q) + m := makeDNSNotImplResponse(r) + s.cache.Put(r, m, negLocalTTL, 0, now) + w.WriteMsg(m) + return + } + for _, lookup := range lookups { if name, err := lookup.LookupInaddr(q.Name); err == nil { m := makePTRReply(r, &q, []string{name}) From 5d5b1017074d123c9f29352e105896922e384b0d Mon Sep 17 00:00:00 2001 From: Alvaro Saurin Date: Thu, 9 Apr 2015 16:00:42 +0200 Subject: [PATCH 3/4] Set locally resolved queries as Authoritative --- nameserver/server.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nameserver/server.go b/nameserver/server.go index f7ba7817..02b33175 100644 --- a/nameserver/server.go +++ b/nameserver/server.go @@ -253,6 +253,7 @@ func (s *DNSServer) queryHandler(proto dnsProtocol) dns.HandlerFunc { for _, lookup := range lookups { if ip, err := lookup.LookupName(q.Name); err == nil { m := makeAddressReply(r, &q, []net.IP{ip}) + m.Authoritative = true Debug.Printf("[dns msgid %d] Caching response for %s-query for \"%s\": %s [code:%s]", m.MsgHdr.Id, dns.TypeToString[q.Qtype], q.Name, ip, dns.RcodeToString[m.Rcode]) @@ -310,6 +311,8 @@ func (s *DNSServer) rdnsHandler(proto dnsProtocol) dns.HandlerFunc { for _, lookup := range lookups { if name, err := lookup.LookupInaddr(q.Name); err == nil { m := makePTRReply(r, &q, []string{name}) + m.Authoritative = true + Debug.Printf("[dns msgid %d] Caching response for %s-query for \"%s\": %s [code:%s]", m.MsgHdr.Id, dns.TypeToString[q.Qtype], q.Name, name, dns.RcodeToString[m.Rcode]) s.cache.Put(r, m, nullTTL, 0, now) From 7811e2b470cab98aea75d1c07f604d73e2c16714 Mon Sep 17 00:00:00 2001 From: Alvaro Saurin Date: Thu, 9 Apr 2015 16:01:38 +0200 Subject: [PATCH 4/4] Improved log messages --- nameserver/cache.go | 3 +++ nameserver/server.go | 6 ++---- weavedns/main.go | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/nameserver/cache.go b/nameserver/cache.go index 38d1515b..90393f53 100644 --- a/nameserver/cache.go +++ b/nameserver/cache.go @@ -131,6 +131,9 @@ func (e cacheEntry) hasExpired(now time.Time) bool { func (e *cacheEntry) setReply(reply *dns.Msg, ttl int, flags uint8, now time.Time) bool { var prevValidUntil time.Time if e.Status == stResolved { + if reply != nil { + Debug.Printf("[cache msgid %d] replacing response in cache", reply.MsgHdr.Id) + } prevValidUntil = e.validUntil } diff --git a/nameserver/server.go b/nameserver/server.go index 02b33175..f10941d6 100644 --- a/nameserver/server.go +++ b/nameserver/server.go @@ -18,7 +18,6 @@ const ( DefaultCacheLen = 8192 // default cache capacity DefaultResolvWorkers = 8 // default number of resolution workers DefaultTimeout = 5 // default timeout for DNS resolutions - DefaultResolvTries = 3 // max # of times a worker tries to resolve a query ) type DNSServerConfig struct { @@ -264,7 +263,7 @@ func (s *DNSServer) queryHandler(proto dnsProtocol) dns.HandlerFunc { now = time.Now() } - Info.Printf("[dns msgid %d] No results for type %s query %s", + Info.Printf("[dns msgid %d] No results for type %s query %s [caching no-local]", r.MsgHdr.Id, dns.TypeToString[q.Qtype], q.Name) s.cache.Put(r, nil, negLocalTTL, CacheNoLocalReplies, now) w.WriteMsg(makeDNSFailResponse(r)) @@ -360,8 +359,7 @@ func (s *DNSServer) notUsHandler(proto dnsProtocol) dns.HandlerFunc { w.WriteMsg(reply) return } - Warning.Printf("[dns msgid %d] Failed lookup for external name %s", - r.MsgHdr.Id, q.Name) + Warning.Printf("[dns msgid %d] Failed lookup for external name %s", r.MsgHdr.Id, q.Name) w.WriteMsg(makeDNSFailResponse(r)) } } diff --git a/weavedns/main.go b/weavedns/main.go index 7c239e0c..1b0613b9 100644 --- a/weavedns/main.go +++ b/weavedns/main.go @@ -54,6 +54,7 @@ func main() { } InitDefaultLogging(debug) + Info.Printf("WeaveDNS version %s\n", version) // first thing in log: the version var zone = new(weavedns.ZoneDb)