From 6be70bc29cbdb25b48cf0f1c4cd3d0eadd086bcd Mon Sep 17 00:00:00 2001 From: Lucas Clemente Date: Wed, 20 Apr 2016 15:06:10 +0200 Subject: [PATCH] add Frame.MaxLength and implement it for currently needed frames --- frames/ack_frame.go | 12 +++++++++++- frames/ack_frame_test.go | 27 +++++++++++++++++++++++++++ frames/connection_close_frame.go | 5 +++++ frames/connection_close_frame_test.go | 10 ++++++++++ frames/frame.go | 1 + frames/stream_frame.go | 5 +++++ frames/stream_frame_test.go | 11 +++++++++++ 7 files changed, 70 insertions(+), 1 deletion(-) diff --git a/frames/ack_frame.go b/frames/ack_frame.go index 775628c89..388a01607 100644 --- a/frames/ack_frame.go +++ b/frames/ack_frame.go @@ -65,6 +65,16 @@ func (f *AckFrame) Write(b *bytes.Buffer) error { return nil } +// MaxLength of a written frame +func (f *AckFrame) MaxLength() int { + l := 1 + 1 + 6 + 2 + 1 + 1 + 4 + l += (1 + 2) * 0 /* TODO: num_timestamps */ + if f.HasNACK() { + l += 1 + (6+1)*len(f.NackRanges) + } + return l +} + // HasNACK returns if the frame has NACK ranges func (f *AckFrame) HasNACK() bool { if len(f.NackRanges) > 0 { @@ -180,7 +190,7 @@ func ParseAckFrame(r *bytes.Reader) (*AckFrame, error) { nackRange.FirstPacketNumber = frame.LargestObserved - protocol.PacketNumber(missingPacketSequenceNumberDelta+uint64(rangeLength)) } else { if missingPacketSequenceNumberDelta == 0 { - return nil, errors.New("ACK frame: Continues NACK ranges not yet implemented.") + return nil, errors.New("ACK frame: Continues NACK ranges not yet implemented") } lastNackRange := frame.NackRanges[len(frame.NackRanges)-1] nackRange.FirstPacketNumber = lastNackRange.FirstPacketNumber - protocol.PacketNumber(missingPacketSequenceNumberDelta+uint64(rangeLength)) - 1 diff --git a/frames/ack_frame_test.go b/frames/ack_frame_test.go index 79cbee0be..b677388c2 100644 --- a/frames/ack_frame_test.go +++ b/frames/ack_frame_test.go @@ -163,6 +163,33 @@ var _ = Describe("AckFrame", func() { Expect(packetNumber1).To(BeEquivalentTo([]byte{1, 0, 0, 0, 0, 0})) Expect(packetNumber2).To(BeEquivalentTo([]byte{1, 0, 0, 0, 0, 0})) }) + + It("has proper max length", func() { + b := &bytes.Buffer{} + f := &AckFrame{ + Entropy: 2, + LargestObserved: 1, + } + f.Write(b) + Expect(f.MaxLength()).To(Equal(b.Len())) + }) + + It("has proper max length with nack ranges", func() { + b := &bytes.Buffer{} + f := &AckFrame{ + Entropy: 2, + LargestObserved: 4, + NackRanges: []NackRange{ + NackRange{ + FirstPacketNumber: 2, + Length: 1, + }, + }, + } + err := f.Write(b) + Expect(err).ToNot(HaveOccurred()) + Expect(f.MaxLength()).To(Equal(b.Len())) + }) }) Context("self-consistency checks", func() { diff --git a/frames/connection_close_frame.go b/frames/connection_close_frame.go index d61497cb9..faa1b3059 100644 --- a/frames/connection_close_frame.go +++ b/frames/connection_close_frame.go @@ -46,6 +46,11 @@ func ParseConnectionCloseFrame(r *bytes.Reader) (*ConnectionCloseFrame, error) { return frame, nil } +// MaxLength of a written frame +func (f *ConnectionCloseFrame) MaxLength() int { + return 1 + 4 + 2 + len(f.ReasonPhrase) +} + // Write writes an CONNECTION_CLOSE frame. func (f *ConnectionCloseFrame) Write(b *bytes.Buffer) error { b.WriteByte(0x02) diff --git a/frames/connection_close_frame_test.go b/frames/connection_close_frame_test.go index 9cce4e17b..8ec7bc40c 100644 --- a/frames/connection_close_frame_test.go +++ b/frames/connection_close_frame_test.go @@ -70,6 +70,16 @@ var _ = Describe("ConnectionCloseFrame", func() { err := frame.Write(b) Expect(err).To(HaveOccurred()) }) + + It("has proper max length", func() { + b := &bytes.Buffer{} + f := &ConnectionCloseFrame{ + ErrorCode: 0xDEADBEEF, + ReasonPhrase: "foobar", + } + f.Write(b) + Expect(f.MaxLength()).To(Equal(b.Len())) + }) }) It("is self-consistent", func() { diff --git a/frames/frame.go b/frames/frame.go index 44a4f1277..43a17bc8d 100644 --- a/frames/frame.go +++ b/frames/frame.go @@ -5,4 +5,5 @@ import "bytes" // A Frame in QUIC type Frame interface { Write(b *bytes.Buffer) error + MaxLength() int } diff --git a/frames/stream_frame.go b/frames/stream_frame.go index d7f5fc9cd..7f5679fb6 100644 --- a/frames/stream_frame.go +++ b/frames/stream_frame.go @@ -88,3 +88,8 @@ func (f *StreamFrame) Write(b *bytes.Buffer) error { b.Write(f.Data) return nil } + +// MaxLength of a written frame +func (f *StreamFrame) MaxLength() int { + return 1 + 4 + 8 + 2 + 1 +} diff --git a/frames/stream_frame_test.go b/frames/stream_frame_test.go index 391a47a1e..8c32dbc9a 100644 --- a/frames/stream_frame_test.go +++ b/frames/stream_frame_test.go @@ -51,6 +51,17 @@ var _ = Describe("StreamFrame", func() { }).Write(b) Expect(b.Bytes()).To(Equal([]byte{0xbf, 0x1, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'})) }) + + It("has proper max length", func() { + b := &bytes.Buffer{} + f := &StreamFrame{ + StreamID: 1, + Data: []byte("f"), + Offset: 1, + } + f.Write(b) + Expect(f.MaxLength()).To(Equal(b.Len())) + }) }) }) })