Skip to content

Commit 192bc8d

Browse files
account for the size of the header when packing 1-RTT probe packets
1 parent ad8367c commit 192bc8d

File tree

2 files changed

+62
-19
lines changed

2 files changed

+62
-19
lines changed

packet_packer.go

+18-19
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
467467
}, nil
468468
}
469469

470-
func (p *packetPacker) maybeGetCryptoPacket(maxSize, currentSize protocol.ByteCount, encLevel protocol.EncryptionLevel) (*wire.ExtendedHeader, *payload) {
470+
func (p *packetPacker) maybeGetCryptoPacket(maxPacketSize, currentSize protocol.ByteCount, encLevel protocol.EncryptionLevel) (*wire.ExtendedHeader, *payload) {
471471
var s cryptoStream
472472
var hasRetransmission bool
473473
//nolint:exhaustive // Initial and Handshake are the only two encryption levels here.
@@ -494,30 +494,30 @@ func (p *packetPacker) maybeGetCryptoPacket(maxSize, currentSize protocol.ByteCo
494494
if ack != nil {
495495
payload.ack = ack
496496
payload.length = ack.Length(p.version)
497-
maxSize -= payload.length
497+
maxPacketSize -= payload.length
498498
}
499499
hdr := p.getLongHeader(encLevel)
500-
maxSize -= hdr.GetLength(p.version)
500+
maxPacketSize -= hdr.GetLength(p.version)
501501
if hasRetransmission {
502502
for {
503503
var f wire.Frame
504504
//nolint:exhaustive // 0-RTT packets can't contain any retransmission.s
505505
switch encLevel {
506506
case protocol.EncryptionInitial:
507-
f = p.retransmissionQueue.GetInitialFrame(maxSize)
507+
f = p.retransmissionQueue.GetInitialFrame(maxPacketSize)
508508
case protocol.EncryptionHandshake:
509-
f = p.retransmissionQueue.GetHandshakeFrame(maxSize)
509+
f = p.retransmissionQueue.GetHandshakeFrame(maxPacketSize)
510510
}
511511
if f == nil {
512512
break
513513
}
514514
payload.frames = append(payload.frames, ackhandler.Frame{Frame: f})
515515
frameLen := f.Length(p.version)
516516
payload.length += frameLen
517-
maxSize -= frameLen
517+
maxPacketSize -= frameLen
518518
}
519519
} else if s.HasData() {
520-
cf := s.PopCryptoFrame(maxSize)
520+
cf := s.PopCryptoFrame(maxPacketSize)
521521
payload.frames = []ackhandler.Frame{{Frame: cf}}
522522
payload.length += cf.Length(p.version)
523523
}
@@ -547,18 +547,19 @@ func (p *packetPacker) maybeGetAppDataPacket(maxPacketSize, currentSize protocol
547547
}
548548

549549
maxPayloadSize := maxPacketSize - hdr.GetLength(p.version) - protocol.ByteCount(sealer.Overhead())
550-
payload := p.maybeGetAppDataPacketWithEncLevel(maxPayloadSize, currentSize, encLevel)
550+
payload := p.maybeGetAppDataPacketWithEncLevel(maxPayloadSize, encLevel == protocol.Encryption1RTT && currentSize == 0)
551551
return sealer, hdr, payload
552552
}
553553

554-
func (p *packetPacker) maybeGetAppDataPacketWithEncLevel(maxPayloadSize, currentSize protocol.ByteCount, encLevel protocol.EncryptionLevel) *payload {
555-
payload := p.composeNextPacket(maxPayloadSize, encLevel == protocol.Encryption1RTT && currentSize == 0)
554+
func (p *packetPacker) maybeGetAppDataPacketWithEncLevel(maxPayloadSize protocol.ByteCount, ackAllowed bool) *payload {
555+
payload := p.composeNextPacket(maxPayloadSize, ackAllowed)
556556

557557
// check if we have anything to send
558-
if len(payload.frames) == 0 && payload.ack == nil {
559-
return nil
560-
}
561-
if len(payload.frames) == 0 { // the packet only contains an ACK
558+
if len(payload.frames) == 0 {
559+
if payload.ack == nil {
560+
return nil
561+
}
562+
// the packet only contains an ACK
562563
if p.numNonAckElicitingAcks >= protocol.MaxNonAckElicitingAcks {
563564
ping := &wire.PingFrame{}
564565
payload.frames = append(payload.frames, ackhandler.Frame{Frame: ping})
@@ -642,14 +643,12 @@ func (p *packetPacker) MaybePackProbePacket(encLevel protocol.EncryptionLevel) (
642643
return nil, err
643644
}
644645
sealer = oneRTTSealer
645-
payload = p.maybeGetAppDataPacketWithEncLevel(p.maxPacketSize-protocol.ByteCount(sealer.Overhead()), 0, protocol.Encryption1RTT)
646-
if payload != nil {
647-
hdr = p.getShortHeader(oneRTTSealer.KeyPhase())
648-
}
646+
hdr = p.getShortHeader(oneRTTSealer.KeyPhase())
647+
payload = p.maybeGetAppDataPacketWithEncLevel(p.maxPacketSize-protocol.ByteCount(sealer.Overhead())-hdr.GetLength(p.version), true)
649648
default:
650649
panic("unknown encryption level")
651650
}
652-
if hdr == nil {
651+
if payload == nil {
653652
return nil, nil
654653
}
655654
size := p.packetLength(hdr, payload) + protocol.ByteCount(sealer.Overhead())

packet_packer_test.go

+44
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,25 @@ var _ = Describe("Packet packer", func() {
13221322
parsePacket(packet.buffer.Data)
13231323
})
13241324

1325+
It("packs a full size Handshake probe packet", func() {
1326+
f := &wire.CryptoFrame{Data: make([]byte, 2000)}
1327+
retransmissionQueue.AddHandshake(f)
1328+
sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil)
1329+
ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake, false)
1330+
handshakeStream.EXPECT().HasData()
1331+
pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
1332+
pnManager.EXPECT().PopPacketNumber(protocol.EncryptionHandshake).Return(protocol.PacketNumber(0x42))
1333+
1334+
packet, err := packer.MaybePackProbePacket(protocol.EncryptionHandshake)
1335+
Expect(err).ToNot(HaveOccurred())
1336+
Expect(packet).ToNot(BeNil())
1337+
Expect(packet.EncryptionLevel()).To(Equal(protocol.EncryptionHandshake))
1338+
Expect(packet.frames).To(HaveLen(1))
1339+
Expect(packet.frames[0].Frame).To(BeAssignableToTypeOf(&wire.CryptoFrame{}))
1340+
Expect(packet.length).To(Equal(maxPacketSize))
1341+
parsePacket(packet.buffer.Data)
1342+
})
1343+
13251344
It("packs a 1-RTT probe packet", func() {
13261345
f := &wire.StreamFrame{Data: []byte("1-RTT")}
13271346
retransmissionQueue.AddInitial(f)
@@ -1341,8 +1360,33 @@ var _ = Describe("Packet packer", func() {
13411360
Expect(packet.frames[0].Frame).To(Equal(f))
13421361
})
13431362

1363+
It("packs a full size 1-RTT probe packet", func() {
1364+
f := &wire.StreamFrame{Data: make([]byte, 2000)}
1365+
retransmissionQueue.AddInitial(f)
1366+
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
1367+
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT, false)
1368+
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
1369+
pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
1370+
framer.EXPECT().HasData().Return(true)
1371+
expectAppendControlFrames()
1372+
framer.EXPECT().AppendStreamFrames(gomock.Any(), gomock.Any()).DoAndReturn(func(fs []ackhandler.Frame, maxSize protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount) {
1373+
sf, split := f.MaybeSplitOffFrame(maxSize, packer.version)
1374+
Expect(split).To(BeTrue())
1375+
return append(fs, ackhandler.Frame{Frame: sf}), sf.Length(packer.version)
1376+
})
1377+
1378+
packet, err := packer.MaybePackProbePacket(protocol.Encryption1RTT)
1379+
Expect(err).ToNot(HaveOccurred())
1380+
Expect(packet).ToNot(BeNil())
1381+
Expect(packet.EncryptionLevel()).To(Equal(protocol.Encryption1RTT))
1382+
Expect(packet.frames).To(HaveLen(1))
1383+
Expect(packet.frames[0].Frame).To(BeAssignableToTypeOf(&wire.StreamFrame{}))
1384+
Expect(packet.length).To(Equal(maxPacketSize))
1385+
})
1386+
13441387
It("returns nil if there's no probe data to send", func() {
13451388
sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil)
1389+
pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
13461390
ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT, true)
13471391
framer.EXPECT().HasData()
13481392

0 commit comments

Comments
 (0)