move parsing of version negotiation packets to the wire.Header

This commit is contained in:
Marten Seemann 2018-11-25 12:36:45 +07:00
parent 5581fee684
commit 9bcedd988d
15 changed files with 167 additions and 176 deletions

View file

@ -302,8 +302,8 @@ func (c *client) handlePacketImpl(p *receivedPacket) error {
defer c.mutex.Unlock()
// handle Version Negotiation Packets
if p.header.IsVersionNegotiation {
err := c.handleVersionNegotiationPacket(p.header)
if p.hdr.IsVersionNegotiation() {
err := c.handleVersionNegotiationPacket(p.hdr)
if err != nil {
c.session.destroy(err)
}
@ -312,12 +312,12 @@ func (c *client) handlePacketImpl(p *receivedPacket) error {
}
// reject packets with the wrong connection ID
if !p.header.DestConnectionID.Equal(c.srcConnID) {
return fmt.Errorf("received a packet with an unexpected connection ID (%s, expected %s)", p.header.DestConnectionID, c.srcConnID)
if !p.hdr.DestConnectionID.Equal(c.srcConnID) {
return fmt.Errorf("received a packet with an unexpected connection ID (%s, expected %s)", p.hdr.DestConnectionID, c.srcConnID)
}
if p.header.Type == protocol.PacketTypeRetry {
c.handleRetryPacket(p.header)
if p.extHdr.Type == protocol.PacketTypeRetry {
c.handleRetryPacket(p.extHdr)
return nil
}
@ -331,7 +331,7 @@ func (c *client) handlePacketImpl(p *receivedPacket) error {
return nil
}
func (c *client) handleVersionNegotiationPacket(hdr *wire.ExtendedHeader) error {
func (c *client) handleVersionNegotiationPacket(hdr *wire.Header) error {
// ignore delayed / duplicated version negotiation packets
if c.receivedVersionNegotiationPacket || c.versionNegotiated {
c.logger.Debugf("Received a delayed Version Negotiation Packet.")

View file

@ -58,13 +58,14 @@ var _ = Describe("Client", func() {
}
composeVersionNegotiationPacket := func(connID protocol.ConnectionID, versions []protocol.VersionNumber) *receivedPacket {
data, err := wire.ComposeVersionNegotiation(connID, nil, versions)
Expect(err).ToNot(HaveOccurred())
hdr, err := wire.ParseHeader(bytes.NewReader(data), 0)
Expect(err).ToNot(HaveOccurred())
Expect(hdr.IsVersionNegotiation()).To(BeTrue())
return &receivedPacket{
rcvTime: time.Now(),
header: &wire.ExtendedHeader{
IsVersionNegotiation: true,
DestConnectionID: connID,
SupportedVersions: versions,
},
hdr: hdr,
}
}
@ -510,11 +511,14 @@ var _ = Describe("Client", func() {
manager := NewMockPacketHandlerManager(mockCtrl)
manager.EXPECT().Add(gomock.Any(), gomock.Any()).Do(func(id protocol.ConnectionID, handler packetHandler) {
go handler.handlePacket(&receivedPacket{
header: &wire.ExtendedHeader{
hdr: &wire.Header{
Version: cl.version,
DestConnectionID: id,
},
extHdr: &wire.ExtendedHeader{
IsLongHeader: true,
Type: protocol.PacketTypeRetry,
Token: []byte("foobar"),
DestConnectionID: id,
OrigDestConnectionID: connID,
},
})
@ -570,12 +574,15 @@ var _ = Describe("Client", func() {
manager := NewMockPacketHandlerManager(mockCtrl)
manager.EXPECT().Add(gomock.Any(), gomock.Any()).Do(func(id protocol.ConnectionID, handler packetHandler) {
go handler.handlePacket(&receivedPacket{
header: &wire.ExtendedHeader{
hdr: &wire.Header{
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4},
DestConnectionID: id,
Version: cl.version,
},
extHdr: &wire.ExtendedHeader{
IsLongHeader: true,
Type: protocol.PacketTypeRetry,
Token: []byte("foobar"),
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4},
DestConnectionID: id,
OrigDestConnectionID: connID,
Version: protocol.VersionTLS,
},
@ -673,18 +680,22 @@ var _ = Describe("Client", func() {
Expect(err).To(MatchError(testErr))
})
It("recognizes that a packet without VersionFlag means that the server accepted the suggested version", func() {
It("recognizes that a non version negotiation packet means that the server accepted the suggested version", func() {
sess := NewMockQuicSession(mockCtrl)
sess.EXPECT().handlePacket(gomock.Any())
cl.session = sess
cl.config = &Config{}
ph := &wire.ExtendedHeader{
PacketNumber: 1,
PacketNumberLen: protocol.PacketNumberLen2,
DestConnectionID: connID,
SrcConnectionID: connID,
}
err := cl.handlePacketImpl(&receivedPacket{header: ph})
err := cl.handlePacketImpl(&receivedPacket{
hdr: &wire.Header{
DestConnectionID: connID,
SrcConnectionID: connID,
Version: cl.version,
},
extHdr: &wire.ExtendedHeader{
PacketNumber: 1,
PacketNumberLen: protocol.PacketNumberLen2,
},
})
Expect(err).ToNot(HaveOccurred())
Expect(cl.versionNegotiated).To(BeTrue())
})
@ -738,16 +749,17 @@ var _ = Describe("Client", func() {
cl.session = NewMockQuicSession(mockCtrl) // don't EXPECT any handlePacket calls
connID2 := protocol.ConnectionID{8, 7, 6, 5, 4, 3, 2, 1}
Expect(connID).ToNot(Equal(connID2))
hdr := &wire.ExtendedHeader{
DestConnectionID: connID2,
SrcConnectionID: connID,
PacketNumber: 1,
PacketNumberLen: protocol.PacketNumberLen1,
}
err := cl.handlePacketImpl(&receivedPacket{
Expect(cl.handlePacketImpl(&receivedPacket{
remoteAddr: addr,
header: hdr,
})
Expect(err).To(MatchError(fmt.Sprintf("received a packet with an unexpected connection ID (0x0807060504030201, expected %s)", connID)))
hdr: &wire.Header{
DestConnectionID: connID2,
SrcConnectionID: connID,
Version: cl.version,
},
extHdr: &wire.ExtendedHeader{
PacketNumber: 1,
PacketNumberLen: protocol.PacketNumberLen1,
},
})).To(MatchError(fmt.Sprintf("received a packet with an unexpected connection ID (0x0807060504030201, expected %s)", connID)))
})
})

View file

@ -22,9 +22,6 @@ type ExtendedHeader struct {
PacketNumberLen protocol.PacketNumberLen
PacketNumber protocol.PacketNumber
IsVersionNegotiation bool
SupportedVersions []protocol.VersionNumber // Version Number sent in a Version Negotiation Packet by the server
Type protocol.PacketType
IsLongHeader bool
KeyPhase int
@ -103,23 +100,19 @@ func (h *ExtendedHeader) GetLength(v protocol.VersionNumber) protocol.ByteCount
// Log logs the Header
func (h *ExtendedHeader) Log(logger utils.Logger) {
if h.IsLongHeader {
if h.Version == 0 {
logger.Debugf("\tVersionNegotiationPacket{DestConnectionID: %s, SrcConnectionID: %s, SupportedVersions: %s}", h.DestConnectionID, h.SrcConnectionID, h.SupportedVersions)
} else {
var token string
if h.Type == protocol.PacketTypeInitial || h.Type == protocol.PacketTypeRetry {
if len(h.Token) == 0 {
token = "Token: (empty), "
} else {
token = fmt.Sprintf("Token: %#x, ", h.Token)
}
var token string
if h.Type == protocol.PacketTypeInitial || h.Type == protocol.PacketTypeRetry {
if len(h.Token) == 0 {
token = "Token: (empty), "
} else {
token = fmt.Sprintf("Token: %#x, ", h.Token)
}
if h.Type == protocol.PacketTypeRetry {
logger.Debugf("\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, %sOrigDestConnectionID: %s, Version: %s}", h.Type, h.DestConnectionID, h.SrcConnectionID, token, h.OrigDestConnectionID, h.Version)
return
}
logger.Debugf("\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, %sPacketNumber: %#x, PacketNumberLen: %d, Length: %d, Version: %s}", h.Type, h.DestConnectionID, h.SrcConnectionID, token, h.PacketNumber, h.PacketNumberLen, h.Length, h.Version)
}
logger.Debugf("\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, %sPacketNumber: %#x, PacketNumberLen: %d, Length: %d, Version: %s}", h.Type, h.DestConnectionID, h.SrcConnectionID, token, h.PacketNumber, h.PacketNumberLen, h.Length, h.Version)
} else {
logger.Debugf("\tShort Header{DestConnectionID: %s, PacketNumber: %#x, PacketNumberLen: %d, KeyPhase: %d}", h.DestConnectionID, h.PacketNumber, h.PacketNumberLen, h.KeyPhase)
}

View file

@ -321,21 +321,6 @@ var _ = Describe("Header", func() {
log.SetOutput(os.Stdout)
})
It("logs version negotiation packets", func() {
destConnID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}
srcConnID := protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad, 0x013, 0x37, 0x13, 0x37}
data, err := ComposeVersionNegotiation(destConnID, srcConnID, []protocol.VersionNumber{0x12345678, 0x87654321})
Expect(err).ToNot(HaveOccurred())
hdr, err := ParseHeader(bytes.NewReader(data), 4)
Expect(err).ToNot(HaveOccurred())
extHdr, err := hdr.Parse(bytes.NewReader(data), versionIETFHeader)
Expect(err).ToNot(HaveOccurred())
extHdr.Log(logger)
Expect(buf.String()).To(ContainSubstring("VersionNegotiationPacket{DestConnectionID: 0xdeadbeefcafe1337, SrcConnectionID: 0xdecafbad13371337"))
Expect(buf.String()).To(ContainSubstring("0x12345678"))
Expect(buf.String()).To(ContainSubstring("0x87654321"))
})
It("logs Long Headers", func() {
(&ExtendedHeader{
IsLongHeader: true,

View file

@ -12,11 +12,12 @@ import (
// The Header is the version independent part of the header
type Header struct {
IsLongHeader bool
Version protocol.VersionNumber
SrcConnectionID protocol.ConnectionID
DestConnectionID protocol.ConnectionID
SupportedVersions []protocol.VersionNumber // sent in a Version Negotiation Packet
typeByte byte
len int // how many bytes were read while parsing this header
}
@ -39,10 +40,9 @@ func parseHeaderImpl(b *bytes.Reader, shortHeaderConnIDLen int) (*Header, error)
}
h := &Header{typeByte: typeByte}
h.IsLongHeader = typeByte&0x80 > 0
// If this is not a Long Header, it could either be a Public Header or a Short Header.
if !h.IsLongHeader {
if !h.IsLongHeader() {
var err error
h.DestConnectionID, err = protocol.ReadConnectionID(b, shortHeaderConnIDLen)
if err != nil {
@ -69,19 +69,39 @@ func parseHeaderImpl(b *bytes.Reader, shortHeaderConnIDLen int) (*Header, error)
if err != nil {
return nil, err
}
if h.Version == 0 {
if b.Len() == 0 {
return nil, qerr.Error(qerr.InvalidVersionNegotiationPacket, "empty version list")
}
h.SupportedVersions = make([]protocol.VersionNumber, b.Len()/4)
for i := 0; b.Len() > 0; i++ {
v, err := utils.BigEndian.ReadUint32(b)
if err != nil {
return nil, qerr.InvalidVersionNegotiationPacket
}
h.SupportedVersions[i] = protocol.VersionNumber(v)
}
}
return h, nil
}
// IsLongHeader says if this is a long header
func (h *Header) IsLongHeader() bool {
return h.typeByte&0x80 > 0
}
// IsVersionNegotiation says if this a version negotiation packet
func (h *Header) IsVersionNegotiation() bool {
return h.IsLongHeader() && h.Version == 0
}
// Parse parses the version dependent part of the header.
// The Reader has to be set such that it points to the first byte of the header.
func (h *Header) Parse(b *bytes.Reader, ver protocol.VersionNumber) (*ExtendedHeader, error) {
if _, err := b.Seek(int64(h.len), io.SeekCurrent); err != nil {
return nil, err
}
if h.IsLongHeader {
if h.Version == 0 { // Version Negotiation Packet
return h.parseVersionNegotiationPacket(b)
}
if h.IsLongHeader() {
return h.parseLongHeader(b, ver)
}
return h.parseShortHeader(b, ver)
@ -89,30 +109,13 @@ func (h *Header) Parse(b *bytes.Reader, ver protocol.VersionNumber) (*ExtendedHe
func (h *Header) toExtendedHeader() *ExtendedHeader {
return &ExtendedHeader{
IsLongHeader: h.IsLongHeader,
IsLongHeader: h.IsLongHeader(),
DestConnectionID: h.DestConnectionID,
SrcConnectionID: h.SrcConnectionID,
Version: h.Version,
}
}
func (h *Header) parseVersionNegotiationPacket(b *bytes.Reader) (*ExtendedHeader, error) {
eh := h.toExtendedHeader()
if b.Len() == 0 {
return nil, qerr.Error(qerr.InvalidVersionNegotiationPacket, "empty version list")
}
eh.IsVersionNegotiation = true
eh.SupportedVersions = make([]protocol.VersionNumber, b.Len()/4)
for i := 0; b.Len() > 0; i++ {
v, err := utils.BigEndian.ReadUint32(b)
if err != nil {
return nil, qerr.InvalidVersionNegotiationPacket
}
eh.SupportedVersions[i] = protocol.VersionNumber(v)
}
return eh, nil
}
func (h *Header) parseLongHeader(b *bytes.Reader, v protocol.VersionNumber) (*ExtendedHeader, error) {
eh := h.toExtendedHeader()
eh.Type = protocol.PacketType(h.typeByte & 0x7f)

View file

@ -25,20 +25,16 @@ var _ = Describe("Header Parsing", func() {
versions := []protocol.VersionNumber{0x22334455, 0x33445566}
data, err := ComposeVersionNegotiation(destConnID, srcConnID, versions)
Expect(err).ToNot(HaveOccurred())
hdr, err := ParseHeader(bytes.NewReader(data), 0)
b := bytes.NewReader(data)
hdr, err := ParseHeader(b, 0)
Expect(err).ToNot(HaveOccurred())
Expect(hdr.DestConnectionID).To(Equal(destConnID))
Expect(hdr.SrcConnectionID).To(Equal(srcConnID))
Expect(hdr.IsLongHeader).To(BeTrue())
b := bytes.NewReader(data)
extHdr, err := hdr.Parse(b, versionIETFFrames)
Expect(err).ToNot(HaveOccurred())
Expect(extHdr.IsVersionNegotiation).To(BeTrue())
Expect(extHdr.Version).To(BeZero())
Expect(extHdr.DestConnectionID).To(Equal(destConnID))
Expect(extHdr.SrcConnectionID).To(Equal(srcConnID))
Expect(hdr.IsLongHeader()).To(BeTrue())
Expect(hdr.IsVersionNegotiation()).To(BeTrue())
Expect(hdr.Version).To(BeZero())
for _, v := range versions {
Expect(extHdr.SupportedVersions).To(ContainElement(v))
Expect(hdr.SupportedVersions).To(ContainElement(v))
}
Expect(b.Len()).To(BeZero())
})
@ -49,9 +45,7 @@ var _ = Describe("Header Parsing", func() {
data, err := ComposeVersionNegotiation(connID, connID, versions)
Expect(err).ToNot(HaveOccurred())
data = data[:len(data)-2]
hdr, err := ParseHeader(bytes.NewReader(data), 0)
Expect(err).ToNot(HaveOccurred())
_, err = hdr.Parse(bytes.NewReader(data), versionIETFFrames)
_, err = ParseHeader(bytes.NewReader(data), 0)
Expect(err).To(MatchError(qerr.InvalidVersionNegotiationPacket))
})
@ -62,9 +56,7 @@ var _ = Describe("Header Parsing", func() {
Expect(err).ToNot(HaveOccurred())
// remove 8 bytes (two versions), since ComposeVersionNegotiation also added a reserved version number
data = data[:len(data)-8]
hdr, err := ParseHeader(bytes.NewReader(data), 0)
Expect(err).ToNot(HaveOccurred())
_, err = hdr.Parse(bytes.NewReader(data), versionIETFFrames)
_, err = ParseHeader(bytes.NewReader(data), 0)
Expect(err).To(MatchError("InvalidVersionNegotiationPacket: empty version list"))
})
})
@ -88,7 +80,8 @@ var _ = Describe("Header Parsing", func() {
hdr, err := ParseHeader(bytes.NewReader(data), 0)
Expect(err).ToNot(HaveOccurred())
Expect(hdr.IsLongHeader).To(BeTrue())
Expect(hdr.IsLongHeader()).To(BeTrue())
Expect(hdr.IsVersionNegotiation()).To(BeFalse())
Expect(hdr.DestConnectionID).To(Equal(destConnID))
Expect(hdr.SrcConnectionID).To(Equal(srcConnID))
b := bytes.NewReader(data)
@ -103,7 +96,6 @@ var _ = Describe("Header Parsing", func() {
Expect(extHdr.PacketNumber).To(Equal(protocol.PacketNumber(0xbeef)))
Expect(extHdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen4))
Expect(extHdr.Version).To(Equal(protocol.VersionNumber(0x1020304)))
Expect(extHdr.IsVersionNegotiation).To(BeFalse())
Expect(b.Len()).To(BeZero())
})
@ -272,7 +264,8 @@ var _ = Describe("Header Parsing", func() {
data = appendPacketNumber(data, 0x42, protocol.PacketNumberLen1)
hdr, err := ParseHeader(bytes.NewReader(data), 8)
Expect(err).ToNot(HaveOccurred())
Expect(hdr.IsLongHeader).To(BeFalse())
Expect(hdr.IsLongHeader()).To(BeFalse())
Expect(hdr.IsVersionNegotiation()).To(BeFalse())
Expect(hdr.DestConnectionID).To(Equal(connID))
b := bytes.NewReader(data)
extHdr, err := hdr.Parse(b, versionIETFFrames)
@ -281,7 +274,6 @@ var _ = Describe("Header Parsing", func() {
Expect(extHdr.DestConnectionID).To(Equal(connID))
Expect(extHdr.SrcConnectionID).To(BeEmpty())
Expect(extHdr.PacketNumber).To(Equal(protocol.PacketNumber(0x42)))
Expect(extHdr.IsVersionNegotiation).To(BeFalse())
Expect(b.Len()).To(BeZero())
})
@ -291,7 +283,7 @@ var _ = Describe("Header Parsing", func() {
data = appendPacketNumber(data, 0x42, protocol.PacketNumberLen1)
hdr, err := ParseHeader(bytes.NewReader(data), 5)
Expect(err).ToNot(HaveOccurred())
Expect(hdr.IsLongHeader).To(BeFalse())
Expect(hdr.IsLongHeader()).To(BeFalse())
Expect(hdr.DestConnectionID).To(Equal(connID))
b := bytes.NewReader(data)
extHdr, err := hdr.Parse(b, versionIETFFrames)
@ -310,10 +302,10 @@ var _ = Describe("Header Parsing", func() {
data = appendPacketNumber(data, 11, protocol.PacketNumberLen1)
hdr, err := ParseHeader(bytes.NewReader(data), 6)
Expect(err).ToNot(HaveOccurred())
Expect(hdr.IsLongHeader()).To(BeFalse())
b := bytes.NewReader(data)
extHdr, err := hdr.Parse(b, versionIETFFrames)
Expect(err).ToNot(HaveOccurred())
Expect(extHdr.IsLongHeader).To(BeFalse())
Expect(extHdr.KeyPhase).To(Equal(1))
Expect(b.Len()).To(BeZero())
})

View file

@ -16,19 +16,17 @@ var _ = Describe("Version Negotiation Packets", func() {
data, err := ComposeVersionNegotiation(destConnID, srcConnID, versions)
Expect(err).ToNot(HaveOccurred())
Expect(data[0] & 0x80).ToNot(BeZero())
hdr, err := ParseHeader(bytes.NewReader(data), 4)
Expect(err).ToNot(HaveOccurred())
b := bytes.NewReader(data)
extHdr, err := hdr.Parse(b, versionIETFFrames)
hdr, err := ParseHeader(b, 4)
Expect(err).ToNot(HaveOccurred())
Expect(extHdr.IsVersionNegotiation).To(BeTrue())
Expect(extHdr.DestConnectionID).To(Equal(destConnID))
Expect(extHdr.SrcConnectionID).To(Equal(srcConnID))
Expect(extHdr.Version).To(BeZero())
Expect(err).ToNot(HaveOccurred())
Expect(hdr.DestConnectionID).To(Equal(destConnID))
Expect(hdr.SrcConnectionID).To(Equal(srcConnID))
Expect(hdr.Version).To(BeZero())
// the supported versions should include one reserved version number
Expect(extHdr.SupportedVersions).To(HaveLen(len(versions) + 1))
Expect(hdr.SupportedVersions).To(HaveLen(len(versions) + 1))
for _, version := range versions {
Expect(extHdr.SupportedVersions).To(ContainElement(version))
Expect(hdr.SupportedVersions).To(ContainElement(version))
}
Expect(b.Len()).To(BeZero())
})

View file

@ -183,7 +183,7 @@ func (h *packetHandlerMap) handlePacket(addr net.Addr, data []byte) error {
handlePacket = handler.handlePacket
} else { // no session found
// this might be a stateless reset
if !hdr.IsLongHeader {
if !hdr.IsLongHeader() {
if len(data) >= protocol.MinStatelessResetSize {
var token [16]byte
copy(token[:], data[len(data)-16:])
@ -205,28 +205,34 @@ func (h *packetHandlerMap) handlePacket(addr net.Addr, data []byte) error {
}
h.mutex.RUnlock()
r = bytes.NewReader(data)
extHdr, err := hdr.Parse(r, version)
if err != nil {
return fmt.Errorf("error parsing extended header: %s", err)
}
extHdr.Raw = data[:len(data)-r.Len()]
packetData := data[len(data)-r.Len():]
var extHdr *wire.ExtendedHeader
var packetData []byte
if !hdr.IsVersionNegotiation() {
r = bytes.NewReader(data)
var err error
extHdr, err = hdr.Parse(r, version)
if err != nil {
return fmt.Errorf("error parsing extended header: %s", err)
}
extHdr.Raw = data[:len(data)-r.Len()]
packetData = data[len(data)-r.Len():]
if extHdr.IsLongHeader {
if extHdr.Length < protocol.ByteCount(extHdr.PacketNumberLen) {
return fmt.Errorf("packet length (%d bytes) shorter than packet number (%d bytes)", extHdr.Length, extHdr.PacketNumberLen)
if hdr.IsLongHeader() {
if extHdr.Length < protocol.ByteCount(extHdr.PacketNumberLen) {
return fmt.Errorf("packet length (%d bytes) shorter than packet number (%d bytes)", extHdr.Length, extHdr.PacketNumberLen)
}
if protocol.ByteCount(len(packetData))+protocol.ByteCount(extHdr.PacketNumberLen) < extHdr.Length {
return fmt.Errorf("packet length (%d bytes) is smaller than the expected length (%d bytes)", len(packetData)+int(extHdr.PacketNumberLen), extHdr.Length)
}
packetData = packetData[:int(extHdr.Length)-int(extHdr.PacketNumberLen)]
// TODO(#1312): implement parsing of compound packets
}
if protocol.ByteCount(len(packetData))+protocol.ByteCount(extHdr.PacketNumberLen) < extHdr.Length {
return fmt.Errorf("packet length (%d bytes) is smaller than the expected length (%d bytes)", len(packetData)+int(extHdr.PacketNumberLen), extHdr.Length)
}
packetData = packetData[:int(extHdr.Length)-int(extHdr.PacketNumberLen)]
// TODO(#1312): implement parsing of compound packets
}
handlePacket(&receivedPacket{
remoteAddr: addr,
header: extHdr,
hdr: hdr,
extHdr: extHdr,
data: packetData,
rcvTime: rcvTime,
})

View file

@ -57,12 +57,12 @@ var _ = Describe("Packet Handler Map", func() {
handledPacket1 := make(chan struct{})
handledPacket2 := make(chan struct{})
packetHandler1.EXPECT().handlePacket(gomock.Any()).Do(func(p *receivedPacket) {
Expect(p.header.DestConnectionID).To(Equal(connID1))
Expect(p.extHdr.DestConnectionID).To(Equal(connID1))
close(handledPacket1)
})
packetHandler1.EXPECT().GetVersion()
packetHandler2.EXPECT().handlePacket(gomock.Any()).Do(func(p *receivedPacket) {
Expect(p.header.DestConnectionID).To(Equal(connID2))
Expect(p.extHdr.DestConnectionID).To(Equal(connID2))
close(handledPacket2)
})
packetHandler2.EXPECT().GetVersion()
@ -166,7 +166,7 @@ var _ = Describe("Packet Handler Map", func() {
packetHandler.EXPECT().GetVersion().Return(protocol.VersionWhatever)
handler.Add(connID, packetHandler)
packetHandler.EXPECT().handlePacket(gomock.Any()).Do(func(p *receivedPacket) {
Expect(p.data).To(HaveLen(456 - int(p.header.PacketNumberLen)))
Expect(p.data).To(HaveLen(456 - int(p.extHdr.PacketNumberLen)))
})
hdr := &wire.ExtendedHeader{
@ -206,7 +206,7 @@ var _ = Describe("Packet Handler Map", func() {
handledPacket := make(chan struct{})
packetHandler.EXPECT().GetVersion()
packetHandler.EXPECT().handlePacket(gomock.Any()).Do(func(p *receivedPacket) {
Expect(p.header.DestConnectionID).To(Equal(connID))
Expect(p.extHdr.DestConnectionID).To(Equal(connID))
close(handledPacket)
})
conn.dataToRead <- getPacket(connID)
@ -249,7 +249,7 @@ var _ = Describe("Packet Handler Map", func() {
p := getPacket(connID)
server := NewMockUnknownPacketHandler(mockCtrl)
server.EXPECT().handlePacket(gomock.Any()).Do(func(p *receivedPacket) {
Expect(p.header.DestConnectionID).To(Equal(connID))
Expect(p.extHdr.DestConnectionID).To(Equal(connID))
})
handler.SetServer(server)
Expect(handler.handlePacket(nil, p)).To(Succeed())

View file

@ -306,7 +306,7 @@ func (s *server) handlePacket(p *receivedPacket) {
}
func (s *server) handlePacketImpl(p *receivedPacket) error {
hdr := p.header
hdr := p.extHdr
// send a Version Negotiation Packet if the client is speaking a different protocol version
if !protocol.IsSupportedVersion(s.config.Versions, hdr.Version) {
@ -335,7 +335,7 @@ func (s *server) handleInitial(p *receivedPacket) {
}
func (s *server) handleInitialImpl(p *receivedPacket) (quicSession, protocol.ConnectionID, error) {
hdr := p.header
hdr := p.extHdr
if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial {
return nil, nil, errors.New("dropping Initial packet with too short connection ID")
}
@ -358,7 +358,7 @@ func (s *server) handleInitialImpl(p *receivedPacket) (quicSession, protocol.Con
if !s.config.AcceptCookie(p.remoteAddr, cookie) {
// Log the Initial packet now.
// If no Retry is sent, the packet will be logged by the session.
p.header.Log(s.logger)
p.extHdr.Log(s.logger)
return nil, nil, s.sendRetry(p.remoteAddr, hdr)
}
@ -453,7 +453,7 @@ func (s *server) sendRetry(remoteAddr net.Addr, hdr *wire.ExtendedHeader) error
}
func (s *server) sendVersionNegotiationPacket(p *receivedPacket) error {
hdr := p.header
hdr := p.extHdr
s.logger.Debugf("Client offered version %s, sending VersionNegotiationPacket", hdr.Version)
data, err := wire.ComposeVersionNegotiation(hdr.SrcConnectionID, hdr.DestConnectionID, s.config.Versions)

View file

@ -32,7 +32,7 @@ func (s *serverSession) handlePacket(p *receivedPacket) {
}
func (s *serverSession) handlePacketImpl(p *receivedPacket) error {
hdr := p.header
hdr := p.extHdr
// Probably an old packet that was sent by the client before the version was negotiated.
// It is safe to drop it.

View file

@ -22,7 +22,7 @@ var _ = Describe("Server Session", func() {
It("handles packets", func() {
p := &receivedPacket{
header: &wire.ExtendedHeader{DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5}},
extHdr: &wire.ExtendedHeader{DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5}},
}
qsess.EXPECT().handlePacket(p)
sess.handlePacket(p)
@ -32,7 +32,7 @@ var _ = Describe("Server Session", func() {
qsess.EXPECT().GetVersion().Return(protocol.VersionNumber(100))
// don't EXPECT any calls to handlePacket()
p := &receivedPacket{
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
IsLongHeader: true,
Version: protocol.VersionNumber(123),
DestConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
@ -45,7 +45,7 @@ var _ = Describe("Server Session", func() {
It("ignores packets with the wrong Long Header type", func() {
qsess.EXPECT().GetVersion().Return(protocol.VersionNumber(100))
p := &receivedPacket{
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
IsLongHeader: true,
Type: protocol.PacketTypeRetry,
Version: protocol.VersionNumber(100),
@ -58,7 +58,7 @@ var _ = Describe("Server Session", func() {
It("passes on Handshake packets", func() {
p := &receivedPacket{
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
IsLongHeader: true,
Type: protocol.PacketTypeHandshake,
Version: protocol.VersionNumber(100),

View file

@ -108,7 +108,7 @@ var _ = Describe("Server", func() {
It("drops Initial packets with a too short connection ID", func() {
serv.handlePacket(&receivedPacket{
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
IsLongHeader: true,
Type: protocol.PacketTypeInitial,
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4},
@ -120,7 +120,7 @@ var _ = Describe("Server", func() {
It("drops too small Initial", func() {
serv.handlePacket(&receivedPacket{
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
IsLongHeader: true,
Type: protocol.PacketTypeInitial,
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
@ -141,7 +141,7 @@ var _ = Describe("Server", func() {
PacketNumberLen: protocol.PacketNumberLen1,
}
serv.handlePacket(&receivedPacket{
header: hdr,
extHdr: hdr,
data: bytes.Repeat([]byte{0}, protocol.MinInitialPacketSize),
})
Consistently(conn.dataWritten.Len).Should(BeZero())
@ -150,7 +150,7 @@ var _ = Describe("Server", func() {
It("drops non-Initial packets", func() {
serv.logger.SetLogLevel(utils.LogLevelDebug)
serv.handlePacket(&receivedPacket{
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
Type: protocol.PacketTypeHandshake,
Version: serv.config.Versions[0],
},
@ -174,7 +174,7 @@ var _ = Describe("Server", func() {
Expect(err).ToNot(HaveOccurred())
serv.handlePacket(&receivedPacket{
remoteAddr: raddr,
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
Type: protocol.PacketTypeInitial,
Token: token,
Version: serv.config.Versions[0],
@ -198,7 +198,7 @@ var _ = Describe("Server", func() {
}
serv.handlePacket(&receivedPacket{
remoteAddr: raddr,
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
Type: protocol.PacketTypeInitial,
Token: []byte("foobar"),
Version: serv.config.Versions[0],
@ -212,7 +212,7 @@ var _ = Describe("Server", func() {
srcConnID := protocol.ConnectionID{1, 2, 3, 4, 5}
destConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6}
serv.handlePacket(&receivedPacket{
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
IsLongHeader: true,
SrcConnectionID: srcConnID,
DestConnectionID: destConnID,
@ -221,8 +221,9 @@ var _ = Describe("Server", func() {
},
})
Expect(conn.dataWritten.Len()).ToNot(BeZero())
hdr := parseHeader(conn.dataWritten.Bytes())
Expect(hdr.IsVersionNegotiation).To(BeTrue())
hdr, err := wire.ParseHeader(bytes.NewReader(conn.dataWritten.Bytes()), 0)
Expect(err).ToNot(HaveOccurred())
Expect(hdr.IsVersionNegotiation()).To(BeTrue())
Expect(hdr.DestConnectionID).To(Equal(srcConnID))
Expect(hdr.SrcConnectionID).To(Equal(destConnID))
Expect(hdr.SupportedVersions).ToNot(ContainElement(protocol.VersionNumber(0x42)))
@ -238,7 +239,7 @@ var _ = Describe("Server", func() {
}
serv.handleInitial(&receivedPacket{
remoteAddr: &net.UDPAddr{},
header: hdr,
extHdr: hdr,
data: bytes.Repeat([]byte{0}, protocol.MinInitialPacketSize),
})
Expect(conn.dataWritten.Len()).ToNot(BeZero())
@ -259,7 +260,7 @@ var _ = Describe("Server", func() {
Version: protocol.VersionTLS,
}
p := &receivedPacket{
header: hdr,
extHdr: hdr,
data: bytes.Repeat([]byte{0}, protocol.MinInitialPacketSize),
}
run := make(chan struct{})

View file

@ -52,7 +52,8 @@ type cryptoStreamHandler interface {
type receivedPacket struct {
remoteAddr net.Addr
header *wire.ExtendedHeader
hdr *wire.Header
extHdr *wire.ExtendedHeader
data []byte
rcvTime time.Time
}
@ -373,7 +374,7 @@ runLoop:
}
// This is a bit unclean, but works properly, since the packet always
// begins with the public header and we never copy it.
putPacketBuffer(&p.header.Raw)
putPacketBuffer(&p.extHdr.Raw)
case <-s.handshakeCompleteChan:
s.handleHandshakeComplete()
}
@ -478,11 +479,11 @@ func (s *session) handleHandshakeComplete() {
}
func (s *session) handlePacketImpl(p *receivedPacket) error {
hdr := p.header
hdr := p.extHdr
// The server can change the source connection ID with the first Handshake packet.
// After this, all packets with a different source connection have to be ignored.
if s.receivedFirstPacket && hdr.IsLongHeader && !hdr.SrcConnectionID.Equal(s.destConnID) {
s.logger.Debugf("Dropping packet with unexpected source connection ID: %s (expected %s)", p.header.SrcConnectionID, s.destConnID)
s.logger.Debugf("Dropping packet with unexpected source connection ID: %s (expected %s)", p.extHdr.SrcConnectionID, s.destConnID)
return nil
}

View file

@ -457,7 +457,7 @@ var _ = Describe("Session", func() {
hdr.PacketNumber = 5
hdr.Raw = []byte("raw header")
unpacker.EXPECT().Unpack([]byte("raw header"), hdr, []byte("foobar")).Return(&unpackedPacket{}, nil)
err := sess.handlePacketImpl(&receivedPacket{header: hdr, data: []byte("foobar")})
err := sess.handlePacketImpl(&receivedPacket{extHdr: hdr, data: []byte("foobar")})
Expect(err).ToNot(HaveOccurred())
Expect(sess.largestRcvdPacketNumber).To(Equal(protocol.PacketNumber(5)))
})
@ -470,7 +470,7 @@ var _ = Describe("Session", func() {
})
sess.receivedPacketHandler = rph
hdr.PacketNumber = 5
Expect(sess.handlePacketImpl(&receivedPacket{header: hdr})).To(Succeed())
Expect(sess.handlePacketImpl(&receivedPacket{extHdr: hdr})).To(Succeed())
})
It("doesn't inform the ReceivedPacketHandler about Retry packets", func() {
@ -481,7 +481,7 @@ var _ = Describe("Session", func() {
// don't EXPECT any call to ReceivedPacket
hdr.PacketNumber = 5
hdr.Type = protocol.PacketTypeRetry
err := sess.handlePacketImpl(&receivedPacket{header: hdr, rcvTime: now})
err := sess.handlePacketImpl(&receivedPacket{extHdr: hdr, rcvTime: now})
Expect(err).ToNot(HaveOccurred())
})
@ -501,15 +501,15 @@ var _ = Describe("Session", func() {
close(done)
}()
sessionRunner.EXPECT().retireConnectionID(gomock.Any())
sess.handlePacket(&receivedPacket{header: hdr})
sess.handlePacket(&receivedPacket{extHdr: hdr})
Eventually(done).Should(BeClosed())
})
It("handles duplicate packets", func() {
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).Return(&unpackedPacket{}, nil).Times(2)
hdr.PacketNumber = 5
Expect(sess.handlePacketImpl(&receivedPacket{header: hdr})).To(Succeed())
Expect(sess.handlePacketImpl(&receivedPacket{header: hdr})).To(Succeed())
Expect(sess.handlePacketImpl(&receivedPacket{extHdr: hdr})).To(Succeed())
Expect(sess.handlePacketImpl(&receivedPacket{extHdr: hdr})).To(Succeed())
})
It("ignores packets with a different source connection ID", func() {
@ -517,7 +517,7 @@ var _ = Describe("Session", func() {
// only EXPECT one call to the unpacker
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).Return(&unpackedPacket{}, nil)
err := sess.handlePacketImpl(&receivedPacket{
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
IsLongHeader: true,
DestConnectionID: sess.destConnID,
SrcConnectionID: sess.srcConnID,
@ -526,7 +526,7 @@ var _ = Describe("Session", func() {
Expect(err).ToNot(HaveOccurred())
// The next packet has to be ignored, since the source connection ID doesn't match.
err = sess.handlePacketImpl(&receivedPacket{
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
IsLongHeader: true,
DestConnectionID: sess.destConnID,
SrcConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
@ -543,7 +543,7 @@ var _ = Describe("Session", func() {
Expect(origAddr).ToNot(Equal(remoteIP))
p := receivedPacket{
remoteAddr: remoteIP,
header: &wire.ExtendedHeader{PacketNumber: 1337},
extHdr: &wire.ExtendedHeader{PacketNumber: 1337},
}
err := sess.handlePacketImpl(&p)
Expect(err).ToNot(HaveOccurred())
@ -1317,7 +1317,7 @@ var _ = Describe("Client Session", func() {
newConnID := protocol.ConnectionID{1, 3, 3, 7, 1, 3, 3, 7}
packer.EXPECT().ChangeDestConnectionID(newConnID)
err := sess.handlePacketImpl(&receivedPacket{
header: &wire.ExtendedHeader{
extHdr: &wire.ExtendedHeader{
IsLongHeader: true,
Type: protocol.PacketTypeHandshake,
SrcConnectionID: newConnID,