mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-05 21:27:35 +03:00
fix splitting of STREAM frames for IETF QUIC
Move splitting of STREAM frames from the quic package to the wire package.
This commit is contained in:
parent
5974c6c113
commit
80969de93f
39 changed files with 248 additions and 157 deletions
|
@ -138,10 +138,10 @@ func (f *AckFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *AckFrame) MinLength(version protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *AckFrame) Length(version protocol.VersionNumber) protocol.ByteCount {
|
||||
if !version.UsesIETFFrameFormat() {
|
||||
return f.minLengthLegacy(version)
|
||||
return f.lengthLegacy(version)
|
||||
}
|
||||
|
||||
length := 1 + utils.VarIntLen(uint64(f.LargestAcked)) + utils.VarIntLen(uint64(encodeAckDelay(f.DelayTime)))
|
||||
|
|
|
@ -308,7 +308,7 @@ func (f *AckFrame) writeLegacy(b *bytes.Buffer, _ protocol.VersionNumber) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func (f *AckFrame) minLengthLegacy(_ protocol.VersionNumber) protocol.ByteCount {
|
||||
func (f *AckFrame) lengthLegacy(_ protocol.VersionNumber) protocol.ByteCount {
|
||||
length := protocol.ByteCount(1 + 2 + 1) // 1 TypeByte, 2 ACK delay time, 1 Num Timestamp
|
||||
length += protocol.ByteCount(protocol.GetPacketNumberLength(f.LargestAcked))
|
||||
|
||||
|
|
|
@ -1067,7 +1067,7 @@ var _ = Describe("ACK Frame (for gQUIC)", func() {
|
|||
}
|
||||
err := f.Write(b, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
Expect(f.Length(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
})
|
||||
|
||||
It("has proper min length with a large LargestObserved", func() {
|
||||
|
@ -1076,7 +1076,7 @@ var _ = Describe("ACK Frame (for gQUIC)", func() {
|
|||
}
|
||||
err := f.Write(b, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
Expect(f.Length(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
})
|
||||
|
||||
It("has the proper min length for an ACK with missing packets", func() {
|
||||
|
@ -1091,7 +1091,7 @@ var _ = Describe("ACK Frame (for gQUIC)", func() {
|
|||
}
|
||||
err := f.Write(b, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
Expect(f.Length(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
})
|
||||
|
||||
It("has the proper min length for an ACK with long gaps of missing packets", func() {
|
||||
|
@ -1106,7 +1106,7 @@ var _ = Describe("ACK Frame (for gQUIC)", func() {
|
|||
}
|
||||
err := f.Write(b, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
Expect(f.Length(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
})
|
||||
|
||||
It("has the proper min length for an ACK with a long ACK range", func() {
|
||||
|
@ -1122,7 +1122,7 @@ var _ = Describe("ACK Frame (for gQUIC)", func() {
|
|||
}
|
||||
err := f.Write(b, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
Expect(f.Length(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -140,7 +140,7 @@ var _ = Describe("ACK Frame (for IETF QUIC)", func() {
|
|||
}
|
||||
err := f.Write(buf, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionIETFFrames)).To(BeEquivalentTo(buf.Len()))
|
||||
Expect(f.Length(versionIETFFrames)).To(BeEquivalentTo(buf.Len()))
|
||||
b := bytes.NewReader(buf.Bytes())
|
||||
frame, err := ParseAckFrame(b, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -157,7 +157,7 @@ var _ = Describe("ACK Frame (for IETF QUIC)", func() {
|
|||
}
|
||||
err := f.Write(buf, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionIETFFrames)).To(BeEquivalentTo(buf.Len()))
|
||||
Expect(f.Length(versionIETFFrames)).To(BeEquivalentTo(buf.Len()))
|
||||
b := bytes.NewReader(buf.Bytes())
|
||||
frame, err := ParseAckFrame(b, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -179,7 +179,7 @@ var _ = Describe("ACK Frame (for IETF QUIC)", func() {
|
|||
Expect(f.validateAckRanges()).To(BeTrue())
|
||||
err := f.Write(buf, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionIETFFrames)).To(BeEquivalentTo(buf.Len()))
|
||||
Expect(f.Length(versionIETFFrames)).To(BeEquivalentTo(buf.Len()))
|
||||
b := bytes.NewReader(buf.Bytes())
|
||||
frame, err := ParseAckFrame(b, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -203,7 +203,7 @@ var _ = Describe("ACK Frame (for IETF QUIC)", func() {
|
|||
Expect(f.validateAckRanges()).To(BeTrue())
|
||||
err := f.Write(buf, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionIETFFrames)).To(BeEquivalentTo(buf.Len()))
|
||||
Expect(f.Length(versionIETFFrames)).To(BeEquivalentTo(buf.Len()))
|
||||
b := bytes.NewReader(buf.Bytes())
|
||||
frame, err := ParseAckFrame(b, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
|
|
@ -36,8 +36,8 @@ func (f *BlockedFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) er
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *BlockedFrame) MinLength(version protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *BlockedFrame) Length(version protocol.VersionNumber) protocol.ByteCount {
|
||||
if !version.UsesIETFFrameFormat() {
|
||||
return 1 + 4
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ var _ = Describe("legacy BLOCKED Frame", func() {
|
|||
|
||||
It("has the correct min length for a BLOCKED frame for a stream", func() {
|
||||
frame := StreamBlockedFrame{StreamID: 3}
|
||||
Expect(frame.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(5)))
|
||||
Expect(frame.Length(versionBigEndian)).To(Equal(protocol.ByteCount(5)))
|
||||
})
|
||||
|
||||
It("writes a BLOCKED frame for the connection", func() {
|
||||
|
@ -59,7 +59,7 @@ var _ = Describe("legacy BLOCKED Frame", func() {
|
|||
|
||||
It("has the correct min length for a BLOCKED frame for the connection", func() {
|
||||
frame := BlockedFrame{}
|
||||
Expect(frame.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(5)))
|
||||
Expect(frame.Length(versionBigEndian)).To(Equal(protocol.ByteCount(5)))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -48,7 +48,7 @@ var _ = Describe("BLOCKED frame", func() {
|
|||
|
||||
It("has the correct min length", func() {
|
||||
frame := BlockedFrame{Offset: 0x12345}
|
||||
Expect(frame.MinLength(versionIETFFrames)).To(Equal(1 + utils.VarIntLen(0x12345)))
|
||||
Expect(frame.Length(versionIETFFrames)).To(Equal(1 + utils.VarIntLen(0x12345)))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -67,8 +67,8 @@ func ParseConnectionCloseFrame(r *bytes.Reader, version protocol.VersionNumber)
|
|||
}, nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *ConnectionCloseFrame) MinLength(version protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *ConnectionCloseFrame) Length(version protocol.VersionNumber) protocol.ByteCount {
|
||||
if version.UsesIETFFrameFormat() {
|
||||
return 1 + 2 + utils.VarIntLen(uint64(len(f.ReasonPhrase))) + protocol.ByteCount(len(f.ReasonPhrase))
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ var _ = Describe("CONNECTION_CLOSE Frame", func() {
|
|||
}
|
||||
err := f.Write(b, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionIETFFrames)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
Expect(f.Length(versionIETFFrames)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -189,7 +189,7 @@ var _ = Describe("CONNECTION_CLOSE Frame", func() {
|
|||
}
|
||||
err := f.Write(b, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
Expect(f.Length(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -9,5 +9,5 @@ import (
|
|||
// A Frame in QUIC
|
||||
type Frame interface {
|
||||
Write(b *bytes.Buffer, version protocol.VersionNumber) error
|
||||
MinLength(version protocol.VersionNumber) protocol.ByteCount
|
||||
Length(version protocol.VersionNumber) protocol.ByteCount
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ func (f *GoawayFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *GoawayFrame) MinLength(version protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *GoawayFrame) Length(version protocol.VersionNumber) protocol.ByteCount {
|
||||
return protocol.ByteCount(1 + 4 + 4 + 2 + len(f.ReasonPhrase))
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ var _ = Describe("GoawayFrame", func() {
|
|||
frame := GoawayFrame{
|
||||
ReasonPhrase: "foo",
|
||||
}
|
||||
Expect(frame.MinLength(0)).To(Equal(protocol.ByteCount(14)))
|
||||
Expect(frame.Length(0)).To(Equal(protocol.ByteCount(14)))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -42,8 +42,8 @@ func (f *MaxDataFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) er
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *MaxDataFrame) MinLength(version protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *MaxDataFrame) Length(version protocol.VersionNumber) protocol.ByteCount {
|
||||
if !version.UsesIETFFrameFormat() { // writing this frame would result in a gQUIC WINDOW_UPDATE being written, which is longer
|
||||
return 1 + 4 + 8
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ var _ = Describe("MAX_DATA frame", func() {
|
|||
f := &MaxDataFrame{
|
||||
ByteOffset: 0xdeadbeef,
|
||||
}
|
||||
Expect(f.MinLength(versionIETFFrames)).To(Equal(1 + utils.VarIntLen(0xdeadbeef)))
|
||||
Expect(f.Length(versionIETFFrames)).To(Equal(1 + utils.VarIntLen(0xdeadbeef)))
|
||||
})
|
||||
|
||||
It("writes a MAX_DATA frame", func() {
|
||||
|
|
|
@ -50,8 +50,8 @@ func (f *MaxStreamDataFrame) Write(b *bytes.Buffer, version protocol.VersionNumb
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *MaxStreamDataFrame) MinLength(version protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *MaxStreamDataFrame) Length(version protocol.VersionNumber) protocol.ByteCount {
|
||||
// writing this frame would result in a gQUIC WINDOW_UPDATE being written, which has a different length
|
||||
if !version.UsesIETFFrameFormat() {
|
||||
return 1 + 4 + 8
|
||||
|
|
|
@ -42,7 +42,7 @@ var _ = Describe("MAX_STREAM_DATA frame", func() {
|
|||
StreamID: 0x1337,
|
||||
ByteOffset: 0xdeadbeef,
|
||||
}
|
||||
Expect(f.MinLength(protocol.VersionWhatever)).To(Equal(1 + utils.VarIntLen(uint64(f.StreamID)) + utils.VarIntLen(uint64(f.ByteOffset))))
|
||||
Expect(f.Length(protocol.VersionWhatever)).To(Equal(1 + utils.VarIntLen(uint64(f.StreamID)) + utils.VarIntLen(uint64(f.ByteOffset))))
|
||||
})
|
||||
|
||||
It("writes a sample frame", func() {
|
||||
|
|
|
@ -31,7 +31,7 @@ func (f *MaxStreamIDFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) erro
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *MaxStreamIDFrame) MinLength(protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *MaxStreamIDFrame) Length(protocol.VersionNumber) protocol.ByteCount {
|
||||
return 1 + utils.VarIntLen(uint64(f.StreamID))
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ var _ = Describe("MAX_STREAM_ID frame", func() {
|
|||
|
||||
It("has the correct min length", func() {
|
||||
frame := MaxStreamIDFrame{StreamID: 0x1337}
|
||||
Expect(frame.MinLength(protocol.VersionWhatever)).To(Equal(1 + utils.VarIntLen(0x1337)))
|
||||
Expect(frame.Length(protocol.VersionWhatever)).To(Equal(1 + utils.VarIntLen(0x1337)))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -27,7 +27,7 @@ func (f *PingFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *PingFrame) MinLength(version protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *PingFrame) Length(version protocol.VersionNumber) protocol.ByteCount {
|
||||
return 1
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ var _ = Describe("PingFrame", func() {
|
|||
|
||||
It("has the correct min length", func() {
|
||||
frame := PingFrame{}
|
||||
Expect(frame.MinLength(0)).To(Equal(protocol.ByteCount(1)))
|
||||
Expect(frame.Length(0)).To(Equal(protocol.ByteCount(1)))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -80,8 +80,8 @@ func (f *RstStreamFrame) Write(b *bytes.Buffer, version protocol.VersionNumber)
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *RstStreamFrame) MinLength(version protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *RstStreamFrame) Length(version protocol.VersionNumber) protocol.ByteCount {
|
||||
if version.UsesIETFFrameFormat() {
|
||||
return 1 + utils.VarIntLen(uint64(f.StreamID)) + 2 + utils.VarIntLen(uint64(f.ByteOffset))
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ var _ = Describe("RST_STREAM frame", func() {
|
|||
ErrorCode: 0xde,
|
||||
}
|
||||
expectedLen := 1 + utils.VarIntLen(0x1337) + utils.VarIntLen(0x1234567) + 2
|
||||
Expect(rst.MinLength(versionIETFFrames)).To(Equal(expectedLen))
|
||||
Expect(rst.Length(versionIETFFrames)).To(Equal(expectedLen))
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -121,7 +121,7 @@ var _ = Describe("RST_STREAM frame", func() {
|
|||
ByteOffset: 0x1000,
|
||||
ErrorCode: 0xde,
|
||||
}
|
||||
Expect(rst.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(17)))
|
||||
Expect(rst.Length(versionBigEndian)).To(Equal(protocol.ByteCount(17)))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -34,8 +34,8 @@ func ParseStopSendingFrame(r *bytes.Reader, _ protocol.VersionNumber) (*StopSend
|
|||
}, nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *StopSendingFrame) MinLength(_ protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *StopSendingFrame) Length(_ protocol.VersionNumber) protocol.ByteCount {
|
||||
return 1 + utils.VarIntLen(uint64(f.StreamID)) + 2
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ var _ = Describe("STOP_SENDING frame", func() {
|
|||
StreamID: 0xdeadbeef,
|
||||
ErrorCode: 0x10,
|
||||
}
|
||||
Expect(frame.MinLength(versionIETFFrames)).To(Equal(1 + 2 + utils.VarIntLen(0xdeadbeef)))
|
||||
Expect(frame.Length(versionIETFFrames)).To(Equal(1 + 2 + utils.VarIntLen(0xdeadbeef)))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -51,8 +51,8 @@ func (f *StopWaitingFrame) Write(b *bytes.Buffer, v protocol.VersionNumber) erro
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *StopWaitingFrame) MinLength(_ protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *StopWaitingFrame) Length(_ protocol.VersionNumber) protocol.ByteCount {
|
||||
return 1 + protocol.ByteCount(f.PacketNumberLen)
|
||||
}
|
||||
|
||||
|
|
|
@ -177,14 +177,14 @@ var _ = Describe("StopWaitingFrame", func() {
|
|||
})
|
||||
})
|
||||
|
||||
Context("minLength", func() {
|
||||
It("calculates the right minLength", func() {
|
||||
Context("Length", func() {
|
||||
It("calculates the right length", func() {
|
||||
for _, length := range []protocol.PacketNumberLen{protocol.PacketNumberLen1, protocol.PacketNumberLen2, protocol.PacketNumberLen4, protocol.PacketNumberLen6} {
|
||||
frame := &StopWaitingFrame{
|
||||
LeastUnacked: 10,
|
||||
PacketNumberLen: length,
|
||||
}
|
||||
Expect(frame.MinLength(protocol.VersionWhatever)).To(Equal(protocol.ByteCount(length + 1)))
|
||||
Expect(frame.Length(protocol.VersionWhatever)).To(Equal(protocol.ByteCount(length + 1)))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
@ -43,8 +43,8 @@ func (f *StreamBlockedFrame) Write(b *bytes.Buffer, version protocol.VersionNumb
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *StreamBlockedFrame) MinLength(version protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *StreamBlockedFrame) Length(version protocol.VersionNumber) protocol.ByteCount {
|
||||
if !version.UsesIETFFrameFormat() {
|
||||
return 1 + 4
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ var _ = Describe("STREAM_BLOCKED frame", func() {
|
|||
StreamID: 0x1337,
|
||||
Offset: 0xdeadbeef,
|
||||
}
|
||||
Expect(f.MinLength(0)).To(Equal(1 + utils.VarIntLen(0x1337) + utils.VarIntLen(0xdeadbeef)))
|
||||
Expect(f.Length(0)).To(Equal(1 + utils.VarIntLen(0x1337) + utils.VarIntLen(0xdeadbeef)))
|
||||
})
|
||||
|
||||
It("writes a sample frame", func() {
|
||||
|
|
|
@ -115,11 +115,10 @@ func (f *StreamFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) err
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength returns the length of the header of a StreamFrame
|
||||
// the total length of the frame is frame.MinLength() + frame.DataLen()
|
||||
func (f *StreamFrame) MinLength(version protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length returns the total length of the STREAM frame
|
||||
func (f *StreamFrame) Length(version protocol.VersionNumber) protocol.ByteCount {
|
||||
if !version.UsesIETFFrameFormat() {
|
||||
return f.minLengthLegacy(version)
|
||||
return f.lengthLegacy(version)
|
||||
}
|
||||
length := 1 + utils.VarIntLen(uint64(f.StreamID))
|
||||
if f.Offset != 0 {
|
||||
|
@ -128,11 +127,11 @@ func (f *StreamFrame) MinLength(version protocol.VersionNumber) protocol.ByteCou
|
|||
if f.DataLenPresent {
|
||||
length += utils.VarIntLen(uint64(f.DataLen()))
|
||||
}
|
||||
return length
|
||||
return length + f.DataLen()
|
||||
}
|
||||
|
||||
// MaxDataLen returns the maximum data length
|
||||
// If 0 is returned, writing will fail (a STREAM_FRAME must contain at least 1 byte of data).
|
||||
// If 0 is returned, writing will fail (a STREAM frame must contain at least 1 byte of data).
|
||||
func (f *StreamFrame) MaxDataLen(maxSize protocol.ByteCount, version protocol.VersionNumber) protocol.ByteCount {
|
||||
if !version.UsesIETFFrameFormat() {
|
||||
return f.maxDataLenLegacy(maxSize, version)
|
||||
|
@ -156,3 +155,28 @@ func (f *StreamFrame) MaxDataLen(maxSize protocol.ByteCount, version protocol.Ve
|
|||
}
|
||||
return maxDataLen
|
||||
}
|
||||
|
||||
// MaybeSplitOffFrame splits a frame such that it is not bigger than n bytes.
|
||||
// If n >= len(frame), nil is returned and nothing is modified.
|
||||
func (f *StreamFrame) MaybeSplitOffFrame(maxSize protocol.ByteCount, version protocol.VersionNumber) (*StreamFrame, error) {
|
||||
if maxSize >= f.Length(version) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
n := f.MaxDataLen(maxSize, version)
|
||||
if n == 0 {
|
||||
return nil, errors.New("too small")
|
||||
}
|
||||
newFrame := &StreamFrame{
|
||||
FinBit: false,
|
||||
StreamID: f.StreamID,
|
||||
Offset: f.Offset,
|
||||
Data: f.Data[:n],
|
||||
DataLenPresent: f.DataLenPresent,
|
||||
}
|
||||
|
||||
f.Data = f.Data[n:]
|
||||
f.Offset += n
|
||||
|
||||
return newFrame, nil
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ func (f *StreamFrame) getOffsetLength() protocol.ByteCount {
|
|||
return 8
|
||||
}
|
||||
|
||||
func (f *StreamFrame) minLengthLegacy(_ protocol.VersionNumber) protocol.ByteCount {
|
||||
func (f *StreamFrame) headerLengthLegacy(_ protocol.VersionNumber) protocol.ByteCount {
|
||||
length := protocol.ByteCount(1) + protocol.ByteCount(f.calculateStreamIDLength()) + f.getOffsetLength()
|
||||
if f.DataLenPresent {
|
||||
length += 2
|
||||
|
@ -191,8 +191,12 @@ func (f *StreamFrame) minLengthLegacy(_ protocol.VersionNumber) protocol.ByteCou
|
|||
return length
|
||||
}
|
||||
|
||||
func (f *StreamFrame) lengthLegacy(version protocol.VersionNumber) protocol.ByteCount {
|
||||
return f.headerLengthLegacy(version) + f.DataLen()
|
||||
}
|
||||
|
||||
func (f *StreamFrame) maxDataLenLegacy(maxFrameSize protocol.ByteCount, version protocol.VersionNumber) protocol.ByteCount {
|
||||
headerLen := f.minLengthLegacy(version)
|
||||
headerLen := f.headerLengthLegacy(version)
|
||||
if headerLen > maxFrameSize {
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ var _ = Describe("STREAM frame (for gQUIC)", func() {
|
|||
}
|
||||
err := f.Write(b, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
Expect(f.Length(0)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
})
|
||||
|
||||
It("has proper min length for a long StreamID and a big offset", func() {
|
||||
|
@ -195,7 +195,7 @@ var _ = Describe("STREAM frame (for gQUIC)", func() {
|
|||
}
|
||||
err := f.Write(b, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
Expect(f.Length(versionBigEndian)).To(Equal(protocol.ByteCount(b.Len())))
|
||||
})
|
||||
|
||||
Context("data length field", func() {
|
||||
|
@ -210,9 +210,11 @@ var _ = Describe("STREAM frame (for gQUIC)", func() {
|
|||
}
|
||||
err := f.Write(b, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
minLength := f.MinLength(0)
|
||||
Expect(b.Bytes()[0] & 0x20).To(Equal(uint8(0x20)))
|
||||
Expect(b.Bytes()[minLength-2 : minLength]).To(Equal([]byte{0x13, 0x37}))
|
||||
frame, err := ParseStreamFrame(bytes.NewReader(b.Bytes()), versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(frame.DataLenPresent).To(BeTrue())
|
||||
Expect(frame.DataLen()).To(Equal(protocol.ByteCount(dataLen)))
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -229,10 +231,10 @@ var _ = Describe("STREAM frame (for gQUIC)", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(b.Bytes()[0] & 0x20).To(Equal(uint8(0)))
|
||||
Expect(b.Bytes()[1 : b.Len()-dataLen]).ToNot(ContainSubstring(string([]byte{0x37, 0x13})))
|
||||
minLength := f.MinLength(versionBigEndian)
|
||||
length := f.Length(versionBigEndian)
|
||||
f.DataLenPresent = true
|
||||
minLengthWithoutDataLen := f.MinLength(versionBigEndian)
|
||||
Expect(minLength).To(Equal(minLengthWithoutDataLen - 2))
|
||||
lengthWithoutDataLen := f.Length(versionBigEndian)
|
||||
Expect(length).To(Equal(lengthWithoutDataLen - 2))
|
||||
})
|
||||
|
||||
It("calculates the correct min-length", func() {
|
||||
|
@ -242,9 +244,9 @@ var _ = Describe("STREAM frame (for gQUIC)", func() {
|
|||
DataLenPresent: false,
|
||||
Offset: 0xdeadbeef,
|
||||
}
|
||||
minLengthWithoutDataLen := f.MinLength(versionBigEndian)
|
||||
lengthWithoutDataLen := f.Length(versionBigEndian)
|
||||
f.DataLenPresent = true
|
||||
Expect(f.MinLength(versionBigEndian)).To(Equal(minLengthWithoutDataLen + 2))
|
||||
Expect(f.Length(versionBigEndian)).To(Equal(lengthWithoutDataLen + 2))
|
||||
})
|
||||
|
||||
Context("offset lengths", func() {
|
||||
|
@ -495,8 +497,8 @@ var _ = Describe("STREAM frame (for gQUIC)", func() {
|
|||
b.Reset()
|
||||
f.Data = nil
|
||||
maxDataLen := f.MaxDataLen(protocol.ByteCount(i), versionBigEndian)
|
||||
if maxDataLen == 0 { // 0 means that no valid STREAM_FRAME can be written
|
||||
// check that writing a minimal size STREAM_FRAME (i.e. with 1 byte data) is actually larger than the desired size
|
||||
if maxDataLen == 0 { // 0 means that no valid STREAM frame can be written
|
||||
// check that writing a minimal size STREAM frame (i.e. with 1 byte data) is actually larger than the desired size
|
||||
f.Data = []byte{0}
|
||||
err := f.Write(b, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
|
|
@ -186,7 +186,7 @@ var _ = Describe("STREAM frame (for IETF QUIC)", func() {
|
|||
StreamID: 0x1337,
|
||||
Data: []byte("foobar"),
|
||||
}
|
||||
Expect(f.MinLength(versionIETFFrames)).To(Equal(1 + utils.VarIntLen(0x1337)))
|
||||
Expect(f.Length(versionIETFFrames)).To(Equal(1 + utils.VarIntLen(0x1337) + 6))
|
||||
})
|
||||
|
||||
It("has the right length for a frame with offset", func() {
|
||||
|
@ -195,7 +195,7 @@ var _ = Describe("STREAM frame (for IETF QUIC)", func() {
|
|||
Offset: 0x42,
|
||||
Data: []byte("foobar"),
|
||||
}
|
||||
Expect(f.MinLength(versionIETFFrames)).To(Equal(1 + utils.VarIntLen(0x1337) + utils.VarIntLen(0x42)))
|
||||
Expect(f.Length(versionIETFFrames)).To(Equal(1 + utils.VarIntLen(0x1337) + utils.VarIntLen(0x42) + 6))
|
||||
})
|
||||
|
||||
It("has the right length for a frame with data length", func() {
|
||||
|
@ -205,7 +205,7 @@ var _ = Describe("STREAM frame (for IETF QUIC)", func() {
|
|||
DataLenPresent: true,
|
||||
Data: []byte("foobar"),
|
||||
}
|
||||
Expect(f.MinLength(versionIETFFrames)).To(Equal(1 + utils.VarIntLen(0x1337) + utils.VarIntLen(0x1234567) + utils.VarIntLen(6)))
|
||||
Expect(f.Length(versionIETFFrames)).To(Equal(1 + utils.VarIntLen(0x1337) + utils.VarIntLen(0x1234567) + utils.VarIntLen(6) + 6))
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -223,8 +223,8 @@ var _ = Describe("STREAM frame (for IETF QUIC)", func() {
|
|||
b.Reset()
|
||||
f.Data = nil
|
||||
maxDataLen := f.MaxDataLen(protocol.ByteCount(i), versionIETFFrames)
|
||||
if maxDataLen == 0 { // 0 means that no valid STREAM_FRAME can be written
|
||||
// check that writing a minimal size STREAM_FRAME (i.e. with 1 byte data) is actually larger than the desired size
|
||||
if maxDataLen == 0 { // 0 means that no valid STREAM frame can be written
|
||||
// check that writing a minimal size STREAM frame (i.e. with 1 byte data) is actually larger than the desired size
|
||||
f.Data = []byte{0}
|
||||
err := f.Write(b, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -251,8 +251,8 @@ var _ = Describe("STREAM frame (for IETF QUIC)", func() {
|
|||
b.Reset()
|
||||
f.Data = nil
|
||||
maxDataLen := f.MaxDataLen(protocol.ByteCount(i), versionIETFFrames)
|
||||
if maxDataLen == 0 { // 0 means that no valid STREAM_FRAME can be written
|
||||
// check that writing a minimal size STREAM_FRAME (i.e. with 1 byte data) is actually larger than the desired size
|
||||
if maxDataLen == 0 { // 0 means that no valid STREAM frame can be written
|
||||
// check that writing a minimal size STREAM frame (i.e. with 1 byte data) is actually larger than the desired size
|
||||
f.Data = []byte{0}
|
||||
err := f.Write(b, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -264,7 +264,7 @@ var _ = Describe("STREAM frame (for IETF QUIC)", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
// There's *one* pathological case, where a data length of x can be encoded into 1 byte
|
||||
// but a data lengths of x+1 needs 2 bytes
|
||||
// In that case, it's impossible to create a STREAM_FRAME of the desired size
|
||||
// In that case, it's impossible to create a STREAM frame of the desired size
|
||||
if b.Len() == i-1 {
|
||||
frameOneByteTooSmallCounter++
|
||||
continue
|
||||
|
@ -274,4 +274,118 @@ var _ = Describe("STREAM frame (for IETF QUIC)", func() {
|
|||
Expect(frameOneByteTooSmallCounter).To(Equal(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("splitting", func() {
|
||||
for _, v := range []protocol.VersionNumber{versionBigEndian, versionIETFFrames} {
|
||||
version := v
|
||||
|
||||
It("doesn't split if the frame is short enough", func() {
|
||||
f := &StreamFrame{
|
||||
StreamID: 0x1337,
|
||||
DataLenPresent: true,
|
||||
Offset: 0xdeadbeef,
|
||||
Data: make([]byte, 100),
|
||||
}
|
||||
newFrame, err := f.MaybeSplitOffFrame(f.Length(version), version)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(newFrame).To(BeNil())
|
||||
newFrame, err = f.MaybeSplitOffFrame(f.Length(version)-1, version)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(newFrame).ToNot(BeNil())
|
||||
})
|
||||
|
||||
It("keeps the data len", func() {
|
||||
f := &StreamFrame{
|
||||
StreamID: 0x1337,
|
||||
DataLenPresent: true,
|
||||
Data: make([]byte, 100),
|
||||
}
|
||||
newFrame, err := f.MaybeSplitOffFrame(66, version)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(newFrame).ToNot(BeNil())
|
||||
Expect(f.DataLenPresent).To(BeTrue())
|
||||
Expect(newFrame.DataLenPresent).To(BeTrue())
|
||||
})
|
||||
|
||||
It("adjusts the offset", func() {
|
||||
f := &StreamFrame{
|
||||
StreamID: 0x1337,
|
||||
Offset: 0x100,
|
||||
Data: []byte("foobar"),
|
||||
}
|
||||
newFrame, err := f.MaybeSplitOffFrame(f.Length(version)-3, version)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(newFrame).ToNot(BeNil())
|
||||
Expect(newFrame.Offset).To(Equal(protocol.ByteCount(0x100)))
|
||||
Expect(newFrame.Data).To(Equal([]byte("foo")))
|
||||
Expect(f.Offset).To(Equal(protocol.ByteCount(0x100 + 3)))
|
||||
Expect(f.Data).To(Equal([]byte("bar")))
|
||||
})
|
||||
|
||||
It("preserves the FIN bit", func() {
|
||||
f := &StreamFrame{
|
||||
StreamID: 0x1337,
|
||||
FinBit: true,
|
||||
Offset: 0xdeadbeef,
|
||||
Data: make([]byte, 100),
|
||||
}
|
||||
newFrame, err := f.MaybeSplitOffFrame(50, version)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(newFrame).ToNot(BeNil())
|
||||
Expect(newFrame.Offset).To(BeNumerically("<", f.Offset))
|
||||
Expect(f.FinBit).To(BeTrue())
|
||||
Expect(newFrame.FinBit).To(BeFalse())
|
||||
})
|
||||
|
||||
It("produces frames of the correct length, without data len", func() {
|
||||
const size = 1000
|
||||
f := &StreamFrame{
|
||||
StreamID: 0xdecafbad,
|
||||
Offset: 0x1234,
|
||||
Data: []byte{0},
|
||||
}
|
||||
minFrameSize := f.Length(version)
|
||||
for i := protocol.ByteCount(0); i < minFrameSize; i++ {
|
||||
_, err := f.MaybeSplitOffFrame(i, version)
|
||||
Expect(err).To(HaveOccurred())
|
||||
}
|
||||
for i := minFrameSize; i < size; i++ {
|
||||
f.Data = make([]byte, size)
|
||||
newFrame, err := f.MaybeSplitOffFrame(i, version)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(newFrame.Length(version)).To(Equal(i))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
It("produces frames of the correct length, with data len", func() {
|
||||
const size = 1000
|
||||
f := &StreamFrame{
|
||||
StreamID: 0xdecafbad,
|
||||
Offset: 0x1234,
|
||||
DataLenPresent: true,
|
||||
Data: []byte{0},
|
||||
}
|
||||
minFrameSize := f.Length(versionIETFFrames)
|
||||
for i := protocol.ByteCount(0); i < minFrameSize; i++ {
|
||||
_, err := f.MaybeSplitOffFrame(i, versionIETFFrames)
|
||||
Expect(err).To(HaveOccurred())
|
||||
}
|
||||
var frameOneByteTooSmallCounter int
|
||||
for i := minFrameSize; i < size; i++ {
|
||||
f.Data = make([]byte, size)
|
||||
newFrame, err := f.MaybeSplitOffFrame(i, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
// There's *one* pathological case, where a data length of x can be encoded into 1 byte
|
||||
// but a data lengths of x+1 needs 2 bytes
|
||||
// In that case, it's impossible to create a STREAM frame of the desired size
|
||||
if newFrame.Length(versionIETFFrames) == i-1 {
|
||||
frameOneByteTooSmallCounter++
|
||||
continue
|
||||
}
|
||||
Expect(newFrame.Length(versionIETFFrames)).To(Equal(i))
|
||||
}
|
||||
Expect(frameOneByteTooSmallCounter).To(Equal(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -31,7 +31,7 @@ func (f *StreamIDBlockedFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber)
|
|||
return nil
|
||||
}
|
||||
|
||||
// MinLength of a written frame
|
||||
func (f *StreamIDBlockedFrame) MinLength(_ protocol.VersionNumber) protocol.ByteCount {
|
||||
// Length of a written frame
|
||||
func (f *StreamIDBlockedFrame) Length(_ protocol.VersionNumber) protocol.ByteCount {
|
||||
return 1 + utils.VarIntLen(uint64(f.StreamID))
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ var _ = Describe("STREAM_ID_BLOCKED frame", func() {
|
|||
|
||||
It("has the correct min length", func() {
|
||||
frame := StreamIDBlockedFrame{StreamID: 0x123456}
|
||||
Expect(frame.MinLength(0)).To(Equal(protocol.ByteCount(1) + utils.VarIntLen(0x123456)))
|
||||
Expect(frame.Length(0)).To(Equal(protocol.ByteCount(1) + utils.VarIntLen(0x123456)))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -56,14 +56,14 @@ var _ = Describe("WINDOW_UPDATE frame", func() {
|
|||
f := &MaxDataFrame{
|
||||
ByteOffset: 0xdeadbeef,
|
||||
}
|
||||
Expect(f.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(1 + 4 + 8)))
|
||||
Expect(f.Length(versionBigEndian)).To(Equal(protocol.ByteCount(1 + 4 + 8)))
|
||||
})
|
||||
|
||||
It("has the proper min length for the connection-level WINDOW_UPDATE frame", func() {
|
||||
f := &MaxDataFrame{
|
||||
ByteOffset: 0xdeadbeef,
|
||||
}
|
||||
Expect(f.MinLength(versionBigEndian)).To(Equal(protocol.ByteCount(1 + 4 + 8)))
|
||||
Expect(f.Length(versionBigEndian)).To(Equal(protocol.ByteCount(1 + 4 + 8)))
|
||||
})
|
||||
|
||||
Context("in big endian", func() {
|
||||
|
|
|
@ -230,23 +230,23 @@ func (p *packetPacker) composeNextPacket(
|
|||
// STOP_WAITING and ACK will always fit
|
||||
if p.ackFrame != nil { // ACKs need to go first, so that the sentPacketHandler will recognize them
|
||||
payloadFrames = append(payloadFrames, p.ackFrame)
|
||||
l := p.ackFrame.MinLength(p.version)
|
||||
l := p.ackFrame.Length(p.version)
|
||||
payloadLength += l
|
||||
}
|
||||
if p.stopWaiting != nil { // a STOP_WAITING will only be queued when using gQUIC
|
||||
payloadFrames = append(payloadFrames, p.stopWaiting)
|
||||
payloadLength += p.stopWaiting.MinLength(p.version)
|
||||
payloadLength += p.stopWaiting.Length(p.version)
|
||||
}
|
||||
|
||||
p.controlFrameMutex.Lock()
|
||||
for len(p.controlFrames) > 0 {
|
||||
frame := p.controlFrames[len(p.controlFrames)-1]
|
||||
minLength := frame.MinLength(p.version)
|
||||
if payloadLength+minLength > maxFrameSize {
|
||||
length := frame.Length(p.version)
|
||||
if payloadLength+length > maxFrameSize {
|
||||
break
|
||||
}
|
||||
payloadFrames = append(payloadFrames, frame)
|
||||
payloadLength += minLength
|
||||
payloadLength += length
|
||||
p.controlFrames = p.controlFrames[:len(p.controlFrames)-1]
|
||||
}
|
||||
p.controlFrameMutex.Unlock()
|
||||
|
|
|
@ -345,7 +345,7 @@ var _ = Describe("Packet packer", func() {
|
|||
|
||||
It("packs a lot of control frames into 2 packets if they don't fit into one", func() {
|
||||
blockedFrame := &wire.BlockedFrame{}
|
||||
maxFramesPerPacket := int(maxFrameSize) / int(blockedFrame.MinLength(packer.version))
|
||||
maxFramesPerPacket := int(maxFrameSize) / int(blockedFrame.Length(packer.version))
|
||||
var controlFrames []wire.Frame
|
||||
for i := 0; i < maxFramesPerPacket+10; i++ {
|
||||
controlFrames = append(controlFrames, blockedFrame)
|
||||
|
@ -445,7 +445,7 @@ var _ = Describe("Packet packer", func() {
|
|||
StreamID: 5,
|
||||
DataLenPresent: true,
|
||||
}
|
||||
f.Data = bytes.Repeat([]byte{'f'}, int(maxSize-f.MinLength(packer.version)))
|
||||
f.Data = bytes.Repeat([]byte{'f'}, int(maxSize-f.Length(packer.version)))
|
||||
return []*wire.StreamFrame{f}
|
||||
})
|
||||
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any())
|
||||
|
@ -468,7 +468,7 @@ var _ = Describe("Packet packer", func() {
|
|||
StreamID: 5,
|
||||
DataLenPresent: true,
|
||||
}
|
||||
f.Data = bytes.Repeat([]byte{'f'}, int(maxSize-f.MinLength(packer.version)))
|
||||
f.Data = bytes.Repeat([]byte{'f'}, int(maxSize-f.Length(packer.version)))
|
||||
return []*wire.StreamFrame{f}
|
||||
})
|
||||
mockStreamFramer.EXPECT().PopStreamFrames(gomock.Any())
|
||||
|
|
|
@ -81,22 +81,24 @@ func (f *streamFramer) maybePopFramesForRetransmission(maxTotalLen protocol.Byte
|
|||
frame := f.retransmissionQueue[0]
|
||||
frame.DataLenPresent = true
|
||||
|
||||
frameHeaderLen := frame.MinLength(f.version) // can never error
|
||||
maxLen := maxTotalLen - currentLen
|
||||
if frameHeaderLen+frame.DataLen() > maxLen && maxLen < protocol.MinStreamFrameSize {
|
||||
if frame.Length(f.version) > maxLen && maxLen < protocol.MinStreamFrameSize {
|
||||
break
|
||||
}
|
||||
|
||||
splitFrame := maybeSplitOffFrame(frame, maxLen-frameHeaderLen)
|
||||
if splitFrame != nil { // StreamFrame was split
|
||||
splitFrame, err := frame.MaybeSplitOffFrame(maxLen, f.version)
|
||||
if err != nil { // maxLen is too small. Can't split frame
|
||||
break
|
||||
}
|
||||
if splitFrame != nil { // frame was split
|
||||
res = append(res, splitFrame)
|
||||
currentLen += frameHeaderLen + splitFrame.DataLen()
|
||||
currentLen += splitFrame.Length(f.version)
|
||||
break
|
||||
}
|
||||
|
||||
f.retransmissionQueue = f.retransmissionQueue[1:]
|
||||
res = append(res, frame)
|
||||
currentLen += frameHeaderLen + frame.DataLen()
|
||||
currentLen += frame.Length(f.version)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -131,28 +133,8 @@ func (f *streamFramer) maybePopNormalFrames(maxTotalLen protocol.ByteCount) []*w
|
|||
continue
|
||||
}
|
||||
frames = append(frames, frame)
|
||||
currentLen += frame.MinLength(f.version) + frame.DataLen()
|
||||
currentLen += frame.Length(f.version)
|
||||
}
|
||||
f.streamQueueMutex.Unlock()
|
||||
return frames
|
||||
}
|
||||
|
||||
// maybeSplitOffFrame removes the first n bytes and returns them as a separate frame. If n >= len(frame), nil is returned and nothing is modified.
|
||||
func maybeSplitOffFrame(frame *wire.StreamFrame, n protocol.ByteCount) *wire.StreamFrame {
|
||||
if n >= frame.DataLen() {
|
||||
return nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
frame.Data = frame.Data[n:]
|
||||
frame.Offset += n
|
||||
}()
|
||||
|
||||
return &wire.StreamFrame{
|
||||
FinBit: false,
|
||||
StreamID: frame.StreamID,
|
||||
Offset: frame.Offset,
|
||||
Data: frame.Data[:n],
|
||||
DataLenPresent: frame.DataLenPresent,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -268,46 +268,11 @@ var _ = Describe("Stream Framer", func() {
|
|||
})
|
||||
|
||||
Context("splitting of frames", func() {
|
||||
It("splits off nothing", func() {
|
||||
f := &wire.StreamFrame{
|
||||
StreamID: 1,
|
||||
Data: []byte("bar"),
|
||||
Offset: 3,
|
||||
}
|
||||
Expect(maybeSplitOffFrame(f, 1000)).To(BeNil())
|
||||
Expect(f.Offset).To(Equal(protocol.ByteCount(3)))
|
||||
Expect(f.Data).To(Equal([]byte("bar")))
|
||||
})
|
||||
|
||||
It("splits off initial frame", func() {
|
||||
f := &wire.StreamFrame{
|
||||
StreamID: 1,
|
||||
Data: []byte("foobar"),
|
||||
DataLenPresent: true,
|
||||
Offset: 3,
|
||||
FinBit: true,
|
||||
}
|
||||
previous := maybeSplitOffFrame(f, 3)
|
||||
Expect(previous).ToNot(BeNil())
|
||||
Expect(previous.StreamID).To(Equal(protocol.StreamID(1)))
|
||||
Expect(previous.Data).To(Equal([]byte("foo")))
|
||||
Expect(previous.DataLenPresent).To(BeTrue())
|
||||
Expect(previous.Offset).To(Equal(protocol.ByteCount(3)))
|
||||
Expect(previous.FinBit).To(BeFalse())
|
||||
Expect(f.StreamID).To(Equal(protocol.StreamID(1)))
|
||||
Expect(f.Data).To(Equal([]byte("bar")))
|
||||
Expect(f.DataLenPresent).To(BeTrue())
|
||||
Expect(f.Offset).To(Equal(protocol.ByteCount(6)))
|
||||
Expect(f.FinBit).To(BeTrue())
|
||||
})
|
||||
|
||||
It("splits a frame", func() {
|
||||
frame := &wire.StreamFrame{Data: bytes.Repeat([]byte{0}, 600)}
|
||||
framer.AddFrameForRetransmission(frame)
|
||||
framer.AddFrameForRetransmission(&wire.StreamFrame{Data: make([]byte, 600)})
|
||||
fs := framer.PopStreamFrames(500)
|
||||
Expect(fs).To(HaveLen(1))
|
||||
minLength := fs[0].MinLength(framer.version)
|
||||
Expect(minLength + fs[0].DataLen()).To(Equal(protocol.ByteCount(500)))
|
||||
Expect(fs[0].Length(framer.version)).To(Equal(protocol.ByteCount(500)))
|
||||
Expect(framer.retransmissionQueue[0].Data).To(HaveLen(int(600 - fs[0].DataLen())))
|
||||
Expect(framer.retransmissionQueue[0].Offset).To(Equal(fs[0].DataLen()))
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue