mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-05 13:17:36 +03:00
more the PublicHeader to the wire package
This commit is contained in:
parent
88afad8722
commit
1794636220
16 changed files with 107 additions and 89 deletions
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||||
"github.com/lucas-clemente/quic-go/protocol"
|
"github.com/lucas-clemente/quic-go/protocol"
|
||||||
"github.com/lucas-clemente/quic-go/qerr"
|
"github.com/lucas-clemente/quic-go/qerr"
|
||||||
|
"github.com/lucas-clemente/quic-go/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
type client struct {
|
type client struct {
|
||||||
|
@ -224,7 +225,7 @@ func (c *client) handlePacket(remoteAddr net.Addr, packet []byte) {
|
||||||
rcvTime := time.Now()
|
rcvTime := time.Now()
|
||||||
|
|
||||||
r := bytes.NewReader(packet)
|
r := bytes.NewReader(packet)
|
||||||
hdr, err := ParsePublicHeader(r, protocol.PerspectiveServer, c.version)
|
hdr, err := wire.ParsePublicHeader(r, protocol.PerspectiveServer, c.version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Errorf("error parsing packet from %s: %s", remoteAddr.String(), err.Error())
|
utils.Errorf("error parsing packet from %s: %s", remoteAddr.String(), err.Error())
|
||||||
// drop this packet if we can't parse the Public Header
|
// drop this packet if we can't parse the Public Header
|
||||||
|
@ -280,7 +281,7 @@ func (c *client) handlePacket(remoteAddr net.Addr, packet []byte) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) handlePacketWithVersionFlag(hdr *PublicHeader) error {
|
func (c *client) handlePacketWithVersionFlag(hdr *wire.PublicHeader) error {
|
||||||
for _, v := range hdr.SupportedVersions {
|
for _, v := range hdr.SupportedVersions {
|
||||||
if v == c.version {
|
if v == c.version {
|
||||||
// the version negotiation packet contains the version that we offered
|
// the version negotiation packet contains the version that we offered
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/lucas-clemente/quic-go/protocol"
|
"github.com/lucas-clemente/quic-go/protocol"
|
||||||
"github.com/lucas-clemente/quic-go/qerr"
|
"github.com/lucas-clemente/quic-go/qerr"
|
||||||
|
"github.com/lucas-clemente/quic-go/wire"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
@ -228,7 +229,7 @@ var _ = Describe("Client", func() {
|
||||||
|
|
||||||
Context("version negotiation", func() {
|
Context("version negotiation", func() {
|
||||||
It("recognizes that a packet without VersionFlag means that the server accepted the suggested version", func() {
|
It("recognizes that a packet without VersionFlag means that the server accepted the suggested version", func() {
|
||||||
ph := PublicHeader{
|
ph := wire.PublicHeader{
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
ConnectionID: 0x1337,
|
ConnectionID: 0x1337,
|
||||||
|
@ -262,7 +263,7 @@ var _ = Describe("Client", func() {
|
||||||
Expect(newVersion).ToNot(Equal(cl.version))
|
Expect(newVersion).ToNot(Equal(cl.version))
|
||||||
Expect(sess.packetCount).To(BeZero())
|
Expect(sess.packetCount).To(BeZero())
|
||||||
cl.connectionID = 0x1337
|
cl.connectionID = 0x1337
|
||||||
cl.handlePacket(nil, composeVersionNegotiation(0x1337, []protocol.VersionNumber{newVersion}))
|
cl.handlePacket(nil, wire.ComposeVersionNegotiation(0x1337, []protocol.VersionNumber{newVersion}))
|
||||||
Expect(cl.version).To(Equal(newVersion))
|
Expect(cl.version).To(Equal(newVersion))
|
||||||
Expect(cl.versionNegotiated).To(BeTrue())
|
Expect(cl.versionNegotiated).To(BeTrue())
|
||||||
// it swapped the sessions
|
// it swapped the sessions
|
||||||
|
@ -274,7 +275,7 @@ var _ = Describe("Client", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("errors if no matching version is found", func() {
|
It("errors if no matching version is found", func() {
|
||||||
cl.handlePacket(nil, composeVersionNegotiation(0x1337, []protocol.VersionNumber{1}))
|
cl.handlePacket(nil, wire.ComposeVersionNegotiation(0x1337, []protocol.VersionNumber{1}))
|
||||||
Expect(cl.session.(*mockSession).closed).To(BeTrue())
|
Expect(cl.session.(*mockSession).closed).To(BeTrue())
|
||||||
Expect(cl.session.(*mockSession).closeReason).To(MatchError(qerr.InvalidVersion))
|
Expect(cl.session.(*mockSession).closeReason).To(MatchError(qerr.InvalidVersion))
|
||||||
})
|
})
|
||||||
|
@ -283,13 +284,13 @@ var _ = Describe("Client", func() {
|
||||||
v := protocol.SupportedVersions[1]
|
v := protocol.SupportedVersions[1]
|
||||||
Expect(v).ToNot(Equal(cl.version))
|
Expect(v).ToNot(Equal(cl.version))
|
||||||
Expect(config.Versions).ToNot(ContainElement(v))
|
Expect(config.Versions).ToNot(ContainElement(v))
|
||||||
cl.handlePacket(nil, composeVersionNegotiation(0x1337, []protocol.VersionNumber{v}))
|
cl.handlePacket(nil, wire.ComposeVersionNegotiation(0x1337, []protocol.VersionNumber{v}))
|
||||||
Expect(cl.session.(*mockSession).closed).To(BeTrue())
|
Expect(cl.session.(*mockSession).closed).To(BeTrue())
|
||||||
Expect(cl.session.(*mockSession).closeReason).To(MatchError(qerr.InvalidVersion))
|
Expect(cl.session.(*mockSession).closeReason).To(MatchError(qerr.InvalidVersion))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("changes to the version preferred by the quic.Config", func() {
|
It("changes to the version preferred by the quic.Config", func() {
|
||||||
cl.handlePacket(nil, composeVersionNegotiation(0x1337, []protocol.VersionNumber{config.Versions[2], config.Versions[1]}))
|
cl.handlePacket(nil, wire.ComposeVersionNegotiation(0x1337, []protocol.VersionNumber{config.Versions[2], config.Versions[1]}))
|
||||||
Expect(cl.version).To(Equal(config.Versions[1]))
|
Expect(cl.version).To(Equal(config.Versions[1]))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -297,14 +298,14 @@ var _ = Describe("Client", func() {
|
||||||
// if the version was not yet negotiated, handlePacket would return a VersionNegotiationMismatch error, see above test
|
// if the version was not yet negotiated, handlePacket would return a VersionNegotiationMismatch error, see above test
|
||||||
cl.versionNegotiated = true
|
cl.versionNegotiated = true
|
||||||
Expect(sess.packetCount).To(BeZero())
|
Expect(sess.packetCount).To(BeZero())
|
||||||
cl.handlePacket(nil, composeVersionNegotiation(0x1337, []protocol.VersionNumber{1}))
|
cl.handlePacket(nil, wire.ComposeVersionNegotiation(0x1337, []protocol.VersionNumber{1}))
|
||||||
Expect(cl.versionNegotiated).To(BeTrue())
|
Expect(cl.versionNegotiated).To(BeTrue())
|
||||||
Expect(sess.packetCount).To(BeZero())
|
Expect(sess.packetCount).To(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("drops version negotiation packets that contain the offered version", func() {
|
It("drops version negotiation packets that contain the offered version", func() {
|
||||||
ver := cl.version
|
ver := cl.version
|
||||||
cl.handlePacket(nil, composeVersionNegotiation(0x1337, []protocol.VersionNumber{ver}))
|
cl.handlePacket(nil, wire.ComposeVersionNegotiation(0x1337, []protocol.VersionNumber{ver}))
|
||||||
Expect(cl.version).To(Equal(ver))
|
Expect(cl.version).To(Equal(ver))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -351,7 +352,7 @@ var _ = Describe("Client", func() {
|
||||||
|
|
||||||
Context("handling packets", func() {
|
Context("handling packets", func() {
|
||||||
It("handles packets", func() {
|
It("handles packets", func() {
|
||||||
ph := PublicHeader{
|
ph := wire.PublicHeader{
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
ConnectionID: 0x1337,
|
ConnectionID: 0x1337,
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/lucas-clemente/quic-go"
|
|
||||||
"github.com/lucas-clemente/quic-go/protocol"
|
"github.com/lucas-clemente/quic-go/protocol"
|
||||||
|
"github.com/lucas-clemente/quic-go/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Connection is a UDP connection
|
// Connection is a UDP connection
|
||||||
|
@ -165,7 +165,7 @@ func (p *QuicProxy) runProxy() error {
|
||||||
atomic.AddUint64(&conn.incomingPacketCounter, 1)
|
atomic.AddUint64(&conn.incomingPacketCounter, 1)
|
||||||
|
|
||||||
r := bytes.NewReader(raw)
|
r := bytes.NewReader(raw)
|
||||||
hdr, err := quic.ParsePublicHeader(r, protocol.PerspectiveClient, protocol.VersionWhatever)
|
hdr, err := wire.ParsePublicHeader(r, protocol.PerspectiveClient, protocol.VersionWhatever)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ func (p *QuicProxy) runConnection(conn *connection) error {
|
||||||
|
|
||||||
// TODO: Switch back to using the public header once Chrome properly sets the type byte.
|
// TODO: Switch back to using the public header once Chrome properly sets the type byte.
|
||||||
// r := bytes.NewReader(raw)
|
// r := bytes.NewReader(raw)
|
||||||
// , err := quic.ParsePublicHeader(r, protocol.PerspectiveServer)
|
// , err := wire.ParsePublicHeader(r, protocol.PerspectiveServer)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/lucas-clemente/quic-go"
|
|
||||||
"github.com/lucas-clemente/quic-go/protocol"
|
"github.com/lucas-clemente/quic-go/protocol"
|
||||||
|
"github.com/lucas-clemente/quic-go/wire"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
@ -22,7 +22,7 @@ var _ = Describe("QUIC Proxy", func() {
|
||||||
|
|
||||||
makePacket := func(p protocol.PacketNumber, payload []byte) []byte {
|
makePacket := func(p protocol.PacketNumber, payload []byte) []byte {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := quic.PublicHeader{
|
hdr := wire.PublicHeader{
|
||||||
PacketNumber: p,
|
PacketNumber: p,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
ConnectionID: 1337,
|
ConnectionID: 1337,
|
||||||
|
|
|
@ -264,10 +264,10 @@ func (p *packetPacker) QueueControlFrame(frame wire.Frame) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) getPublicHeader(encLevel protocol.EncryptionLevel) *PublicHeader {
|
func (p *packetPacker) getPublicHeader(encLevel protocol.EncryptionLevel) *wire.PublicHeader {
|
||||||
pnum := p.packetNumberGenerator.Peek()
|
pnum := p.packetNumberGenerator.Peek()
|
||||||
packetNumberLen := protocol.GetPacketNumberLengthForPublicHeader(pnum, p.leastUnacked)
|
packetNumberLen := protocol.GetPacketNumberLengthForPublicHeader(pnum, p.leastUnacked)
|
||||||
publicHeader := &PublicHeader{
|
publicHeader := &wire.PublicHeader{
|
||||||
ConnectionID: p.connectionID,
|
ConnectionID: p.connectionID,
|
||||||
PacketNumber: pnum,
|
PacketNumber: pnum,
|
||||||
PacketNumberLen: packetNumberLen,
|
PacketNumberLen: packetNumberLen,
|
||||||
|
@ -286,7 +286,7 @@ func (p *packetPacker) getPublicHeader(encLevel protocol.EncryptionLevel) *Publi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) writeAndSealPacket(
|
func (p *packetPacker) writeAndSealPacket(
|
||||||
publicHeader *PublicHeader,
|
publicHeader *wire.PublicHeader,
|
||||||
payloadFrames []wire.Frame,
|
payloadFrames []wire.Frame,
|
||||||
sealer handshake.Sealer,
|
sealer handshake.Sealer,
|
||||||
) ([]byte, error) {
|
) ([]byte, error) {
|
||||||
|
|
|
@ -238,7 +238,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
p, err := packer.PackPacket()
|
p, err := packer.PackPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p).ToNot(BeNil())
|
Expect(p).ToNot(BeNil())
|
||||||
hdr, err := ParsePublicHeader(bytes.NewReader(p.raw), protocol.PerspectiveClient, packer.version)
|
hdr, err := wire.ParsePublicHeader(bytes.NewReader(p.raw), protocol.PerspectiveClient, packer.version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.VersionFlag).To(BeTrue())
|
Expect(hdr.VersionFlag).To(BeTrue())
|
||||||
Expect(hdr.VersionNumber).To(Equal(packer.version))
|
Expect(hdr.VersionNumber).To(Equal(packer.version))
|
||||||
|
@ -252,7 +252,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
p, err := packer.PackPacket()
|
p, err := packer.PackPacket()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(p).ToNot(BeNil())
|
Expect(p).ToNot(BeNil())
|
||||||
hdr, err := ParsePublicHeader(bytes.NewReader(p.raw), protocol.PerspectiveClient, packer.version)
|
hdr, err := wire.ParsePublicHeader(bytes.NewReader(p.raw), protocol.PerspectiveClient, packer.version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.VersionFlag).To(BeFalse())
|
Expect(hdr.VersionFlag).To(BeFalse())
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,7 +24,7 @@ type packetUnpacker struct {
|
||||||
aead quicAEAD
|
aead quicAEAD
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *packetUnpacker) Unpack(publicHeaderBinary []byte, hdr *PublicHeader, data []byte) (*unpackedPacket, error) {
|
func (u *packetUnpacker) Unpack(publicHeaderBinary []byte, hdr *wire.PublicHeader, data []byte) (*unpackedPacket, error) {
|
||||||
buf := getPacketBuffer()
|
buf := getPacketBuffer()
|
||||||
defer putPacketBuffer(buf)
|
defer putPacketBuffer(buf)
|
||||||
decrypted, encryptionLevel, err := u.aead.Open(buf, data, hdr.PacketNumber, publicHeaderBinary)
|
decrypted, encryptionLevel, err := u.aead.Open(buf, data, hdr.PacketNumber, publicHeaderBinary)
|
||||||
|
|
|
@ -31,14 +31,14 @@ var _ quicAEAD = &mockAEAD{}
|
||||||
var _ = Describe("Packet unpacker", func() {
|
var _ = Describe("Packet unpacker", func() {
|
||||||
var (
|
var (
|
||||||
unpacker *packetUnpacker
|
unpacker *packetUnpacker
|
||||||
hdr *PublicHeader
|
hdr *wire.PublicHeader
|
||||||
hdrBin []byte
|
hdrBin []byte
|
||||||
data []byte
|
data []byte
|
||||||
buf *bytes.Buffer
|
buf *bytes.Buffer
|
||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
hdr = &PublicHeader{
|
hdr = &wire.PublicHeader{
|
||||||
PacketNumber: 10,
|
PacketNumber: 10,
|
||||||
PacketNumberLen: 1,
|
PacketNumberLen: 1,
|
||||||
}
|
}
|
||||||
|
|
26
server.go
26
server.go
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||||
"github.com/lucas-clemente/quic-go/protocol"
|
"github.com/lucas-clemente/quic-go/protocol"
|
||||||
"github.com/lucas-clemente/quic-go/qerr"
|
"github.com/lucas-clemente/quic-go/qerr"
|
||||||
|
"github.com/lucas-clemente/quic-go/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
// packetHandler handles packets
|
// packetHandler handles packets
|
||||||
|
@ -212,7 +213,7 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
||||||
rcvTime := time.Now()
|
rcvTime := time.Now()
|
||||||
|
|
||||||
r := bytes.NewReader(packet)
|
r := bytes.NewReader(packet)
|
||||||
connID, err := peekConnectionID(r, protocol.PerspectiveClient)
|
connID, err := wire.PeekConnectionID(r, protocol.PerspectiveClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return qerr.Error(qerr.InvalidPacketHeader, err.Error())
|
return qerr.Error(qerr.InvalidPacketHeader, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -231,8 +232,8 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
||||||
version = session.GetVersion()
|
version = session.GetVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr, err := ParsePublicHeader(r, protocol.PerspectiveClient, version)
|
hdr, err := wire.ParsePublicHeader(r, protocol.PerspectiveClient, version)
|
||||||
if err == errPacketWithUnknownVersion {
|
if err == wire.ErrPacketWithUnknownVersion {
|
||||||
_, err = pconn.WriteTo(writePublicReset(connID, 0, 0), remoteAddr)
|
_, err = pconn.WriteTo(writePublicReset(connID, 0, 0), remoteAddr)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -271,7 +272,7 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
||||||
return errors.New("dropping small packet with unknown version")
|
return errors.New("dropping small packet with unknown version")
|
||||||
}
|
}
|
||||||
utils.Infof("Client offered version %d, sending VersionNegotiationPacket", hdr.VersionNumber)
|
utils.Infof("Client offered version %d, sending VersionNegotiationPacket", hdr.VersionNumber)
|
||||||
_, err = pconn.WriteTo(composeVersionNegotiation(hdr.ConnectionID, s.config.Versions), remoteAddr)
|
_, err = pconn.WriteTo(wire.ComposeVersionNegotiation(hdr.ConnectionID, s.config.Versions), remoteAddr)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,20 +338,3 @@ func (s *server) removeConnection(id protocol.ConnectionID) {
|
||||||
s.sessionsMutex.Unlock()
|
s.sessionsMutex.Unlock()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func composeVersionNegotiation(connectionID protocol.ConnectionID, versions []protocol.VersionNumber) []byte {
|
|
||||||
fullReply := &bytes.Buffer{}
|
|
||||||
responsePublicHeader := PublicHeader{
|
|
||||||
ConnectionID: connectionID,
|
|
||||||
PacketNumber: 1,
|
|
||||||
VersionFlag: true,
|
|
||||||
}
|
|
||||||
err := responsePublicHeader.Write(fullReply, protocol.VersionWhatever, protocol.PerspectiveServer)
|
|
||||||
if err != nil {
|
|
||||||
utils.Errorf("error composing version negotiation packet: %s", err.Error())
|
|
||||||
}
|
|
||||||
for _, v := range versions {
|
|
||||||
utils.LittleEndian.WriteUint32(fullReply, protocol.VersionNumberToTag(v))
|
|
||||||
}
|
|
||||||
return fullReply.Bytes()
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||||
"github.com/lucas-clemente/quic-go/protocol"
|
"github.com/lucas-clemente/quic-go/protocol"
|
||||||
"github.com/lucas-clemente/quic-go/qerr"
|
"github.com/lucas-clemente/quic-go/qerr"
|
||||||
|
"github.com/lucas-clemente/quic-go/wire"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
@ -128,14 +129,6 @@ var _ = Describe("Server", func() {
|
||||||
Expect(serv.Addr().String()).To(Equal("192.168.13.37:1234"))
|
Expect(serv.Addr().String()).To(Equal("192.168.13.37:1234"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("composes version negotiation packets", func() {
|
|
||||||
expected := append(
|
|
||||||
[]byte{0x01 | 0x08, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
|
||||||
[]byte{'Q', '0', '9', '9'}...,
|
|
||||||
)
|
|
||||||
Expect(composeVersionNegotiation(1, []protocol.VersionNumber{99})).To(Equal(expected))
|
|
||||||
})
|
|
||||||
|
|
||||||
It("creates new sessions", func() {
|
It("creates new sessions", func() {
|
||||||
err := serv.handlePacket(nil, nil, firstPacket)
|
err := serv.handlePacket(nil, nil, firstPacket)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
@ -334,7 +327,7 @@ var _ = Describe("Server", func() {
|
||||||
|
|
||||||
It("doesn't respond with a version negotiation packet if the first packet is too small", func() {
|
It("doesn't respond with a version negotiation packet if the first packet is too small", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := wire.PublicHeader{
|
||||||
VersionFlag: true,
|
VersionFlag: true,
|
||||||
ConnectionID: 0x1337,
|
ConnectionID: 0x1337,
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
|
@ -402,7 +395,7 @@ var _ = Describe("Server", func() {
|
||||||
It("setups and responds with version negotiation", func() {
|
It("setups and responds with version negotiation", func() {
|
||||||
config.Versions = []protocol.VersionNumber{99}
|
config.Versions = []protocol.VersionNumber{99}
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := wire.PublicHeader{
|
||||||
VersionFlag: true,
|
VersionFlag: true,
|
||||||
ConnectionID: 0x1337,
|
ConnectionID: 0x1337,
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
|
|
|
@ -20,12 +20,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type unpacker interface {
|
type unpacker interface {
|
||||||
Unpack(publicHeaderBinary []byte, hdr *PublicHeader, data []byte) (*unpackedPacket, error)
|
Unpack(publicHeaderBinary []byte, hdr *wire.PublicHeader, data []byte) (*unpackedPacket, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type receivedPacket struct {
|
type receivedPacket struct {
|
||||||
remoteAddr net.Addr
|
remoteAddr net.Addr
|
||||||
publicHeader *PublicHeader
|
publicHeader *wire.PublicHeader
|
||||||
data []byte
|
data []byte
|
||||||
rcvTime time.Time
|
rcvTime time.Time
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ type mockUnpacker struct {
|
||||||
unpackErr error
|
unpackErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockUnpacker) Unpack(publicHeaderBinary []byte, hdr *PublicHeader, data []byte) (*unpackedPacket, error) {
|
func (m *mockUnpacker) Unpack(publicHeaderBinary []byte, hdr *wire.PublicHeader, data []byte) (*unpackedPacket, error) {
|
||||||
if m.unpackErr != nil {
|
if m.unpackErr != nil {
|
||||||
return nil, m.unpackErr
|
return nil, m.unpackErr
|
||||||
}
|
}
|
||||||
|
@ -847,11 +847,11 @@ var _ = Describe("Session", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("receiving packets", func() {
|
Context("receiving packets", func() {
|
||||||
var hdr *PublicHeader
|
var hdr *wire.PublicHeader
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sess.unpacker = &mockUnpacker{}
|
sess.unpacker = &mockUnpacker{}
|
||||||
hdr = &PublicHeader{PacketNumberLen: protocol.PacketNumberLen6}
|
hdr = &wire.PublicHeader{PacketNumberLen: protocol.PacketNumberLen6}
|
||||||
})
|
})
|
||||||
|
|
||||||
It("sets the {last,largest}RcvdPacketNumber", func() {
|
It("sets the {last,largest}RcvdPacketNumber", func() {
|
||||||
|
@ -903,7 +903,7 @@ var _ = Describe("Session", func() {
|
||||||
Expect(sess.conn.(*mockConnection).remoteAddr).ToNot(Equal(remoteIP))
|
Expect(sess.conn.(*mockConnection).remoteAddr).ToNot(Equal(remoteIP))
|
||||||
p := receivedPacket{
|
p := receivedPacket{
|
||||||
remoteAddr: remoteIP,
|
remoteAddr: remoteIP,
|
||||||
publicHeader: &PublicHeader{PacketNumber: 1337},
|
publicHeader: &wire.PublicHeader{PacketNumber: 1337},
|
||||||
}
|
}
|
||||||
err := sess.handlePacketImpl(&p)
|
err := sess.handlePacketImpl(&p)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
@ -919,7 +919,7 @@ var _ = Describe("Session", func() {
|
||||||
sess.unpacker.(*packetUnpacker).aead = &mockAEAD{}
|
sess.unpacker.(*packetUnpacker).aead = &mockAEAD{}
|
||||||
p := receivedPacket{
|
p := receivedPacket{
|
||||||
remoteAddr: attackerIP,
|
remoteAddr: attackerIP,
|
||||||
publicHeader: &PublicHeader{PacketNumber: 1337},
|
publicHeader: &wire.PublicHeader{PacketNumber: 1337},
|
||||||
}
|
}
|
||||||
err := sess.handlePacketImpl(&p)
|
err := sess.handlePacketImpl(&p)
|
||||||
quicErr := err.(*qerr.QuicError)
|
quicErr := err.(*qerr.QuicError)
|
||||||
|
@ -933,7 +933,7 @@ var _ = Describe("Session", func() {
|
||||||
Expect(sess.conn.(*mockConnection).remoteAddr).ToNot(Equal(remoteIP))
|
Expect(sess.conn.(*mockConnection).remoteAddr).ToNot(Equal(remoteIP))
|
||||||
p := receivedPacket{
|
p := receivedPacket{
|
||||||
remoteAddr: remoteIP,
|
remoteAddr: remoteIP,
|
||||||
publicHeader: &PublicHeader{PacketNumber: 1337},
|
publicHeader: &wire.PublicHeader{PacketNumber: 1337},
|
||||||
}
|
}
|
||||||
sess.unpacker.(*mockUnpacker).unpackErr = testErr
|
sess.unpacker.(*mockUnpacker).unpackErr = testErr
|
||||||
err := sess.handlePacketImpl(&p)
|
err := sess.handlePacketImpl(&p)
|
||||||
|
@ -1347,7 +1347,7 @@ var _ = Describe("Session", func() {
|
||||||
// this completely fills up the undecryptable packets queue and triggers the public reset timer
|
// this completely fills up the undecryptable packets queue and triggers the public reset timer
|
||||||
sendUndecryptablePackets := func() {
|
sendUndecryptablePackets := func() {
|
||||||
for i := 0; i < protocol.MaxUndecryptablePackets+1; i++ {
|
for i := 0; i < protocol.MaxUndecryptablePackets+1; i++ {
|
||||||
hdr := &PublicHeader{
|
hdr := &wire.PublicHeader{
|
||||||
PacketNumber: protocol.PacketNumber(i + 1),
|
PacketNumber: protocol.PacketNumber(i + 1),
|
||||||
}
|
}
|
||||||
sess.handlePacket(&receivedPacket{
|
sess.handlePacket(&receivedPacket{
|
||||||
|
@ -1420,7 +1420,7 @@ var _ = Describe("Session", func() {
|
||||||
|
|
||||||
It("unqueues undecryptable packets for later decryption", func() {
|
It("unqueues undecryptable packets for later decryption", func() {
|
||||||
sess.undecryptablePackets = []*receivedPacket{{
|
sess.undecryptablePackets = []*receivedPacket{{
|
||||||
publicHeader: &PublicHeader{PacketNumber: protocol.PacketNumber(42)},
|
publicHeader: &wire.PublicHeader{PacketNumber: protocol.PacketNumber(42)},
|
||||||
}}
|
}}
|
||||||
Expect(sess.receivedPackets).NotTo(Receive())
|
Expect(sess.receivedPackets).NotTo(Receive())
|
||||||
sess.tryDecryptingQueuedPackets()
|
sess.tryDecryptingQueuedPackets()
|
||||||
|
@ -1722,10 +1722,10 @@ var _ = Describe("Client Session", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("receiving packets", func() {
|
Context("receiving packets", func() {
|
||||||
var hdr *PublicHeader
|
var hdr *wire.PublicHeader
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
hdr = &PublicHeader{PacketNumberLen: protocol.PacketNumberLen6}
|
hdr = &wire.PublicHeader{PacketNumberLen: protocol.PacketNumberLen6}
|
||||||
sess.unpacker = &mockUnpacker{}
|
sess.unpacker = &mockUnpacker{}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package quic
|
package wire
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -11,13 +11,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errPacketNumberLenNotSet = errors.New("PublicHeader: PacketNumberLen not set")
|
// ErrPacketWithUnknownVersion occurs when a packet with an unknown version is parsed.
|
||||||
|
// This can happen when the server is restarted. The client will send a packet without a version number.
|
||||||
|
ErrPacketWithUnknownVersion = errors.New("PublicHeader: Received a packet without version number, that we don't know the version for")
|
||||||
errResetAndVersionFlagSet = errors.New("PublicHeader: Reset Flag and Version Flag should not be set at the same time")
|
errResetAndVersionFlagSet = errors.New("PublicHeader: Reset Flag and Version Flag should not be set at the same time")
|
||||||
errReceivedTruncatedConnectionID = qerr.Error(qerr.InvalidPacketHeader, "receiving packets with truncated ConnectionID is not supported")
|
errReceivedTruncatedConnectionID = qerr.Error(qerr.InvalidPacketHeader, "receiving packets with truncated ConnectionID is not supported")
|
||||||
errInvalidConnectionID = qerr.Error(qerr.InvalidPacketHeader, "connection ID cannot be 0")
|
errInvalidConnectionID = qerr.Error(qerr.InvalidPacketHeader, "connection ID cannot be 0")
|
||||||
errGetLengthNotForVersionNegotiation = errors.New("PublicHeader: GetLength cannot be called for VersionNegotiation packets")
|
errGetLengthNotForVersionNegotiation = errors.New("PublicHeader: GetLength cannot be called for VersionNegotiation packets")
|
||||||
// this can happen when the server is restarted. The client will send a packet without a version number
|
|
||||||
errPacketWithUnknownVersion = errors.New("PublicHeader: Received a packet without version number, that we don't know the version for")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// The PublicHeader of a QUIC packet. Warning: This struct should not be considered stable and will change soon.
|
// The PublicHeader of a QUIC packet. Warning: This struct should not be considered stable and will change soon.
|
||||||
|
@ -93,10 +93,6 @@ func (h *PublicHeader) Write(b *bytes.Buffer, version protocol.VersionNumber, pe
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.PacketNumberLen != protocol.PacketNumberLen1 && h.PacketNumberLen != protocol.PacketNumberLen2 && h.PacketNumberLen != protocol.PacketNumberLen4 && h.PacketNumberLen != protocol.PacketNumberLen6 {
|
|
||||||
return errPacketNumberLenNotSet
|
|
||||||
}
|
|
||||||
|
|
||||||
switch h.PacketNumberLen {
|
switch h.PacketNumberLen {
|
||||||
case protocol.PacketNumberLen1:
|
case protocol.PacketNumberLen1:
|
||||||
b.WriteByte(uint8(h.PacketNumber))
|
b.WriteByte(uint8(h.PacketNumber))
|
||||||
|
@ -107,15 +103,15 @@ func (h *PublicHeader) Write(b *bytes.Buffer, version protocol.VersionNumber, pe
|
||||||
case protocol.PacketNumberLen6:
|
case protocol.PacketNumberLen6:
|
||||||
utils.GetByteOrder(version).WriteUint48(b, uint64(h.PacketNumber)&(1<<48-1))
|
utils.GetByteOrder(version).WriteUint48(b, uint64(h.PacketNumber)&(1<<48-1))
|
||||||
default:
|
default:
|
||||||
return errPacketNumberLenNotSet
|
return errors.New("PublicHeader: PacketNumberLen not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// peekConnectionID parses the connection ID from a QUIC packet's public header.
|
// PeekConnectionID parses the connection ID from a QUIC packet's public header.
|
||||||
// If no error occurs, it restores the read position in the bytes.Reader.
|
// If no error occurs, it restores the read position in the bytes.Reader.
|
||||||
func peekConnectionID(b *bytes.Reader, packetSentBy protocol.Perspective) (protocol.ConnectionID, error) {
|
func PeekConnectionID(b *bytes.Reader, packetSentBy protocol.Perspective) (protocol.ConnectionID, error) {
|
||||||
var connectionID protocol.ConnectionID
|
var connectionID protocol.ConnectionID
|
||||||
publicFlagByte, err := b.ReadByte()
|
publicFlagByte, err := b.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -156,7 +152,7 @@ func ParsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective, versi
|
||||||
header.ResetFlag = publicFlagByte&0x02 > 0
|
header.ResetFlag = publicFlagByte&0x02 > 0
|
||||||
header.VersionFlag = publicFlagByte&0x01 > 0
|
header.VersionFlag = publicFlagByte&0x01 > 0
|
||||||
if version == protocol.VersionUnknown && !(header.VersionFlag || header.ResetFlag) {
|
if version == protocol.VersionUnknown && !(header.VersionFlag || header.ResetFlag) {
|
||||||
return nil, errPacketWithUnknownVersion
|
return nil, ErrPacketWithUnknownVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: activate this check once Chrome sends the correct value
|
// TODO: activate this check once Chrome sends the correct value
|
|
@ -1,4 +1,4 @@
|
||||||
package quic
|
package wire
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -15,14 +15,14 @@ var _ = Describe("Public Header", func() {
|
||||||
Context("parsing the connection ID", func() {
|
Context("parsing the connection ID", func() {
|
||||||
It("does not accept truncated connection ID as a server", func() {
|
It("does not accept truncated connection ID as a server", func() {
|
||||||
b := bytes.NewReader([]byte{0x00, 0x01})
|
b := bytes.NewReader([]byte{0x00, 0x01})
|
||||||
_, err := peekConnectionID(b, protocol.PerspectiveClient)
|
_, err := PeekConnectionID(b, protocol.PerspectiveClient)
|
||||||
Expect(err).To(MatchError(errReceivedTruncatedConnectionID))
|
Expect(err).To(MatchError(errReceivedTruncatedConnectionID))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("gets the connection ID", func() {
|
It("gets the connection ID", func() {
|
||||||
b := bytes.NewReader([]byte{0x09, 0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c, 0x51, 0x30, 0x33, 0x34, 0x01})
|
b := bytes.NewReader([]byte{0x09, 0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c, 0x51, 0x30, 0x33, 0x34, 0x01})
|
||||||
len := b.Len()
|
len := b.Len()
|
||||||
connID, err := peekConnectionID(b, protocol.PerspectiveClient)
|
connID, err := PeekConnectionID(b, protocol.PerspectiveClient)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(connID).To(Equal(protocol.ConnectionID(0x4cfa9f9b668619f6)))
|
Expect(connID).To(Equal(protocol.ConnectionID(0x4cfa9f9b668619f6)))
|
||||||
Expect(b.Len()).To(Equal(len))
|
Expect(b.Len()).To(Equal(len))
|
||||||
|
@ -30,20 +30,20 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("errors if the Public Header is too short", func() {
|
It("errors if the Public Header is too short", func() {
|
||||||
b := bytes.NewReader([]byte{0x09, 0xf6, 0x19, 0x86, 0x66, 0x9b})
|
b := bytes.NewReader([]byte{0x09, 0xf6, 0x19, 0x86, 0x66, 0x9b})
|
||||||
_, err := peekConnectionID(b, protocol.PerspectiveClient)
|
_, err := PeekConnectionID(b, protocol.PerspectiveClient)
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("errors if the Public Header is empty", func() {
|
It("errors if the Public Header is empty", func() {
|
||||||
b := bytes.NewReader([]byte{})
|
b := bytes.NewReader([]byte{})
|
||||||
_, err := peekConnectionID(b, protocol.PerspectiveClient)
|
_, err := PeekConnectionID(b, protocol.PerspectiveClient)
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("accepts a truncated connection ID as a client", func() {
|
It("accepts a truncated connection ID as a client", func() {
|
||||||
b := bytes.NewReader([]byte{0x00, 0x01})
|
b := bytes.NewReader([]byte{0x00, 0x01})
|
||||||
len := b.Len()
|
len := b.Len()
|
||||||
connID, err := peekConnectionID(b, protocol.PerspectiveServer)
|
connID, err := PeekConnectionID(b, protocol.PerspectiveServer)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(connID).To(BeZero())
|
Expect(connID).To(BeZero())
|
||||||
Expect(b.Len()).To(Equal(len))
|
Expect(b.Len()).To(Equal(len))
|
||||||
|
@ -116,7 +116,7 @@ var _ = Describe("Public Header", func() {
|
||||||
It("returns an unknown version error when receiving a packet without a version for which the version is not given", func() {
|
It("returns an unknown version error when receiving a packet without a version for which the version is not given", func() {
|
||||||
b := bytes.NewReader([]byte{0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xef})
|
b := bytes.NewReader([]byte{0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xef})
|
||||||
_, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
_, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
||||||
Expect(err).To(MatchError(errPacketWithUnknownVersion))
|
Expect(err).To(MatchError(ErrPacketWithUnknownVersion))
|
||||||
})
|
})
|
||||||
|
|
||||||
PIt("rejects diversification nonces sent by the client", func() {
|
PIt("rejects diversification nonces sent by the client", func() {
|
||||||
|
@ -136,7 +136,7 @@ var _ = Describe("Public Header", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
It("parses version negotiation packets sent by the server", func() {
|
It("parses version negotiation packets sent by the server", func() {
|
||||||
b := bytes.NewReader(composeVersionNegotiation(0x1337, protocol.SupportedVersions))
|
b := bytes.NewReader(ComposeVersionNegotiation(0x1337, protocol.SupportedVersions))
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
hdr, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.VersionFlag).To(BeTrue())
|
Expect(hdr.VersionFlag).To(BeTrue())
|
||||||
|
@ -169,7 +169,7 @@ var _ = Describe("Public Header", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("errors on invalid version tags", func() {
|
It("errors on invalid version tags", func() {
|
||||||
data := composeVersionNegotiation(0x1337, protocol.SupportedVersions)
|
data := ComposeVersionNegotiation(0x1337, protocol.SupportedVersions)
|
||||||
data = append(data, []byte{0x13, 0x37}...)
|
data = append(data, []byte{0x13, 0x37}...)
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
_, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
_, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
||||||
|
@ -300,7 +300,7 @@ var _ = Describe("Public Header", func() {
|
||||||
}
|
}
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
||||||
Expect(err).To(MatchError(errPacketNumberLenNotSet))
|
Expect(err).To(MatchError("PublicHeader: PacketNumberLen not set"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("truncates the connection ID", func() {
|
It("truncates the connection ID", func() {
|
||||||
|
@ -526,7 +526,7 @@ var _ = Describe("Public Header", func() {
|
||||||
PacketNumber: 0xDECAFBAD,
|
PacketNumber: 0xDECAFBAD,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
||||||
Expect(err).To(MatchError(errPacketNumberLenNotSet))
|
Expect(err).To(MatchError("PublicHeader: PacketNumberLen not set"))
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("in little endian", func() {
|
Context("in little endian", func() {
|
26
wire/version_negotiation.go
Normal file
26
wire/version_negotiation.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package wire
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||||
|
"github.com/lucas-clemente/quic-go/protocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ComposeVersionNegotiation composes a Version Negotiation Packet
|
||||||
|
func ComposeVersionNegotiation(connectionID protocol.ConnectionID, versions []protocol.VersionNumber) []byte {
|
||||||
|
fullReply := &bytes.Buffer{}
|
||||||
|
responsePublicHeader := PublicHeader{
|
||||||
|
ConnectionID: connectionID,
|
||||||
|
PacketNumber: 1,
|
||||||
|
VersionFlag: true,
|
||||||
|
}
|
||||||
|
err := responsePublicHeader.Write(fullReply, protocol.VersionWhatever, protocol.PerspectiveServer)
|
||||||
|
if err != nil {
|
||||||
|
utils.Errorf("error composing version negotiation packet: %s", err.Error())
|
||||||
|
}
|
||||||
|
for _, v := range versions {
|
||||||
|
utils.LittleEndian.WriteUint32(fullReply, protocol.VersionNumberToTag(v))
|
||||||
|
}
|
||||||
|
return fullReply.Bytes()
|
||||||
|
}
|
17
wire/version_negotiation_test.go
Normal file
17
wire/version_negotiation_test.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package wire
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/lucas-clemente/quic-go/protocol"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Version Negotiation Packet", func() {
|
||||||
|
It("composes version negotiation packets", func() {
|
||||||
|
expected := append(
|
||||||
|
[]byte{0x01 | 0x08, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
[]byte{'Q', '0', '9', '9'}...,
|
||||||
|
)
|
||||||
|
Expect(ComposeVersionNegotiation(1, []protocol.VersionNumber{99})).To(Equal(expected))
|
||||||
|
})
|
||||||
|
})
|
Loading…
Add table
Add a link
Reference in a new issue