diff --git a/nameserver/cache.go b/nameserver/cache.go index 644814f0..7a5cc0c1 100644 --- a/nameserver/cache.go +++ b/nameserver/cache.go @@ -9,7 +9,6 @@ import ( "github.com/miekg/dns" . "github.com/weaveworks/weave/common" "math" - "math/rand" "sync" "time" ) @@ -43,21 +42,6 @@ const ( CacheNoLocalReplies uint8 = 1 << iota // not found in local network (stored in the cache so we skip another local lookup or some time) ) -// shuffleAnswers reorders answers for very basic load balancing -func shuffleAnswers(answers []dns.RR) []dns.RR { - n := len(answers) - if n > 1 { - rand.Seed(time.Now().UTC().UnixNano()) - - for i := 0; i < n; i++ { - r := i + rand.Intn(n-i) - answers[r], answers[i] = answers[i], answers[r] - } - } - - return answers -} - // a cache entry type cacheEntry struct { Status entryStatus // status of the entry @@ -124,9 +108,6 @@ func (e *cacheEntry) getReply(request *dns.Msg, maxLen int, now time.Time) (*dns reply.Rcode = e.reply.Rcode reply.Authoritative = true - // shuffle the values, etc... - reply.Answer = shuffleAnswers(reply.Answer) - return reply, nil } diff --git a/nameserver/dns.go b/nameserver/dns.go index 3b8b8c57..be0a7fd0 100644 --- a/nameserver/dns.go +++ b/nameserver/dns.go @@ -2,6 +2,8 @@ package nameserver import ( "github.com/miekg/dns" + "math/rand" + "time" ) const ( @@ -86,3 +88,20 @@ func getMaxReplyLen(r *dns.Msg, proto dnsProtocol) int { } return maxLen } + + +func init() { + rand.Seed(time.Now().UTC().UnixNano()) +} + +// shuffleAnswers reorders answers for very basic load balancing +func shuffleAnswers(answers []dns.RR) []dns.RR { + if len(answers) > 1 { + for i := range answers { + j := rand.Intn(i + 1) + answers[i], answers[j] = answers[j], answers[i] + } + } + + return answers +} diff --git a/nameserver/server.go b/nameserver/server.go index c26bc63b..6fd244c9 100644 --- a/nameserver/server.go +++ b/nameserver/server.go @@ -283,7 +283,7 @@ func (s *DNSServer) localHandler(proto dnsProtocol, kind string, qtype uint16, Debug.Printf("[dns msgid %d] %s: %+v", r.MsgHdr.Id, kind, q) maxLen := getMaxReplyLen(r, proto) - // cache a reponse if the cache is enabled, and observe the name/IP + // cache a response if the cache is enabled, and observe the name/IP maybeCache := func(m *dns.Msg, ttl int, flags uint8) { if !s.cacheDisabled { s.cache.Put(r, m, ttl, flags) @@ -311,6 +311,7 @@ func (s *DNSServer) localHandler(proto dnsProtocol, kind string, qtype uint16, if reply != nil { Debug.Printf("[dns msgid %d] Returning reply from cache: %s/%d answers", r.MsgHdr.Id, dns.RcodeToString[reply.MsgHdr.Rcode], len(reply.Answer)) + reply.Answer = shuffleAnswers(reply.Answer) w.WriteMsg(reply) return } @@ -333,6 +334,7 @@ func (s *DNSServer) localHandler(proto dnsProtocol, kind string, qtype uint16, } else { m := msgBuilder(r, &q, answers) m.Authoritative = true + m.Answer = shuffleAnswers(m.Answer) Debug.Printf("[dns msgid %d] Sending response: %s/%s:%s [code:%s]", m.MsgHdr.Id, dns.TypeToString[q.Qtype], q.Name, answers, dns.RcodeToString[m.Rcode]) maybeCache(m, nullTTL, 0)