mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 20:57:36 +03:00
implement a function to get version slices containing reserved versions
This commit is contained in:
parent
3e41cf9ba1
commit
1f5cd31569
2 changed files with 74 additions and 1 deletions
|
@ -1,11 +1,13 @@
|
|||
package protocol
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// VersionNumber is a version number as int
|
||||
type VersionNumber int
|
||||
type VersionNumber int32
|
||||
|
||||
// gQUIC version range as defined in the wiki: https://github.com/quicwg/base-drafts/wiki/QUIC-Versions
|
||||
const (
|
||||
|
@ -112,3 +114,22 @@ func ChooseSupportedVersion(ours, theirs []VersionNumber) (VersionNumber, bool)
|
|||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// generateReservedVersion generates a reserved version number (v & 0x0f0f0f0f == 0x0a0a0a0a)
|
||||
func generateReservedVersion() VersionNumber {
|
||||
b := make([]byte, 4)
|
||||
_, _ = rand.Read(b) // ignore the error here. Failure to read random data doesn't break anything
|
||||
return VersionNumber((binary.BigEndian.Uint32(b) | 0x0a0a0a0a) & 0xfafafafa)
|
||||
}
|
||||
|
||||
// GetGreasedVersions adds one reserved version number to a slice of version numbers, at a random position
|
||||
func GetGreasedVersions(supported []VersionNumber) []VersionNumber {
|
||||
b := make([]byte, 1)
|
||||
_, _ = rand.Read(b) // ignore the error here. Failure to read random data doesn't break anything
|
||||
randPos := int(b[0]) % (len(supported) + 1)
|
||||
greased := make([]VersionNumber, len(supported)+1)
|
||||
copy(greased, supported[:randPos])
|
||||
greased[randPos] = generateReservedVersion()
|
||||
copy(greased[randPos+1:], supported[randPos:])
|
||||
return greased
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@ import (
|
|||
)
|
||||
|
||||
var _ = Describe("Version", func() {
|
||||
isReservedVersion := func(v VersionNumber) bool {
|
||||
return v&0x0f0f0f0f == 0x0a0a0a0a
|
||||
}
|
||||
|
||||
// version numbers taken from the wiki: https://github.com/quicwg/base-drafts/wiki/QUIC-Versions
|
||||
It("has the right gQUIC version number", func() {
|
||||
Expect(Version39).To(BeEquivalentTo(0x51303339))
|
||||
|
@ -16,6 +20,11 @@ var _ = Describe("Version", func() {
|
|||
Expect(VersionTLS.UsesTLS()).To(BeTrue())
|
||||
})
|
||||
|
||||
It("versions don't have reserved version numbers", func() {
|
||||
Expect(isReservedVersion(Version39)).To(BeFalse())
|
||||
Expect(isReservedVersion(VersionTLS)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("has the right string representation", func() {
|
||||
Expect(Version39.String()).To(Equal("gQUIC 39"))
|
||||
Expect(VersionTLS.String()).To(ContainSubstring("TLS"))
|
||||
|
@ -105,4 +114,47 @@ var _ = Describe("Version", func() {
|
|||
Expect(ok).To(BeFalse())
|
||||
})
|
||||
})
|
||||
|
||||
Context("reserved versions", func() {
|
||||
It("adds a greased version if passed an empty slice", func() {
|
||||
greased := GetGreasedVersions([]VersionNumber{})
|
||||
Expect(greased).To(HaveLen(1))
|
||||
Expect(isReservedVersion(greased[0])).To(BeTrue())
|
||||
})
|
||||
|
||||
It("creates greased lists of version numbers", func() {
|
||||
supported := []VersionNumber{10, 18, 29}
|
||||
for _, v := range supported {
|
||||
Expect(isReservedVersion(v)).To(BeFalse())
|
||||
}
|
||||
var greasedVersionFirst, greasedVersionLast, greasedVersionMiddle int
|
||||
// check that
|
||||
// 1. the greased version sometimes appears first
|
||||
// 2. the greased version sometimes appears in the middle
|
||||
// 3. the greased version sometimes appears last
|
||||
// 4. the supported versions are kept in order
|
||||
for i := 0; i < 100; i++ {
|
||||
greased := GetGreasedVersions(supported)
|
||||
Expect(greased).To(HaveLen(4))
|
||||
var j int
|
||||
for i, v := range greased {
|
||||
if isReservedVersion(v) {
|
||||
if i == 0 {
|
||||
greasedVersionFirst++
|
||||
}
|
||||
if i == len(greased)-1 {
|
||||
greasedVersionLast++
|
||||
}
|
||||
greasedVersionMiddle++
|
||||
continue
|
||||
}
|
||||
Expect(supported[j]).To(Equal(v))
|
||||
j++
|
||||
}
|
||||
}
|
||||
Expect(greasedVersionFirst).ToNot(BeZero())
|
||||
Expect(greasedVersionLast).ToNot(BeZero())
|
||||
Expect(greasedVersionMiddle).ToNot(BeZero())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue