append STREAM frames to the slice of frames when packing a packet

This commit is contained in:
Marten Seemann 2018-09-21 18:01:04 -04:00
parent 2a23a82da6
commit 641ab6390f
5 changed files with 138 additions and 111 deletions

View file

@ -35,6 +35,18 @@ func (m *MockStreamFrameSource) EXPECT() *MockStreamFrameSourceMockRecorder {
return m.recorder return m.recorder
} }
// AppendStreamFrames mocks base method
func (m *MockStreamFrameSource) AppendStreamFrames(arg0 []wire.Frame, arg1 protocol.ByteCount) []wire.Frame {
ret := m.ctrl.Call(m, "AppendStreamFrames", arg0, arg1)
ret0, _ := ret[0].([]wire.Frame)
return ret0
}
// AppendStreamFrames indicates an expected call of AppendStreamFrames
func (mr *MockStreamFrameSourceMockRecorder) AppendStreamFrames(arg0, arg1 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendStreamFrames", reflect.TypeOf((*MockStreamFrameSource)(nil).AppendStreamFrames), arg0, arg1)
}
// HasCryptoStreamData mocks base method // HasCryptoStreamData mocks base method
func (m *MockStreamFrameSource) HasCryptoStreamData() bool { func (m *MockStreamFrameSource) HasCryptoStreamData() bool {
ret := m.ctrl.Call(m, "HasCryptoStreamData") ret := m.ctrl.Call(m, "HasCryptoStreamData")
@ -58,15 +70,3 @@ func (m *MockStreamFrameSource) PopCryptoStreamFrame(arg0 protocol.ByteCount) *w
func (mr *MockStreamFrameSourceMockRecorder) PopCryptoStreamFrame(arg0 interface{}) *gomock.Call { func (mr *MockStreamFrameSourceMockRecorder) PopCryptoStreamFrame(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PopCryptoStreamFrame", reflect.TypeOf((*MockStreamFrameSource)(nil).PopCryptoStreamFrame), arg0) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PopCryptoStreamFrame", reflect.TypeOf((*MockStreamFrameSource)(nil).PopCryptoStreamFrame), arg0)
} }
// PopStreamFrames mocks base method
func (m *MockStreamFrameSource) PopStreamFrames(arg0 protocol.ByteCount) []*wire.StreamFrame {
ret := m.ctrl.Call(m, "PopStreamFrames", arg0)
ret0, _ := ret[0].([]*wire.StreamFrame)
return ret0
}
// PopStreamFrames indicates an expected call of PopStreamFrames
func (mr *MockStreamFrameSourceMockRecorder) PopStreamFrames(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PopStreamFrames", reflect.TypeOf((*MockStreamFrameSource)(nil).PopStreamFrames), arg0)
}

View file

@ -42,7 +42,7 @@ type sealingManager interface {
type streamFrameSource interface { type streamFrameSource interface {
HasCryptoStreamData() bool HasCryptoStreamData() bool
PopCryptoStreamFrame(protocol.ByteCount) *wire.StreamFrame PopCryptoStreamFrame(protocol.ByteCount) *wire.StreamFrame
PopStreamFrames(protocol.ByteCount) []*wire.StreamFrame AppendStreamFrames([]wire.Frame, protocol.ByteCount) []wire.Frame
} }
type packetPacker struct { type packetPacker struct {
@ -173,7 +173,7 @@ func (p *packetPacker) PackRetransmission(packet *ackhandler.Packet) ([]*packedP
encLevel, sealer := p.cryptoSetup.GetSealer() encLevel, sealer := p.cryptoSetup.GetSealer()
for len(controlFrames) > 0 || len(streamFrames) > 0 { for len(controlFrames) > 0 || len(streamFrames) > 0 {
var frames []wire.Frame var frames []wire.Frame
var payloadLength protocol.ByteCount var length protocol.ByteCount
header := p.getHeader(encLevel) header := p.getHeader(encLevel)
headerLength, err := header.GetLength(p.version) headerLength, err := header.GetLength(p.version)
@ -193,17 +193,17 @@ func (p *packetPacker) PackRetransmission(packet *ackhandler.Packet) ([]*packedP
PacketNumber: header.PacketNumber, PacketNumber: header.PacketNumber,
PacketNumberLen: header.PacketNumberLen, PacketNumberLen: header.PacketNumberLen,
} }
payloadLength += swf.Length(p.version) length += swf.Length(p.version)
frames = append(frames, swf) frames = append(frames, swf)
} }
for len(controlFrames) > 0 { for len(controlFrames) > 0 {
frame := controlFrames[0] frame := controlFrames[0]
length := frame.Length(p.version) frameLen := frame.Length(p.version)
if payloadLength+length > maxSize { if length+frameLen > maxSize {
break break
} }
payloadLength += length length += frameLen
frames = append(frames, frame) frames = append(frames, frame)
controlFrames = controlFrames[1:] controlFrames = controlFrames[1:]
} }
@ -218,12 +218,12 @@ func (p *packetPacker) PackRetransmission(packet *ackhandler.Packet) ([]*packedP
} else { } else {
maxSize += 2 maxSize += 2
} }
for len(streamFrames) > 0 && payloadLength+protocol.MinStreamFrameSize < maxSize { for len(streamFrames) > 0 && length+protocol.MinStreamFrameSize < maxSize {
// TODO: optimize by setting DataLenPresent = false on all but the last STREAM frame // TODO: optimize by setting DataLenPresent = false on all but the last STREAM frame
frame := streamFrames[0] frame := streamFrames[0]
frameToAdd := frame frameToAdd := frame
sf, err := frame.MaybeSplitOffFrame(maxSize-payloadLength, p.version) sf, err := frame.MaybeSplitOffFrame(maxSize-length, p.version)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -232,7 +232,7 @@ func (p *packetPacker) PackRetransmission(packet *ackhandler.Packet) ([]*packedP
} else { } else {
streamFrames = streamFrames[1:] streamFrames = streamFrames[1:]
} }
payloadLength += frameToAdd.Length(p.version) length += frameToAdd.Length(p.version)
frames = append(frames, frameToAdd) frames = append(frames, frameToAdd)
} }
if sf, ok := frames[len(frames)-1].(*wire.StreamFrame); ok { if sf, ok := frames[len(frames)-1].(*wire.StreamFrame); ok {
@ -312,24 +312,24 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
} }
maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLength maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLength
payloadFrames, err := p.composeNextPacket(maxSize, p.canSendData(encLevel)) frames, err := p.composeNextPacket(maxSize, p.canSendData(encLevel))
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Check if we have enough frames to send // Check if we have enough frames to send
if len(payloadFrames) == 0 { if len(frames) == 0 {
return nil, nil return nil, nil
} }
// Don't send out packets that only contain a StopWaitingFrame // Don't send out packets that only contain a StopWaitingFrame
if len(payloadFrames) == 1 && p.stopWaiting != nil { if len(frames) == 1 && p.stopWaiting != nil {
return nil, nil return nil, nil
} }
if p.ackFrame != nil { if p.ackFrame != nil {
// check if this packet only contains an ACK (and maybe a STOP_WAITING) // check if this packet only contains an ACK (and maybe a STOP_WAITING)
if len(payloadFrames) == 1 || (p.stopWaiting != nil && len(payloadFrames) == 2) { if len(frames) == 1 || (p.stopWaiting != nil && len(frames) == 2) {
if p.numNonRetransmittableAcks >= protocol.MaxNonRetransmittableAcks { if p.numNonRetransmittableAcks >= protocol.MaxNonRetransmittableAcks {
payloadFrames = append(payloadFrames, &wire.PingFrame{}) frames = append(frames, &wire.PingFrame{})
p.numNonRetransmittableAcks = 0 p.numNonRetransmittableAcks = 0
} else { } else {
p.numNonRetransmittableAcks++ p.numNonRetransmittableAcks++
@ -341,14 +341,14 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
p.stopWaiting = nil p.stopWaiting = nil
p.ackFrame = nil p.ackFrame = nil
raw, err := p.writeAndSealPacket(header, payloadFrames, sealer) raw, err := p.writeAndSealPacket(header, frames, sealer)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &packedPacket{ return &packedPacket{
header: header, header: header,
raw: raw, raw: raw,
frames: payloadFrames, frames: frames,
encryptionLevel: encLevel, encryptionLevel: encLevel,
}, nil }, nil
} }
@ -380,39 +380,38 @@ func (p *packetPacker) composeNextPacket(
maxFrameSize protocol.ByteCount, maxFrameSize protocol.ByteCount,
canSendStreamFrames bool, canSendStreamFrames bool,
) ([]wire.Frame, error) { ) ([]wire.Frame, error) {
var payloadLength protocol.ByteCount var length protocol.ByteCount
var payloadFrames []wire.Frame var frames []wire.Frame
// STOP_WAITING and ACK will always fit // STOP_WAITING and ACK will always fit
if p.ackFrame != nil { // ACKs need to go first, so that the sentPacketHandler will recognize them if p.ackFrame != nil { // ACKs need to go first, so that the sentPacketHandler will recognize them
payloadFrames = append(payloadFrames, p.ackFrame) frames = append(frames, p.ackFrame)
l := p.ackFrame.Length(p.version) length += p.ackFrame.Length(p.version)
payloadLength += l
} }
if p.stopWaiting != nil { // a STOP_WAITING will only be queued when using gQUIC if p.stopWaiting != nil { // a STOP_WAITING will only be queued when using gQUIC
payloadFrames = append(payloadFrames, p.stopWaiting) frames = append(frames, p.stopWaiting)
payloadLength += p.stopWaiting.Length(p.version) length += p.stopWaiting.Length(p.version)
} }
p.controlFrameMutex.Lock() p.controlFrameMutex.Lock()
for len(p.controlFrames) > 0 { for len(p.controlFrames) > 0 {
frame := p.controlFrames[len(p.controlFrames)-1] frame := p.controlFrames[len(p.controlFrames)-1]
length := frame.Length(p.version) frameLen := frame.Length(p.version)
if payloadLength+length > maxFrameSize { if length+frameLen > maxFrameSize {
break break
} }
payloadFrames = append(payloadFrames, frame) frames = append(frames, frame)
payloadLength += length length += frameLen
p.controlFrames = p.controlFrames[:len(p.controlFrames)-1] p.controlFrames = p.controlFrames[:len(p.controlFrames)-1]
} }
p.controlFrameMutex.Unlock() p.controlFrameMutex.Unlock()
if payloadLength > maxFrameSize { if length > maxFrameSize {
return nil, fmt.Errorf("Packet Packer BUG: packet payload (%d) too large (%d)", payloadLength, maxFrameSize) return nil, fmt.Errorf("Packet Packer BUG: packet payload (%d) too large (%d)", length, maxFrameSize)
} }
if !canSendStreamFrames { if !canSendStreamFrames {
return payloadFrames, nil return frames, nil
} }
// temporarily increase the maxFrameSize by the (minimum) length of the DataLen field // temporarily increase the maxFrameSize by the (minimum) length of the DataLen field
@ -426,15 +425,14 @@ func (p *packetPacker) composeNextPacket(
maxFrameSize += 2 maxFrameSize += 2
} }
fs := p.streams.PopStreamFrames(maxFrameSize - payloadLength) frames = p.streams.AppendStreamFrames(frames, maxFrameSize-length)
if len(fs) != 0 { if len(frames) > 0 {
fs[len(fs)-1].DataLenPresent = false lastFrame := frames[len(frames)-1]
if sf, ok := lastFrame.(*wire.StreamFrame); ok {
sf.DataLenPresent = false
}
} }
return frames, nil
for _, f := range fs {
payloadFrames = append(payloadFrames, f)
}
return payloadFrames, nil
} }
func (p *packetPacker) QueueControlFrame(frame wire.Frame) { func (p *packetPacker) QueueControlFrame(frame wire.Frame) {
@ -494,7 +492,7 @@ func (p *packetPacker) getHeader(encLevel protocol.EncryptionLevel) *wire.Header
func (p *packetPacker) writeAndSealPacket( func (p *packetPacker) writeAndSealPacket(
header *wire.Header, header *wire.Header,
payloadFrames []wire.Frame, frames []wire.Frame,
sealer handshake.Sealer, sealer handshake.Sealer,
) ([]byte, error) { ) ([]byte, error) {
raw := *getPacketBuffer() raw := *getPacketBuffer()
@ -507,7 +505,7 @@ func (p *packetPacker) writeAndSealPacket(
header.PayloadLen = protocol.ByteCount(protocol.MinInitialPacketSize) - headerLen header.PayloadLen = protocol.ByteCount(protocol.MinInitialPacketSize) - headerLen
} else { } else {
payloadLen := protocol.ByteCount(sealer.Overhead()) payloadLen := protocol.ByteCount(sealer.Overhead())
for _, frame := range payloadFrames { for _, frame := range frames {
payloadLen += frame.Length(p.version) payloadLen += frame.Length(p.version)
} }
header.PayloadLen = payloadLen header.PayloadLen = payloadLen
@ -521,12 +519,12 @@ func (p *packetPacker) writeAndSealPacket(
// the Initial packet needs to be padded, so the last STREAM frame must have the data length present // the Initial packet needs to be padded, so the last STREAM frame must have the data length present
if header.Type == protocol.PacketTypeInitial { if header.Type == protocol.PacketTypeInitial {
lastFrame := payloadFrames[len(payloadFrames)-1] lastFrame := frames[len(frames)-1]
if sf, ok := lastFrame.(*wire.StreamFrame); ok { if sf, ok := lastFrame.(*wire.StreamFrame); ok {
sf.DataLenPresent = true sf.DataLenPresent = true
} }
} }
for _, frame := range payloadFrames { for _, frame := range frames {
if err := frame.Write(buffer, p.version); err != nil { if err := frame.Write(buffer, p.version); err != nil {
return nil, err return nil, err
} }

View file

@ -73,6 +73,12 @@ var _ = Describe("Packet packer", func() {
ExpectWithOffset(0, hdr.PayloadLen).To(BeEquivalentTo(r.Len())) ExpectWithOffset(0, hdr.PayloadLen).To(BeEquivalentTo(r.Len()))
} }
expectAppendStreamFrames := func(frames ...wire.Frame) {
mockStreamFramer.EXPECT().AppendStreamFrames(gomock.Any(), gomock.Any()).DoAndReturn(func(fs []wire.Frame, _ protocol.ByteCount) []wire.Frame {
return append(frames, fs...)
})
}
BeforeEach(func() { BeforeEach(func() {
version := versionGQUICFrames version := versionGQUICFrames
mockSender := NewMockStreamSender(mockCtrl) mockSender := NewMockStreamSender(mockCtrl)
@ -126,7 +132,7 @@ var _ = Describe("Packet packer", func() {
It("returns nil when no packet is queued", func() { It("returns nil when no packet is queued", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData() mockStreamFramer.EXPECT().HasCryptoStreamData()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) mockStreamFramer.EXPECT().AppendStreamFrames(nil, gomock.Any())
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(p).To(BeNil()) Expect(p).To(BeNil())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
@ -138,7 +144,7 @@ var _ = Describe("Packet packer", func() {
StreamID: 5, StreamID: 5,
Data: []byte{0xDE, 0xCA, 0xFB, 0xAD}, Data: []byte{0xDE, 0xCA, 0xFB, 0xAD},
} }
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).Return([]*wire.StreamFrame{f}) expectAppendStreamFrames(f)
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p).ToNot(BeNil()) Expect(p).ToNot(BeNil())
@ -150,10 +156,10 @@ var _ = Describe("Packet packer", func() {
It("stores the encryption level a packet was sealed with", func() { It("stores the encryption level a packet was sealed with", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData() mockStreamFramer.EXPECT().HasCryptoStreamData()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).Return([]*wire.StreamFrame{{ expectAppendStreamFrames(&wire.StreamFrame{
StreamID: 5, StreamID: 5,
Data: []byte("foobar"), Data: []byte("foobar"),
}}) })
packer.cryptoSetup.(*mockCryptoSetup).encLevelSeal = protocol.EncryptionForwardSecure packer.cryptoSetup.(*mockCryptoSetup).encLevelSeal = protocol.EncryptionForwardSecure
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
@ -356,7 +362,7 @@ var _ = Describe("Packet packer", func() {
It("packs only control frames", func() { It("packs only control frames", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData() mockStreamFramer.EXPECT().HasCryptoStreamData()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) expectAppendStreamFrames()
packer.QueueControlFrame(&wire.RstStreamFrame{}) packer.QueueControlFrame(&wire.RstStreamFrame{})
packer.QueueControlFrame(&wire.MaxDataFrame{}) packer.QueueControlFrame(&wire.MaxDataFrame{})
p, err := packer.PackPacket() p, err := packer.PackPacket()
@ -368,7 +374,8 @@ var _ = Describe("Packet packer", func() {
It("increases the packet number", func() { It("increases the packet number", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2) mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2)
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).Times(2) expectAppendStreamFrames()
expectAppendStreamFrames()
packer.QueueControlFrame(&wire.RstStreamFrame{}) packer.QueueControlFrame(&wire.RstStreamFrame{})
p1, err := packer.PackPacket() p1, err := packer.PackPacket()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
@ -382,7 +389,7 @@ var _ = Describe("Packet packer", func() {
It("packs a STOP_WAITING frame first", func() { It("packs a STOP_WAITING frame first", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData() mockStreamFramer.EXPECT().HasCryptoStreamData()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) expectAppendStreamFrames()
packer.packetNumberGenerator.next = 15 packer.packetNumberGenerator.next = 15
swf := &wire.StopWaitingFrame{LeastUnacked: 10} swf := &wire.StopWaitingFrame{LeastUnacked: 10}
packer.QueueControlFrame(&wire.RstStreamFrame{}) packer.QueueControlFrame(&wire.RstStreamFrame{})
@ -396,7 +403,7 @@ var _ = Describe("Packet packer", func() {
It("sets the LeastUnackedDelta length of a STOP_WAITING frame", func() { It("sets the LeastUnackedDelta length of a STOP_WAITING frame", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData() mockStreamFramer.EXPECT().HasCryptoStreamData()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) expectAppendStreamFrames()
packer.packetNumberGenerator.next = 0x1337 packer.packetNumberGenerator.next = 0x1337
swf := &wire.StopWaitingFrame{LeastUnacked: 0x1337 - 0x100} swf := &wire.StopWaitingFrame{LeastUnacked: 0x1337 - 0x100}
packer.QueueControlFrame(&wire.RstStreamFrame{}) packer.QueueControlFrame(&wire.RstStreamFrame{})
@ -408,7 +415,7 @@ var _ = Describe("Packet packer", func() {
It("does not pack a packet containing only a STOP_WAITING frame", func() { It("does not pack a packet containing only a STOP_WAITING frame", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData() mockStreamFramer.EXPECT().HasCryptoStreamData()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) expectAppendStreamFrames()
swf := &wire.StopWaitingFrame{LeastUnacked: 10} swf := &wire.StopWaitingFrame{LeastUnacked: 10}
packer.QueueControlFrame(swf) packer.QueueControlFrame(swf)
p, err := packer.PackPacket() p, err := packer.PackPacket()
@ -418,7 +425,7 @@ var _ = Describe("Packet packer", func() {
It("packs a packet if it has queued control frames, but no new control frames", func() { It("packs a packet if it has queued control frames, but no new control frames", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData() mockStreamFramer.EXPECT().HasCryptoStreamData()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) expectAppendStreamFrames()
packer.controlFrames = []wire.Frame{&wire.BlockedFrame{}} packer.controlFrames = []wire.Frame{&wire.BlockedFrame{}}
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
@ -471,16 +478,16 @@ var _ = Describe("Packet packer", func() {
It("only increases the packet number when there is an actual packet to send", func() { It("only increases the packet number when there is an actual packet to send", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2) mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2)
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) expectAppendStreamFrames()
packer.packetNumberGenerator.nextToSkip = 1000 packer.packetNumberGenerator.nextToSkip = 1000
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(p).To(BeNil()) Expect(p).To(BeNil())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(packer.packetNumberGenerator.Peek()).To(Equal(protocol.PacketNumber(1))) Expect(packer.packetNumberGenerator.Peek()).To(Equal(protocol.PacketNumber(1)))
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).Return([]*wire.StreamFrame{{ expectAppendStreamFrames(&wire.StreamFrame{
StreamID: 5, StreamID: 5,
Data: []byte{0xDE, 0xCA, 0xFB, 0xAD}, Data: []byte{0xDE, 0xCA, 0xFB, 0xAD},
}}) })
p, err = packer.PackPacket() p, err = packer.PackPacket()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p).ToNot(BeNil()) Expect(p).ToNot(BeNil())
@ -491,9 +498,9 @@ var _ = Describe("Packet packer", func() {
Context("making ACK packets retransmittable", func() { Context("making ACK packets retransmittable", func() {
sendMaxNumNonRetransmittableAcks := func() { sendMaxNumNonRetransmittableAcks := func() {
mockStreamFramer.EXPECT().HasCryptoStreamData().Times(protocol.MaxNonRetransmittableAcks) mockStreamFramer.EXPECT().HasCryptoStreamData().Times(protocol.MaxNonRetransmittableAcks)
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).Times(protocol.MaxNonRetransmittableAcks)
for i := 0; i < protocol.MaxNonRetransmittableAcks; i++ { for i := 0; i < protocol.MaxNonRetransmittableAcks; i++ {
packer.QueueControlFrame(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}}) packer.QueueControlFrame(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}})
expectAppendStreamFrames()
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(p).ToNot(BeNil()) Expect(p).ToNot(BeNil())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
@ -504,7 +511,7 @@ var _ = Describe("Packet packer", func() {
It("adds a PING frame when it's supposed to send a retransmittable packet", func() { It("adds a PING frame when it's supposed to send a retransmittable packet", func() {
sendMaxNumNonRetransmittableAcks() sendMaxNumNonRetransmittableAcks()
mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2) mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2)
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).Times(2) expectAppendStreamFrames()
packer.QueueControlFrame(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}}) packer.QueueControlFrame(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}})
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(p).ToNot(BeNil()) Expect(p).ToNot(BeNil())
@ -512,6 +519,7 @@ var _ = Describe("Packet packer", func() {
Expect(p.frames).To(ContainElement(&wire.PingFrame{})) Expect(p.frames).To(ContainElement(&wire.PingFrame{}))
// make sure the next packet doesn't contain another PING // make sure the next packet doesn't contain another PING
packer.QueueControlFrame(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 2}}}) packer.QueueControlFrame(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 2}}})
expectAppendStreamFrames()
p, err = packer.PackPacket() p, err = packer.PackPacket()
Expect(p).ToNot(BeNil()) Expect(p).ToNot(BeNil())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
@ -521,10 +529,11 @@ var _ = Describe("Packet packer", func() {
It("waits until there's something to send before adding a PING frame", func() { It("waits until there's something to send before adding a PING frame", func() {
sendMaxNumNonRetransmittableAcks() sendMaxNumNonRetransmittableAcks()
mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2) mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2)
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).Times(2) expectAppendStreamFrames()
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p).To(BeNil()) Expect(p).To(BeNil())
expectAppendStreamFrames()
packer.QueueControlFrame(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}}) packer.QueueControlFrame(&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}})
p, err = packer.PackPacket() p, err = packer.PackPacket()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
@ -535,7 +544,7 @@ var _ = Describe("Packet packer", func() {
It("doesn't send a PING if it already sent another retransmittable frame", func() { It("doesn't send a PING if it already sent another retransmittable frame", func() {
sendMaxNumNonRetransmittableAcks() sendMaxNumNonRetransmittableAcks()
mockStreamFramer.EXPECT().HasCryptoStreamData() mockStreamFramer.EXPECT().HasCryptoStreamData()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) expectAppendStreamFrames()
packer.QueueControlFrame(&wire.MaxDataFrame{}) packer.QueueControlFrame(&wire.MaxDataFrame{})
packer.QueueControlFrame(&wire.StopWaitingFrame{}) packer.QueueControlFrame(&wire.StopWaitingFrame{})
p, err := packer.PackPacket() p, err := packer.PackPacket()
@ -547,18 +556,18 @@ var _ = Describe("Packet packer", func() {
}) })
Context("STREAM frame handling", func() { Context("STREAM frame handling", func() {
It("does not splits a STREAM frame with maximum size, for gQUIC frames", func() { It("does not split a STREAM frame with maximum size, for gQUIC frames", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2) mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2)
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).DoAndReturn(func(maxSize protocol.ByteCount) []*wire.StreamFrame { mockStreamFramer.EXPECT().AppendStreamFrames(gomock.Any(), gomock.Any()).DoAndReturn(func(_ []wire.Frame, maxSize protocol.ByteCount) ([]wire.Frame, protocol.ByteCount) {
f := &wire.StreamFrame{ f := &wire.StreamFrame{
Offset: 1, Offset: 1,
StreamID: 5, StreamID: 5,
DataLenPresent: true, DataLenPresent: true,
} }
f.Data = bytes.Repeat([]byte{'f'}, int(maxSize-f.Length(packer.version))) f.Data = bytes.Repeat([]byte{'f'}, int(maxSize-f.Length(packer.version)))
return []*wire.StreamFrame{f} return []wire.Frame{f}, f.Length(packer.version)
}) })
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) mockStreamFramer.EXPECT().AppendStreamFrames(gomock.Any(), gomock.Any())
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p.frames).To(HaveLen(1)) Expect(p.frames).To(HaveLen(1))
@ -569,19 +578,19 @@ var _ = Describe("Packet packer", func() {
Expect(p).To(BeNil()) Expect(p).To(BeNil())
}) })
It("does not splits a STREAM frame with maximum size, for IETF draft style frame", func() { It("does not split a STREAM frame with maximum size, for IETF draft style frame", func() {
packer.version = versionIETFFrames packer.version = versionIETFFrames
mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2) mockStreamFramer.EXPECT().HasCryptoStreamData().Times(2)
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).DoAndReturn(func(maxSize protocol.ByteCount) []*wire.StreamFrame { mockStreamFramer.EXPECT().AppendStreamFrames(gomock.Any(), gomock.Any()).DoAndReturn(func(_ []wire.Frame, maxSize protocol.ByteCount) ([]wire.Frame, protocol.ByteCount) {
f := &wire.StreamFrame{ f := &wire.StreamFrame{
Offset: 1, Offset: 1,
StreamID: 5, StreamID: 5,
DataLenPresent: true, DataLenPresent: true,
} }
f.Data = bytes.Repeat([]byte{'f'}, int(maxSize-f.Length(packer.version))) f.Data = bytes.Repeat([]byte{'f'}, int(maxSize-f.Length(packer.version)))
return []*wire.StreamFrame{f} return []wire.Frame{f}, f.Length(packer.version)
}) })
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) mockStreamFramer.EXPECT().AppendStreamFrames(gomock.Any(), gomock.Any())
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p.frames).To(HaveLen(1)) Expect(p.frames).To(HaveLen(1))
@ -609,7 +618,7 @@ var _ = Describe("Packet packer", func() {
DataLenPresent: true, DataLenPresent: true,
} }
mockStreamFramer.EXPECT().HasCryptoStreamData() mockStreamFramer.EXPECT().HasCryptoStreamData()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).Return([]*wire.StreamFrame{f1, f2, f3}) expectAppendStreamFrames(f1, f2, f3)
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(p).ToNot(BeNil()) Expect(p).ToNot(BeNil())
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
@ -632,12 +641,12 @@ var _ = Describe("Packet packer", func() {
}) })
It("sends non forward-secure data as the client", func() { It("sends non forward-secure data as the client", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData()
f := &wire.StreamFrame{ f := &wire.StreamFrame{
StreamID: 5, StreamID: 5,
Data: []byte("foobar"), Data: []byte("foobar"),
} }
mockStreamFramer.EXPECT().HasCryptoStreamData() expectAppendStreamFrames(f)
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).Return([]*wire.StreamFrame{f})
packer.perspective = protocol.PerspectiveClient packer.perspective = protocol.PerspectiveClient
packer.cryptoSetup.(*mockCryptoSetup).encLevelSeal = protocol.EncryptionSecure packer.cryptoSetup.(*mockCryptoSetup).encLevelSeal = protocol.EncryptionSecure
p, err := packer.PackPacket() p, err := packer.PackPacket()
@ -718,7 +727,7 @@ var _ = Describe("Packet packer", func() {
It("packs a single ACK", func() { It("packs a single ACK", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData() mockStreamFramer.EXPECT().HasCryptoStreamData()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) expectAppendStreamFrames()
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Largest: 42, Smallest: 1}}} ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Largest: 42, Smallest: 1}}}
packer.QueueControlFrame(ack) packer.QueueControlFrame(ack)
p, err := packer.PackPacket() p, err := packer.PackPacket()
@ -729,7 +738,7 @@ var _ = Describe("Packet packer", func() {
It("does not return nil if we only have a single ACK but request it to be sent", func() { It("does not return nil if we only have a single ACK but request it to be sent", func() {
mockStreamFramer.EXPECT().HasCryptoStreamData() mockStreamFramer.EXPECT().HasCryptoStreamData()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()) expectAppendStreamFrames()
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}} ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}}
packer.QueueControlFrame(ack) packer.QueueControlFrame(ack)
p, err := packer.PackPacket() p, err := packer.PackPacket()
@ -1049,7 +1058,9 @@ var _ = Describe("Packet packer", func() {
packer.QueueControlFrame(&wire.PingFrame{}) packer.QueueControlFrame(&wire.PingFrame{})
} }
mockStreamFramer.EXPECT().HasCryptoStreamData().AnyTimes() mockStreamFramer.EXPECT().HasCryptoStreamData().AnyTimes()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).AnyTimes() mockStreamFramer.EXPECT().AppendStreamFrames(gomock.Any(), gomock.Any()).DoAndReturn(func(fs []wire.Frame, _ protocol.ByteCount) []wire.Frame {
return fs
}).AnyTimes()
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p.raw).To(HaveLen(int(maxPacketSize))) Expect(p.raw).To(HaveLen(int(maxPacketSize)))
@ -1065,7 +1076,9 @@ var _ = Describe("Packet packer", func() {
packer.QueueControlFrame(&wire.PingFrame{}) packer.QueueControlFrame(&wire.PingFrame{})
} }
mockStreamFramer.EXPECT().HasCryptoStreamData().AnyTimes() mockStreamFramer.EXPECT().HasCryptoStreamData().AnyTimes()
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any()).AnyTimes() mockStreamFramer.EXPECT().AppendStreamFrames(gomock.Any(), gomock.Any()).DoAndReturn(func(fs []wire.Frame, _ protocol.ByteCount) []wire.Frame {
return fs
}).AnyTimes()
p, err := packer.PackPacket() p, err := packer.PackPacket()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p.raw).To(HaveLen(int(maxPacketSize))) Expect(p.raw).To(HaveLen(int(maxPacketSize)))

View file

@ -61,14 +61,13 @@ func (f *streamFramer) PopCryptoStreamFrame(maxLen protocol.ByteCount) *wire.Str
return frame return frame
} }
func (f *streamFramer) PopStreamFrames(maxTotalLen protocol.ByteCount) []*wire.StreamFrame { func (f *streamFramer) AppendStreamFrames(frames []wire.Frame, maxLen protocol.ByteCount) []wire.Frame {
var currentLen protocol.ByteCount var length protocol.ByteCount
var frames []*wire.StreamFrame
f.streamQueueMutex.Lock() f.streamQueueMutex.Lock()
// pop STREAM frames, until less than MinStreamFrameSize bytes are left in the packet // pop STREAM frames, until less than MinStreamFrameSize bytes are left in the packet
numActiveStreams := len(f.streamQueue) numActiveStreams := len(f.streamQueue)
for i := 0; i < numActiveStreams; i++ { for i := 0; i < numActiveStreams; i++ {
if maxTotalLen-currentLen < protocol.MinStreamFrameSize { if maxLen-length < protocol.MinStreamFrameSize {
break break
} }
id := f.streamQueue[0] id := f.streamQueue[0]
@ -81,7 +80,7 @@ func (f *streamFramer) PopStreamFrames(maxTotalLen protocol.ByteCount) []*wire.S
delete(f.activeStreams, id) delete(f.activeStreams, id)
continue continue
} }
frame, hasMoreData := str.popStreamFrame(maxTotalLen - currentLen) frame, hasMoreData := str.popStreamFrame(maxLen - length)
if hasMoreData { // put the stream back in the queue (at the end) if hasMoreData { // put the stream back in the queue (at the end)
f.streamQueue = append(f.streamQueue, id) f.streamQueue = append(f.streamQueue, id)
} else { // no more data to send. Stream is not active any more } else { // no more data to send. Stream is not active any more
@ -91,7 +90,7 @@ func (f *streamFramer) PopStreamFrames(maxTotalLen protocol.ByteCount) []*wire.S
continue continue
} }
frames = append(frames, frame) frames = append(frames, frame)
currentLen += frame.Length(f.version) length += frame.Length(f.version)
} }
f.streamQueueMutex.Unlock() f.streamQueueMutex.Unlock()
return frames return frames

View file

@ -68,7 +68,7 @@ var _ = Describe("Stream Framer", func() {
Context("Popping", func() { Context("Popping", func() {
It("returns nil when popping an empty framer", func() { It("returns nil when popping an empty framer", func() {
Expect(framer.PopStreamFrames(1000)).To(BeEmpty()) Expect(framer.AppendStreamFrames(nil, 1000)).To(BeEmpty())
}) })
It("returns STREAM frames", func() { It("returns STREAM frames", func() {
@ -80,8 +80,22 @@ var _ = Describe("Stream Framer", func() {
} }
stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f, false) stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f, false)
framer.AddActiveStream(id1) framer.AddActiveStream(id1)
fs := framer.PopStreamFrames(1000) fs := framer.AppendStreamFrames(nil, 1000)
Expect(fs).To(Equal([]*wire.StreamFrame{f})) Expect(fs).To(Equal([]wire.Frame{f}))
})
It("appends to a frame slice", func() {
streamGetter.EXPECT().GetOrOpenSendStream(id1).Return(stream1, nil)
f := &wire.StreamFrame{
StreamID: id1,
Data: []byte("foobar"),
}
stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f, false)
framer.AddActiveStream(id1)
mdf := &wire.MaxDataFrame{ByteOffset: 1337}
frames := []wire.Frame{mdf}
fs := framer.AppendStreamFrames(frames, 1000)
Expect(fs).To(Equal([]wire.Frame{mdf, f}))
}) })
It("skips a stream that was reported active, but was completed shortly after", func() { It("skips a stream that was reported active, but was completed shortly after", func() {
@ -94,7 +108,7 @@ var _ = Describe("Stream Framer", func() {
stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f, false) stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f, false)
framer.AddActiveStream(id1) framer.AddActiveStream(id1)
framer.AddActiveStream(id2) framer.AddActiveStream(id2)
Expect(framer.PopStreamFrames(1000)).To(Equal([]*wire.StreamFrame{f})) Expect(framer.AppendStreamFrames(nil, 1000)).To(Equal([]wire.Frame{f}))
}) })
It("skips a stream that was reported active, but doesn't have any data", func() { It("skips a stream that was reported active, but doesn't have any data", func() {
@ -108,7 +122,7 @@ var _ = Describe("Stream Framer", func() {
stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f, false) stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f, false)
framer.AddActiveStream(id1) framer.AddActiveStream(id1)
framer.AddActiveStream(id2) framer.AddActiveStream(id2)
Expect(framer.PopStreamFrames(1000)).To(Equal([]*wire.StreamFrame{f})) Expect(framer.AppendStreamFrames(nil, 1000)).To(Equal([]wire.Frame{f}))
}) })
It("pops from a stream multiple times, if it has enough data", func() { It("pops from a stream multiple times, if it has enough data", func() {
@ -118,10 +132,10 @@ var _ = Describe("Stream Framer", func() {
stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f1, true) stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f1, true)
stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f2, false) stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f2, false)
framer.AddActiveStream(id1) // only add it once framer.AddActiveStream(id1) // only add it once
Expect(framer.PopStreamFrames(protocol.MinStreamFrameSize)).To(Equal([]*wire.StreamFrame{f1})) Expect(framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize)).To(Equal([]wire.Frame{f1}))
Expect(framer.PopStreamFrames(protocol.MinStreamFrameSize)).To(Equal([]*wire.StreamFrame{f2})) Expect(framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize)).To(Equal([]wire.Frame{f2}))
// no further calls to popStreamFrame, after popStreamFrame said there's no more data // no further calls to popStreamFrame, after popStreamFrame said there's no more data
Expect(framer.PopStreamFrames(protocol.MinStreamFrameSize)).To(BeNil()) Expect(framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize)).To(BeNil())
}) })
It("re-queues a stream at the end, if it has enough data", func() { It("re-queues a stream at the end, if it has enough data", func() {
@ -135,9 +149,12 @@ var _ = Describe("Stream Framer", func() {
stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f2, false) stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f2, false)
framer.AddActiveStream(id1) // only add it once framer.AddActiveStream(id1) // only add it once
framer.AddActiveStream(id2) framer.AddActiveStream(id2)
Expect(framer.PopStreamFrames(protocol.MinStreamFrameSize)).To(Equal([]*wire.StreamFrame{f11})) // first a frame from stream 1 // first a frame from stream 1
Expect(framer.PopStreamFrames(protocol.MinStreamFrameSize)).To(Equal([]*wire.StreamFrame{f2})) // then a frame from stream 2 Expect(framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize)).To(Equal([]wire.Frame{f11}))
Expect(framer.PopStreamFrames(protocol.MinStreamFrameSize)).To(Equal([]*wire.StreamFrame{f12})) // then another frame from stream 1 // then a frame from stream 2
Expect(framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize)).To(Equal([]wire.Frame{f2}))
// then another frame from stream 1
Expect(framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize)).To(Equal([]wire.Frame{f12}))
}) })
It("only dequeues data from each stream once per packet", func() { It("only dequeues data from each stream once per packet", func() {
@ -150,7 +167,7 @@ var _ = Describe("Stream Framer", func() {
stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f2, true) stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f2, true)
framer.AddActiveStream(id1) framer.AddActiveStream(id1)
framer.AddActiveStream(id2) framer.AddActiveStream(id2)
Expect(framer.PopStreamFrames(1000)).To(Equal([]*wire.StreamFrame{f1, f2})) Expect(framer.AppendStreamFrames(nil, 1000)).To(Equal([]wire.Frame{f1, f2}))
}) })
It("returns multiple normal frames in the order they were reported active", func() { It("returns multiple normal frames in the order they were reported active", func() {
@ -162,7 +179,7 @@ var _ = Describe("Stream Framer", func() {
stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f2, false) stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f2, false)
framer.AddActiveStream(id2) framer.AddActiveStream(id2)
framer.AddActiveStream(id1) framer.AddActiveStream(id1)
Expect(framer.PopStreamFrames(1000)).To(Equal([]*wire.StreamFrame{f2, f1})) Expect(framer.AppendStreamFrames(nil, 1000)).To(Equal([]wire.Frame{f2, f1}))
}) })
It("only asks a stream for data once, even if it was reported active multiple times", func() { It("only asks a stream for data once, even if it was reported active multiple times", func() {
@ -171,11 +188,11 @@ var _ = Describe("Stream Framer", func() {
stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f, false) // only one call to this function stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f, false) // only one call to this function
framer.AddActiveStream(id1) framer.AddActiveStream(id1)
framer.AddActiveStream(id1) framer.AddActiveStream(id1)
Expect(framer.PopStreamFrames(1000)).To(HaveLen(1)) Expect(framer.AppendStreamFrames(nil, 1000)).To(HaveLen(1))
}) })
It("does not pop empty frames", func() { It("does not pop empty frames", func() {
fs := framer.PopStreamFrames(500) fs := framer.AppendStreamFrames(nil, 500)
Expect(fs).To(BeEmpty()) Expect(fs).To(BeEmpty())
}) })
@ -183,12 +200,12 @@ var _ = Describe("Stream Framer", func() {
streamGetter.EXPECT().GetOrOpenSendStream(id1).Return(stream1, nil) streamGetter.EXPECT().GetOrOpenSendStream(id1).Return(stream1, nil)
stream1.EXPECT().popStreamFrame(protocol.MinStreamFrameSize).Return(&wire.StreamFrame{Data: []byte("foobar")}, false) stream1.EXPECT().popStreamFrame(protocol.MinStreamFrameSize).Return(&wire.StreamFrame{Data: []byte("foobar")}, false)
framer.AddActiveStream(id1) framer.AddActiveStream(id1)
framer.PopStreamFrames(protocol.MinStreamFrameSize) framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize)
}) })
It("does not pop frames smaller than the minimum size", func() { It("does not pop frames smaller than the minimum size", func() {
// don't expect a call to PopStreamFrame() // don't expect a call to PopStreamFrame()
framer.PopStreamFrames(protocol.MinStreamFrameSize - 1) framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize-1)
}) })
It("stops iterating when the remaining size is smaller than the minimum STREAM frame size", func() { It("stops iterating when the remaining size is smaller than the minimum STREAM frame size", func() {
@ -200,8 +217,8 @@ var _ = Describe("Stream Framer", func() {
} }
stream1.EXPECT().popStreamFrame(protocol.ByteCount(500)).Return(f, false) stream1.EXPECT().popStreamFrame(protocol.ByteCount(500)).Return(f, false)
framer.AddActiveStream(id1) framer.AddActiveStream(id1)
fs := framer.PopStreamFrames(500) fs := framer.AppendStreamFrames(nil, 500)
Expect(fs).To(Equal([]*wire.StreamFrame{f})) Expect(fs).To(Equal([]wire.Frame{f}))
}) })
}) })
}) })