-
Notifications
You must be signed in to change notification settings - Fork 9.1k
Fixes #5001 #5078
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes #5001 #5078
Changes from 7 commits
e8139fc
8cae2b2
0e1b634
fff8c7c
3330b4a
6c6880d
367cf4f
4907e18
8222642
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,8 @@ SPDX-License-Identifier: Apache-2.0 | |
| package algo | ||
|
|
||
| import ( | ||
| "crypto/rand" | ||
| "encoding/binary" | ||
| "sync" | ||
| "sync/atomic" | ||
| "time" | ||
|
|
@@ -319,10 +321,28 @@ func (engine *PullEngine) OnRes(items []string, nonce uint64) { | |
| } | ||
|
|
||
| func (engine *PullEngine) newNONCE() uint64 { | ||
| n := uint64(0) | ||
| engine.lock.Lock() | ||
| defer engine.lock.Unlock() | ||
|
|
||
| maxAttempts := 1000000 | ||
| for i := 0; i < maxAttempts; i++ { | ||
| n := util.RandomUInt64() | ||
| if n != 0 && !engine.outgoingNONCES.Exists(n) { | ||
| return n | ||
| } | ||
| } | ||
|
|
||
|
||
| // If we still couldn't generate a unique NONCE after max attempts, | ||
| // keep trying with crypto/rand until we find one | ||
| var n uint64 | ||
| for { | ||
| n = util.RandomUInt64() | ||
| if !engine.outgoingNONCES.Exists(n) { | ||
| bytes := make([]byte, 8) | ||
| if _, err := rand.Read(bytes); err != nil { | ||
| // Fallback to time-based if crypto/rand fails | ||
| return uint64(time.Now().UnixNano()) | ||
| } | ||
| n = binary.BigEndian.Uint64(bytes) | ||
| if n != 0 && !engine.outgoingNONCES.Exists(n) { | ||
| return n | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,10 @@ import ( | |
| "github.com/spf13/viper" | ||
| ) | ||
|
|
||
| var r *rand.Rand | ||
| var ( | ||
| r *rand.Rand | ||
| rMutex sync.Mutex | ||
| ) | ||
|
|
||
| func init() { // do we really need this? | ||
| var seed [32]byte | ||
|
|
@@ -187,6 +190,8 @@ func RandomInt(n int) int { | |
| // If we want a rand that's non-global and specific to gossip, we can | ||
| // establish one. Otherwise this uses the process-global locking RNG. | ||
| func RandomUInt64() uint64 { | ||
| rMutex.Lock() | ||
| defer rMutex.Unlock() | ||
|
||
| return r.Uint64() | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need to lock at all. We only create nonces from here and we already lock there.
Just loop until
engine.outgoingNONCES.Exists(n)is false, no need for attempts or anything.