Shuffle all the replies, not only the ones from the cache...
This commit is contained in:
1 parent
87a2886539
commit
174b47d1db
3 files changed
+22
-20
No files matched your search
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user