mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 20:57:36 +03:00
uTLS is not yet bumped to the new version, so this commit breaks the dependencies relationship by getting rid of the local replace.
92 lines
3.4 KiB
Go
92 lines
3.4 KiB
Go
package wire
|
|
|
|
import (
|
|
"encoding/binary"
|
|
|
|
"golang.org/x/exp/rand"
|
|
|
|
"github.com/refraction-networking/uquic/internal/protocol"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("Version Negotiation Packets", func() {
|
|
randConnID := func(l int) protocol.ArbitraryLenConnectionID {
|
|
b := make(protocol.ArbitraryLenConnectionID, l)
|
|
_, err := rand.Read(b)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
return b
|
|
}
|
|
|
|
It("parses a Version Negotiation packet", func() {
|
|
srcConnID := randConnID(rand.Intn(255) + 1)
|
|
destConnID := randConnID(rand.Intn(255) + 1)
|
|
versions := []protocol.VersionNumber{0x22334455, 0x33445566}
|
|
data := []byte{0x80, 0, 0, 0, 0}
|
|
data = append(data, uint8(len(destConnID)))
|
|
data = append(data, destConnID...)
|
|
data = append(data, uint8(len(srcConnID)))
|
|
data = append(data, srcConnID...)
|
|
for _, v := range versions {
|
|
data = append(data, []byte{0, 0, 0, 0}...)
|
|
binary.BigEndian.PutUint32(data[len(data)-4:], uint32(v))
|
|
}
|
|
Expect(IsVersionNegotiationPacket(data)).To(BeTrue())
|
|
dest, src, supportedVersions, err := ParseVersionNegotiationPacket(data)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(dest).To(Equal(destConnID))
|
|
Expect(src).To(Equal(srcConnID))
|
|
Expect(supportedVersions).To(Equal(versions))
|
|
})
|
|
|
|
It("errors if it contains versions of the wrong length", func() {
|
|
connID := protocol.ArbitraryLenConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
|
versions := []protocol.VersionNumber{0x22334455, 0x33445566}
|
|
data := ComposeVersionNegotiation(connID, connID, versions)
|
|
_, _, _, err := ParseVersionNegotiationPacket(data[:len(data)-2])
|
|
Expect(err).To(MatchError("Version Negotiation packet has a version list with an invalid length"))
|
|
})
|
|
|
|
It("errors if the version list is empty", func() {
|
|
connID := protocol.ArbitraryLenConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
|
versions := []protocol.VersionNumber{0x22334455}
|
|
data := ComposeVersionNegotiation(connID, connID, versions)
|
|
// remove 8 bytes (two versions), since ComposeVersionNegotiation also added a reserved version number
|
|
data = data[:len(data)-8]
|
|
_, _, _, err := ParseVersionNegotiationPacket(data)
|
|
Expect(err).To(MatchError("Version Negotiation packet has empty version list"))
|
|
})
|
|
|
|
It("adds a reserved version", func() {
|
|
srcConnID := protocol.ArbitraryLenConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}
|
|
destConnID := protocol.ArbitraryLenConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
|
versions := []protocol.VersionNumber{1001, 1003}
|
|
data := ComposeVersionNegotiation(destConnID, srcConnID, versions)
|
|
Expect(IsLongHeaderPacket(data[0])).To(BeTrue())
|
|
v, err := ParseVersion(data)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(v).To(BeZero())
|
|
dest, src, supportedVersions, err := ParseVersionNegotiationPacket(data)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(dest).To(Equal(destConnID))
|
|
Expect(src).To(Equal(srcConnID))
|
|
// the supported versions should include one reserved version number
|
|
Expect(supportedVersions).To(HaveLen(len(versions) + 1))
|
|
for _, v := range versions {
|
|
Expect(supportedVersions).To(ContainElement(v))
|
|
}
|
|
var reservedVersion protocol.VersionNumber
|
|
versionLoop:
|
|
for _, ver := range supportedVersions {
|
|
for _, v := range versions {
|
|
if v == ver {
|
|
continue versionLoop
|
|
}
|
|
}
|
|
reservedVersion = ver
|
|
}
|
|
Expect(reservedVersion).ToNot(BeZero())
|
|
Expect(reservedVersion&0x0f0f0f0f == 0x0a0a0a0a).To(BeTrue()) // check that it's a greased version number
|
|
})
|
|
})
|