@@ -3,7 +3,6 @@ package ackhandler
3
3
import (
4
4
"crypto/rand"
5
5
"encoding/binary"
6
- mrand "math/rand"
7
6
8
7
"github.com/lucas-clemente/quic-go/internal/protocol"
9
8
"github.com/lucas-clemente/quic-go/internal/utils"
@@ -34,25 +33,45 @@ func (p *sequentialPacketNumberGenerator) Pop() protocol.PacketNumber {
34
33
return next
35
34
}
36
35
36
+ type rng struct {
37
+ buf [4 ]byte
38
+ }
39
+
40
+ func (r * rng ) Int31 () int32 {
41
+ rand .Read (r .buf [:])
42
+ return int32 (binary .BigEndian .Uint32 (r .buf [:]) & ^ uint32 (1 << 31 ))
43
+ }
44
+
45
+ // copied from the standard library math/rand implementation of Int63n
46
+ func (r * rng ) Int31n (n int32 ) int32 {
47
+ if n & (n - 1 ) == 0 { // n is power of two, can mask
48
+ return r .Int31 () & (n - 1 )
49
+ }
50
+ max := int32 ((1 << 31 ) - 1 - (1 << 31 )% uint32 (n ))
51
+ v := r .Int31 ()
52
+ for v > max {
53
+ v = r .Int31 ()
54
+ }
55
+ return v % n
56
+ }
57
+
37
58
// The skippingPacketNumberGenerator generates the packet number for the next packet
38
59
// it randomly skips a packet number every averagePeriod packets (on average).
39
60
// It is guaranteed to never skip two consecutive packet numbers.
40
61
type skippingPacketNumberGenerator struct {
41
- rand * mrand.Rand
42
62
period protocol.PacketNumber
43
63
maxPeriod protocol.PacketNumber
44
64
45
65
next protocol.PacketNumber
46
66
nextToSkip protocol.PacketNumber
67
+
68
+ rng rng
47
69
}
48
70
49
71
var _ packetNumberGenerator = & skippingPacketNumberGenerator {}
50
72
51
73
func newSkippingPacketNumberGenerator (initial , initialPeriod , maxPeriod protocol.PacketNumber ) packetNumberGenerator {
52
- b := make ([]byte , 8 )
53
- rand .Read (b ) // it's not the end of the world if we don't get perfect random here
54
74
g := & skippingPacketNumberGenerator {
55
- rand : mrand .New (mrand .NewSource (int64 (binary .LittleEndian .Uint64 (b )))),
56
75
next : initial ,
57
76
period : initialPeriod ,
58
77
maxPeriod : maxPeriod ,
@@ -77,6 +96,6 @@ func (p *skippingPacketNumberGenerator) Pop() protocol.PacketNumber {
77
96
78
97
func (p * skippingPacketNumberGenerator ) generateNewSkip () {
79
98
// make sure that there are never two consecutive packet numbers that are skipped
80
- p .nextToSkip = p .next + 2 + protocol .PacketNumber (p .rand . Int63n ( int64 (2 * p .period )))
99
+ p .nextToSkip = p .next + 2 + protocol .PacketNumber (p .rng . Int31n ( int32 (2 * p .period )))
81
100
p .period = utils .MinPacketNumber (2 * p .period , p .maxPeriod )
82
101
}
0 commit comments