diff options
author | 2022-03-16 09:24:58 -0700 | |
---|---|---|
committer | 2022-03-16 12:24:58 -0400 | |
commit | aa7818e1d342ffbed3588f6bdece621b119debec (patch) | |
tree | d718b6040cfb0f64562fcf8c818598c7ac29e689 | |
parent | c3b30cc3ef57393a7f4cab1bf3b6c4124e72a36e (diff) | |
download | coredns-aa7818e1d342ffbed3588f6bdece621b119debec.tar.gz coredns-aa7818e1d342ffbed3588f6bdece621b119debec.tar.zst coredns-aa7818e1d342ffbed3588f6bdece621b119debec.zip |
Update to avoid pseudo-random number (#5225)
* Update to avoid pseudo-random number
This PR update the usage of rand so that non-global seed is used.
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
* Add concurrency-safe random source
See https://stackoverflow.com/questions/48958886/how-to-create-a-thread-safe-rand-source
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
-rw-r--r-- | plugin/forward/policy.go | 10 | ||||
-rw-r--r-- | plugin/grpc/policy.go | 10 | ||||
-rw-r--r-- | plugin/loop/setup.go | 4 | ||||
-rw-r--r-- | plugin/pkg/rand/rand.go | 36 |
4 files changed, 52 insertions, 8 deletions
diff --git a/plugin/forward/policy.go b/plugin/forward/policy.go index 2066e1316..e81e4ab91 100644 --- a/plugin/forward/policy.go +++ b/plugin/forward/policy.go @@ -1,8 +1,10 @@ package forward import ( - "math/rand" "sync/atomic" + "time" + + "github.com/coredns/coredns/plugin/pkg/rand" ) // Policy defines a policy we use for selecting upstreams. @@ -21,13 +23,13 @@ func (r *random) List(p []*Proxy) []*Proxy { case 1: return p case 2: - if rand.Int()%2 == 0 { + if rn.Int()%2 == 0 { return []*Proxy{p[1], p[0]} // swap } return p } - perms := rand.Perm(len(p)) + perms := rn.Perm(len(p)) rnd := make([]*Proxy, len(p)) for i, p1 := range perms { @@ -62,3 +64,5 @@ func (r *sequential) String() string { return "sequential" } func (r *sequential) List(p []*Proxy) []*Proxy { return p } + +var rn = rand.New(time.Now().UnixNano()) diff --git a/plugin/grpc/policy.go b/plugin/grpc/policy.go index 66351d822..686b2ebb6 100644 --- a/plugin/grpc/policy.go +++ b/plugin/grpc/policy.go @@ -1,8 +1,10 @@ package grpc import ( - "math/rand" "sync/atomic" + "time" + + "github.com/coredns/coredns/plugin/pkg/rand" ) // Policy defines a policy we use for selecting upstreams. @@ -21,13 +23,13 @@ func (r *random) List(p []*Proxy) []*Proxy { case 1: return p case 2: - if rand.Int()%2 == 0 { + if rn.Int()%2 == 0 { return []*Proxy{p[1], p[0]} // swap } return p } - perms := rand.Perm(len(p)) + perms := rn.Perm(len(p)) rnd := make([]*Proxy, len(p)) for i, p1 := range perms { @@ -62,3 +64,5 @@ func (r *sequential) String() string { return "sequential" } func (r *sequential) List(p []*Proxy) []*Proxy { return p } + +var rn = rand.New(time.Now().UnixNano()) diff --git a/plugin/loop/setup.go b/plugin/loop/setup.go index 6af7b3baa..4e076c687 100644 --- a/plugin/loop/setup.go +++ b/plugin/loop/setup.go @@ -1,7 +1,6 @@ package loop import ( - "math/rand" "net" "strconv" "time" @@ -10,6 +9,7 @@ import ( "github.com/coredns/coredns/core/dnsserver" "github.com/coredns/coredns/plugin" "github.com/coredns/coredns/plugin/pkg/dnsutil" + "github.com/coredns/coredns/plugin/pkg/rand" ) func init() { plugin.Register("loop", setup) } @@ -84,4 +84,4 @@ func qname(zone string) string { return dnsutil.Join(l1, l2, zone) } -var r = rand.New(rand.NewSource(time.Now().UnixNano())) +var r = rand.New(time.Now().UnixNano()) diff --git a/plugin/pkg/rand/rand.go b/plugin/pkg/rand/rand.go new file mode 100644 index 000000000..d2b3960b4 --- /dev/null +++ b/plugin/pkg/rand/rand.go @@ -0,0 +1,36 @@ +// Package rand is used for concurrency safe random number generator. +package rand + +import ( + "math/rand" + "sync" +) + +// Rand is used for concurrency safe random number generator. +type Rand struct { + m sync.Mutex + r *rand.Rand +} + +// New returns a new Rand from seed. +func New(seed int64) *Rand { + return &Rand{r: rand.New(rand.NewSource(seed))} +} + +// Int returns a non-negative pseudo-random int from the Source in Rand.r. +func (r *Rand) Int() int { + r.m.Lock() + v := r.r.Int() + r.m.Unlock() + return v +} + +// Perm returns, as a slice of n ints, a pseudo-random permutation of the +// integers in the half-open interval [0,n) from the Source in Rand.r. +func (r *Rand) Perm(n int) []int { + r.m.Lock() + v := r.r.Perm(n) + r.m.Unlock() + return v + +} |