Shuffle all the replies, not only the ones from the cache...

This commit is contained in:
Alvaro Saurin committed 2015-05-26 10:53:13 +02:00
1 parent 87a2886539
commit 174b47d1db
3 files changed
+22 -20

No files matched your search

-19
View File
@@ -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
}
+19
View File
@@ -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
}
+3 -1
View File
@@ -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)