From 78fab5c264df229da9941534e5cf0d2c151ab90f Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 11 Aug 2016 15:02:19 +0700 Subject: [PATCH] use PacketNumberGenerator in PacketPacker --- packet_packer.go | 25 +++++++++++++++++++------ packet_packer_test.go | 12 ++++++++++++ protocol/server_parameters.go | 3 +++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/packet_packer.go b/packet_packer.go index cba74a2b..d19394d4 100644 --- a/packet_packer.go +++ b/packet_packer.go @@ -19,10 +19,12 @@ type packedPacket struct { } type packetPacker struct { - connectionID protocol.ConnectionID - version protocol.VersionNumber - cryptoSetup *handshake.CryptoSetup - lastPacketNumber protocol.PacketNumber + connectionID protocol.ConnectionID + version protocol.VersionNumber + cryptoSetup *handshake.CryptoSetup + + lastPacketNumber protocol.PacketNumber // TODO: remove when dropping support for QUIC 33 + packetNumberGenerator *packetNumberGenerator connectionParametersManager *handshake.ConnectionParametersManager @@ -31,13 +33,19 @@ type packetPacker struct { } func newPacketPacker(connectionID protocol.ConnectionID, cryptoSetup *handshake.CryptoSetup, connectionParametersHandler *handshake.ConnectionParametersManager, streamFramer *streamFramer, version protocol.VersionNumber) *packetPacker { - return &packetPacker{ + p := &packetPacker{ cryptoSetup: cryptoSetup, connectionID: connectionID, connectionParametersManager: connectionParametersHandler, version: version, streamFramer: streamFramer, } + + if version >= protocol.Version34 { + p.packetNumberGenerator = newPacketNumberGenerator(protocol.SkipPacketAveragePeriodLength) + } + + return p } func (p *packetPacker) PackConnectionClose(frame *frames.ConnectionCloseFrame, leastUnacked protocol.PacketNumber) (*packedPacket, error) { @@ -53,7 +61,12 @@ func (p *packetPacker) packPacket(stopWaitingFrame *frames.StopWaitingFrame, con p.controlFrames = append(p.controlFrames, controlFrames...) } - currentPacketNumber := p.lastPacketNumber + 1 + var currentPacketNumber protocol.PacketNumber + if p.version <= protocol.Version33 { + currentPacketNumber = p.lastPacketNumber + 1 + } else { + currentPacketNumber = p.packetNumberGenerator.GetNextPacketNumber() + } // cryptoSetup needs to be locked here, so that the AEADs are not changed between // calling DiversificationNonce() and Seal(). diff --git a/packet_packer_test.go b/packet_packer_test.go index 7a799f93..9d3b32f4 100644 --- a/packet_packer_test.go +++ b/packet_packer_test.go @@ -28,6 +28,7 @@ var _ = Describe("Packet packer", func() { packer = &packetPacker{ cryptoSetup: &handshake.CryptoSetup{}, connectionParametersManager: handshake.NewConnectionParamatersManager(), + packetNumberGenerator: newPacketNumberGenerator(protocol.SkipPacketAveragePeriodLength), streamFramer: streamFramer, } publicHeaderLen = 1 + 8 + 1 // 1 flag byte, 8 connection ID, 1 packet number @@ -112,6 +113,16 @@ var _ = Describe("Packet packer", func() { Expect(p.raw).NotTo(BeEmpty()) }) + It("increases the packet number", func() { + p1, err := packer.PackPacket(nil, []frames.Frame{&frames.ConnectionCloseFrame{}}, 0, true) + Expect(err).ToNot(HaveOccurred()) + Expect(p1).ToNot(BeNil()) + p2, err := packer.PackPacket(nil, []frames.Frame{&frames.ConnectionCloseFrame{}}, 0, true) + Expect(err).ToNot(HaveOccurred()) + Expect(p2).ToNot(BeNil()) + Expect(p2.number).To(BeNumerically(">", p1.number)) + }) + It("packs a StopWaitingFrame first", func() { swf := &frames.StopWaitingFrame{LeastUnacked: 10} p, err := packer.PackPacket(swf, []frames.Frame{&frames.ConnectionCloseFrame{}}, 0, true) @@ -122,6 +133,7 @@ var _ = Describe("Packet packer", func() { }) It("sets the LeastUnackedDelta length of a StopWaitingFrame", func() { + packer.version = protocol.Version33 // TODO: find a different way to test this when dropping support for QUIC 33 packetNumber := protocol.PacketNumber(0xDECAFB) // will result in a 4 byte packet number packer.lastPacketNumber = packetNumber - 1 swf := &frames.StopWaitingFrame{LeastUnacked: packetNumber - 0x100} diff --git a/protocol/server_parameters.go b/protocol/server_parameters.go index 959e1ce3..bcb85b08 100644 --- a/protocol/server_parameters.go +++ b/protocol/server_parameters.go @@ -44,6 +44,9 @@ const MaxSessionUnprocessedPackets = 128 // RetransmissionThreshold + 1 is the number of times a packet has to be NACKed so that it gets retransmitted const RetransmissionThreshold uint8 = 3 +// SkipPacketAveragePeriodLength is the average period length in which one packet number is skipped to prevent an Optimistic ACK attack +const SkipPacketAveragePeriodLength PacketNumber = 500 + // STKExpiryTimeSec is the valid time of a source address token in seconds const STKExpiryTimeSec = 24 * 60 * 60