Merge pull request #2047 from lucas-clemente/fix-stream-frame-length-calculation

fix calculation of the length of appended STREAM frames
This commit is contained in:
Marten Seemann
2019-08-12 12:15:32 -04:00
committed by GitHub
3 changed files with 28 additions and 12 deletions

View File

@@ -114,7 +114,11 @@ func (f *framerI) AppendStreamFrames(frames []wire.Frame, maxLen protocol.ByteCo
}
f.mutex.Unlock()
if frameAdded {
frames[len(frames)-1].(*wire.StreamFrame).DataLenPresent = false
lastFrame := frames[len(frames)-1].(*wire.StreamFrame)
lastFrameLen := lastFrame.Length(f.version)
// acount for the smaller size of the last STREAM frame
lastFrame.DataLenPresent = false
length += lastFrame.Length(f.version) - lastFrameLen
}
return frames, length
}

View File

@@ -80,22 +80,25 @@ var _ = Describe("Framer", func() {
It("returns STREAM frames", func() {
streamGetter.EXPECT().GetOrOpenSendStream(id1).Return(stream1, nil)
f := &wire.StreamFrame{
StreamID: id1,
Data: []byte("foobar"),
Offset: 42,
StreamID: id1,
Data: []byte("foobar"),
Offset: 42,
DataLenPresent: true,
}
stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f, false)
framer.AddActiveStream(id1)
fs, length := framer.AppendStreamFrames(nil, 1000)
Expect(fs).To(Equal([]wire.Frame{f}))
Expect(fs[0].(*wire.StreamFrame).DataLenPresent).To(BeFalse())
Expect(length).To(Equal(f.Length(version)))
})
It("appends to a frame slice", func() {
streamGetter.EXPECT().GetOrOpenSendStream(id1).Return(stream1, nil)
f := &wire.StreamFrame{
StreamID: id1,
Data: []byte("foobar"),
StreamID: id1,
Data: []byte("foobar"),
DataLenPresent: true,
}
stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f, false)
framer.AddActiveStream(id1)
@@ -103,6 +106,7 @@ var _ = Describe("Framer", func() {
frames := []wire.Frame{mdf}
fs, length := framer.AppendStreamFrames(frames, 1000)
Expect(fs).To(Equal([]wire.Frame{mdf, f}))
Expect(fs[1].(*wire.StreamFrame).DataLenPresent).To(BeFalse())
Expect(length).To(Equal(f.Length(version)))
})
@@ -110,8 +114,9 @@ var _ = Describe("Framer", func() {
streamGetter.EXPECT().GetOrOpenSendStream(id1).Return(nil, nil)
streamGetter.EXPECT().GetOrOpenSendStream(id2).Return(stream2, nil)
f := &wire.StreamFrame{
StreamID: id2,
Data: []byte("foobar"),
StreamID: id2,
Data: []byte("foobar"),
DataLenPresent: true,
}
stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f, false)
framer.AddActiveStream(id1)
@@ -124,8 +129,9 @@ var _ = Describe("Framer", func() {
streamGetter.EXPECT().GetOrOpenSendStream(id1).Return(stream1, nil)
streamGetter.EXPECT().GetOrOpenSendStream(id2).Return(stream2, nil)
f := &wire.StreamFrame{
StreamID: id2,
Data: []byte("foobar"),
StreamID: id2,
Data: []byte("foobar"),
DataLenPresent: true,
}
stream1.EXPECT().popStreamFrame(gomock.Any()).Return(nil, false)
stream2.EXPECT().popStreamFrame(gomock.Any()).Return(f, false)
@@ -287,8 +293,9 @@ var _ = Describe("Framer", func() {
streamGetter.EXPECT().GetOrOpenSendStream(id1).Return(stream1, nil)
// pop a frame such that the remaining size is one byte less than the minimum STREAM frame size
f := &wire.StreamFrame{
StreamID: id1,
Data: bytes.Repeat([]byte("f"), int(500-protocol.MinStreamFrameSize)),
StreamID: id1,
Data: bytes.Repeat([]byte("f"), int(500-protocol.MinStreamFrameSize)),
DataLenPresent: true,
}
stream1.EXPECT().popStreamFrame(gomock.Any()).Return(f, false)
framer.AddActiveStream(id1)

View File

@@ -295,7 +295,9 @@ func (p *packetPacker) PackRetransmission(packet *ackhandler.Packet) ([]*packedP
frames = append(frames, frameToAdd)
}
if sf, ok := frames[len(frames)-1].(*wire.StreamFrame); ok {
sfLen := sf.Length(p.version)
sf.DataLenPresent = false
length += sf.Length(p.version) - sfLen
}
p, err := p.writeAndSealPacket(hdr, payload{frames: frames, length: length}, packet.EncryptionLevel, sealer)
if err != nil {
@@ -544,6 +546,9 @@ func (p *packetPacker) writeAndSealPacketWithPadding(
}
}
if payloadSize := protocol.ByteCount(buffer.Len()-payloadOffset) - paddingLen; payloadSize != payload.length {
return nil, fmt.Errorf("PacketPacker BUG: payload size inconsistent (expected %d, got %d bytes)", payload.length, payloadSize)
}
if size := protocol.ByteCount(buffer.Len() + sealer.Overhead()); size > p.maxPacketSize {
return nil, fmt.Errorf("PacketPacker BUG: packet too large (%d bytes, allowed %d bytes)", size, p.maxPacketSize)
}