improve frames coverage and fix a small stream frame parsing bug

ref #241
This commit is contained in:
Lucas Clemente
2016-08-02 13:11:30 +02:00
parent edc24ea795
commit b9abc5b2a1
11 changed files with 266 additions and 167 deletions

View File

@@ -135,6 +135,16 @@ var _ = Describe("AckFrame", func() {
Expect(err).To(MatchError(errInvalidNackRanges))
})
})
It("errors on EOFs", func() {
data := []byte{0x64, 0x8, 0x23, 0x03, 0x72, 0x1, 0x1, 0x0, 0xc0, 0x15, 0x0, 0x0, 0x4, 0x1, 0x8f, 0x0, 0xff, 0x1, 0x8f, 0x0, 0xff}
_, err := ParseAckFrameLegacy(bytes.NewReader(data), 0)
Expect(err).NotTo(HaveOccurred())
for i := range data {
_, err := ParseAckFrameLegacy(bytes.NewReader(data[0:i]), 0)
Expect(err).To(HaveOccurred())
}
})
})
Context("GetHighestInOrderPacket", func() {

View File

@@ -253,6 +253,16 @@ var _ = Describe("AckFrame", func() {
})
})
})
It("errors on EOFs", func() {
data := []byte{0x65, 0x66, 0x9, 0x23, 0x1, 0x7, 0x7, 0x0, 0xff, 0x0, 0x0, 0xf5, 0x8a, 0x2, 0xc8, 0xe6, 0x0, 0xff, 0x0, 0x0, 0xff, 0x0, 0x0, 0xff, 0x0, 0x0, 0x23, 0x13, 0x0, 0x2, 0x1, 0x13, 0xae, 0xb, 0x0, 0x0, 0x80, 0x5}
_, err := ParseAckFrame(bytes.NewReader(data), 0)
Expect(err).NotTo(HaveOccurred())
for i := range data {
_, err := ParseAckFrame(bytes.NewReader(data[0:i]), 0)
Expect(err).To(MatchError("EOF"))
}
})
})
Context("when writing", func() {

View File

@@ -16,6 +16,16 @@ var _ = Describe("BlockedFrame", func() {
Expect(err).ToNot(HaveOccurred())
Expect(frame.StreamID).To(Equal(protocol.StreamID(0xDEADBEEF)))
})
It("errors on EOFs", func() {
data := []byte{0x05, 0xEF, 0xBE, 0xAD, 0xDE}
_, err := ParseBlockedFrame(bytes.NewReader(data))
Expect(err).NotTo(HaveOccurred())
for i := range data {
_, err := ParseBlockedFrame(bytes.NewReader(data[0:i]))
Expect(err).To(HaveOccurred())
}
})
})
Context("when writing", func() {

View File

@@ -35,6 +35,16 @@ var _ = Describe("ConnectionCloseFrame", func() {
_, err := ParseConnectionCloseFrame(b)
Expect(err).To(MatchError(qerr.Error(qerr.InvalidConnectionCloseData, "reason phrase too long")))
})
It("errors on EOFs", func() {
data := []byte{0x40, 0x19, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x4e, 0x6f, 0x20, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e}
_, err := ParseConnectionCloseFrame(bytes.NewReader(data))
Expect(err).NotTo(HaveOccurred())
for i := range data {
_, err := ParseConnectionCloseFrame(bytes.NewReader(data[0:i]))
Expect(err).To(HaveOccurred())
}
})
})
Context("when writing", func() {

View File

@@ -40,6 +40,21 @@ var _ = Describe("GoawayFrame", func() {
_, err := ParseGoawayFrame(b)
Expect(err).To(MatchError(qerr.Error(qerr.InvalidGoawayData, "reason phrase too long")))
})
It("errors on EOFs", func() {
data := []byte{0x03,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x03, 0x00,
'f', 'o', 'o',
}
_, err := ParseGoawayFrame(bytes.NewReader(data))
Expect(err).NotTo(HaveOccurred())
for i := range data {
_, err := ParseGoawayFrame(bytes.NewReader(data[0:i]))
Expect(err).To(HaveOccurred())
}
})
})
Context("when writing", func() {

View File

@@ -16,6 +16,11 @@ var _ = Describe("PingFrame", func() {
Expect(err).ToNot(HaveOccurred())
Expect(b.Len()).To(Equal(0))
})
It("errors on EOFs", func() {
_, err := ParsePingFrame(bytes.NewReader(nil))
Expect(err).To(HaveOccurred())
})
})
Context("when writing", func() {

View File

@@ -18,6 +18,16 @@ var _ = Describe("RstStreamFrame", func() {
Expect(frame.ByteOffset).To(Equal(protocol.ByteCount(0xDECAFBAD11223344)))
Expect(frame.ErrorCode).To(Equal(uint32(0x13371234)))
})
It("errors on EOFs", func() {
data := []byte{0x01, 0xEF, 0xBE, 0xAD, 0xDE, 0x44, 0x33, 0x22, 0x11, 0xAD, 0xFB, 0xCA, 0xDE, 0x34, 0x12, 0x37, 0x13}
_, err := ParseRstStreamFrame(bytes.NewReader(data))
Expect(err).NotTo(HaveOccurred())
for i := range data {
_, err := ParseRstStreamFrame(bytes.NewReader(data[0:i]))
Expect(err).To(HaveOccurred())
}
})
})
Context("when writing", func() {

View File

@@ -9,185 +9,193 @@ import (
)
var _ = Describe("StopWaitingFrame", func() {
Context("stop waiting frames", func() {
Context("when parsing", func() {
It("accepts sample frame", func() {
b := bytes.NewReader([]byte{0x06, 0xA4, 0x03})
frame, err := ParseStopWaitingFrame(b, 5, 1, protocol.Version33)
Expect(err).ToNot(HaveOccurred())
Expect(frame.Entropy).To(Equal(byte(0xA4)))
Expect(frame.LeastUnacked).To(Equal(protocol.PacketNumber(2)))
})
Context("when parsing", func() {
It("accepts sample frame", func() {
b := bytes.NewReader([]byte{0x06, 0xA4, 0x03})
frame, err := ParseStopWaitingFrame(b, 5, 1, protocol.Version33)
Expect(err).ToNot(HaveOccurred())
Expect(frame.Entropy).To(Equal(byte(0xA4)))
Expect(frame.LeastUnacked).To(Equal(protocol.PacketNumber(2)))
})
It("rejects frames with an invalid LeastUnackedDelta", func() {
b := bytes.NewReader([]byte{0x06, 0xA4, 0xD})
_, err := ParseStopWaitingFrame(b, 10, 1, protocol.Version33)
It("rejects frames with an invalid LeastUnackedDelta", func() {
b := bytes.NewReader([]byte{0x06, 0xA4, 0xD})
_, err := ParseStopWaitingFrame(b, 10, 1, protocol.Version33)
Expect(err).To(HaveOccurred())
})
It("reads a StopWaitingFrame, for QUIC version 34", func() {
b := bytes.NewReader([]byte{0x06, 0x03})
frame, err := ParseStopWaitingFrame(b, 5, 1, protocol.Version34)
Expect(err).ToNot(HaveOccurred())
Expect(frame.LeastUnacked).To(Equal(protocol.PacketNumber(2)))
})
It("errors on EOFs", func() {
data := []byte{0x06, 0xA4, 0x03}
_, err := ParseStopWaitingFrame(bytes.NewReader(data), 5, 1, protocol.Version33)
Expect(err).NotTo(HaveOccurred())
for i := range data {
_, err := ParseStopWaitingFrame(bytes.NewReader(data[0:i]), 5, 1, protocol.Version33)
Expect(err).To(HaveOccurred())
})
}
})
})
It("reads a StopWaitingFrame, for QUIC version 34", func() {
b := bytes.NewReader([]byte{0x06, 0x03})
frame, err := ParseStopWaitingFrame(b, 5, 1, protocol.Version34)
Expect(err).ToNot(HaveOccurred())
Expect(frame.LeastUnacked).To(Equal(protocol.PacketNumber(2)))
})
Context("when writing", func() {
It("writes a sample frame", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumber: 13,
Entropy: 0xAD,
PacketNumberLen: protocol.PacketNumberLen6,
}
frame.Write(b, protocol.Version33)
Expect(b.Bytes()[0]).To(Equal(uint8(0x06)))
Expect(b.Bytes()[1]).To(Equal(uint8(frame.Entropy)))
Expect(b.Bytes()[2:8]).To(Equal([]byte{3, 0, 0, 0, 0, 0}))
})
Context("when writing", func() {
It("writes a sample frame", func() {
It("writes a sample frame, for QUIC version 34", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumber: 13,
PacketNumberLen: protocol.PacketNumberLen6,
}
frame.Write(b, protocol.Version34)
Expect(b.Bytes()[0]).To(Equal(uint8(0x06)))
Expect(b.Bytes()[1:7]).To(Equal([]byte{3, 0, 0, 0, 0, 0}))
})
It("errors when PacketNumber was not set", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumberLen: protocol.PacketNumberLen1,
Entropy: 0xAD,
}
err := frame.Write(b, 0)
Expect(err).To(MatchError(errPacketNumberNotSet))
})
It("errors when PacketNumberLen was not set", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumber: 13,
Entropy: 0xAD,
}
err := frame.Write(b, 0)
Expect(err).To(MatchError(errPacketNumberLenNotSet))
})
It("errors when the LeastUnackedDelta would be negative", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumber: 5,
PacketNumberLen: protocol.PacketNumberLen1,
}
err := frame.Write(b, 0)
Expect(err).To(MatchError(errLeastUnackedHigherThanPacketNumber))
})
Context("LeastUnackedDelta length", func() {
It("writes a 1-byte LeastUnackedDelta", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumber: 13,
Entropy: 0xAD,
PacketNumberLen: protocol.PacketNumberLen6,
}
frame.Write(b, protocol.Version33)
Expect(b.Bytes()[0]).To(Equal(uint8(0x06)))
Expect(b.Bytes()[1]).To(Equal(uint8(frame.Entropy)))
Expect(b.Bytes()[2:8]).To(Equal([]byte{3, 0, 0, 0, 0, 0}))
})
It("writes a sample frame, for QUIC version 34", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumber: 13,
PacketNumberLen: protocol.PacketNumberLen6,
}
frame.Write(b, protocol.Version34)
Expect(b.Bytes()[0]).To(Equal(uint8(0x06)))
Expect(b.Bytes()[1:7]).To(Equal([]byte{3, 0, 0, 0, 0, 0}))
})
It("errors when PacketNumber was not set", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumberLen: protocol.PacketNumberLen1,
Entropy: 0xAD,
}
err := frame.Write(b, 0)
Expect(err).To(MatchError(errPacketNumberNotSet))
})
It("errors when PacketNumberLen was not set", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumber: 13,
Entropy: 0xAD,
}
err := frame.Write(b, 0)
Expect(err).To(MatchError(errPacketNumberLenNotSet))
})
It("errors when the LeastUnackedDelta would be negative", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumber: 5,
PacketNumberLen: protocol.PacketNumberLen1,
}
err := frame.Write(b, 0)
Expect(err).To(MatchError(errLeastUnackedHigherThanPacketNumber))
})
Context("LeastUnackedDelta length", func() {
It("writes a 1-byte LeastUnackedDelta", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumber: 13,
PacketNumberLen: protocol.PacketNumberLen1,
}
frame.Write(b, 0)
Expect(b.Len()).To(Equal(3))
Expect(b.Bytes()[2]).To(Equal(uint8(3)))
})
It("writes a 2-byte LeastUnackedDelta", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 0x10,
PacketNumber: 0x1300,
PacketNumberLen: protocol.PacketNumberLen2,
}
frame.Write(b, 0)
Expect(b.Len()).To(Equal(4))
Expect(b.Bytes()[2:4]).To(Equal([]byte{0xF0, 0x12}))
})
It("writes a 4-byte LeastUnackedDelta", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 0x1000,
PacketNumber: 0x12345678,
PacketNumberLen: protocol.PacketNumberLen4,
}
frame.Write(b, 0)
Expect(b.Len()).To(Equal(6))
Expect(b.Bytes()[2:6]).To(Equal([]byte{0x78, 0x46, 0x34, 0x12}))
})
It("writes a 6-byte LeastUnackedDelta", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 0x10,
PacketNumber: 0x123456789ABC,
PacketNumberLen: protocol.PacketNumberLen6,
}
frame.Write(b, 0)
Expect(b.Len()).To(Equal(8))
Expect(b.Bytes()[2:8]).To(Equal([]byte{0xAC, 0x9A, 0x78, 0x56, 0x34, 0x12}))
})
})
})
Context("minLength", func() {
It("calculates the right minLength", func() {
for _, length := range []protocol.PacketNumberLen{protocol.PacketNumberLen1, protocol.PacketNumberLen2, protocol.PacketNumberLen4, protocol.PacketNumberLen6} {
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumberLen: length,
}
Expect(frame.MinLength(protocol.Version33)).To(Equal(protocol.ByteCount(length + 2)))
}
})
It("calculates the right minLength, for QUIC version 34", func() {
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumberLen: protocol.PacketNumberLen4,
}
Expect(frame.MinLength(protocol.Version34)).To(Equal(protocol.ByteCount(4 + 1)))
})
It("errors when packetNumberLen is not set", func() {
frame := &StopWaitingFrame{
LeastUnacked: 10,
}
_, err := frame.MinLength(0)
Expect(err).To(MatchError(errPacketNumberLenNotSet))
})
})
Context("self consistency", func() {
It("reads a stop waiting frame that it wrote", func() {
packetNumber := protocol.PacketNumber(13)
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumber: packetNumber,
Entropy: 0xAC,
PacketNumberLen: protocol.PacketNumberLen4,
}
b := &bytes.Buffer{}
frame.Write(b, 0)
readframe, err := ParseStopWaitingFrame(bytes.NewReader(b.Bytes()), packetNumber, protocol.PacketNumberLen4, protocol.Version33)
Expect(err).ToNot(HaveOccurred())
Expect(readframe.Entropy).To(Equal(frame.Entropy))
Expect(readframe.LeastUnacked).To(Equal(frame.LeastUnacked))
Expect(b.Len()).To(Equal(3))
Expect(b.Bytes()[2]).To(Equal(uint8(3)))
})
It("writes a 2-byte LeastUnackedDelta", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 0x10,
PacketNumber: 0x1300,
PacketNumberLen: protocol.PacketNumberLen2,
}
frame.Write(b, 0)
Expect(b.Len()).To(Equal(4))
Expect(b.Bytes()[2:4]).To(Equal([]byte{0xF0, 0x12}))
})
It("writes a 4-byte LeastUnackedDelta", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 0x1000,
PacketNumber: 0x12345678,
PacketNumberLen: protocol.PacketNumberLen4,
}
frame.Write(b, 0)
Expect(b.Len()).To(Equal(6))
Expect(b.Bytes()[2:6]).To(Equal([]byte{0x78, 0x46, 0x34, 0x12}))
})
It("writes a 6-byte LeastUnackedDelta", func() {
b := &bytes.Buffer{}
frame := &StopWaitingFrame{
LeastUnacked: 0x10,
PacketNumber: 0x123456789ABC,
PacketNumberLen: protocol.PacketNumberLen6,
}
frame.Write(b, 0)
Expect(b.Len()).To(Equal(8))
Expect(b.Bytes()[2:8]).To(Equal([]byte{0xAC, 0x9A, 0x78, 0x56, 0x34, 0x12}))
})
})
})
Context("minLength", func() {
It("calculates the right minLength", func() {
for _, length := range []protocol.PacketNumberLen{protocol.PacketNumberLen1, protocol.PacketNumberLen2, protocol.PacketNumberLen4, protocol.PacketNumberLen6} {
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumberLen: length,
}
Expect(frame.MinLength(protocol.Version33)).To(Equal(protocol.ByteCount(length + 2)))
}
})
It("calculates the right minLength, for QUIC version 34", func() {
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumberLen: protocol.PacketNumberLen4,
}
Expect(frame.MinLength(protocol.Version34)).To(Equal(protocol.ByteCount(4 + 1)))
})
It("errors when packetNumberLen is not set", func() {
frame := &StopWaitingFrame{
LeastUnacked: 10,
}
_, err := frame.MinLength(0)
Expect(err).To(MatchError(errPacketNumberLenNotSet))
})
})
Context("self consistency", func() {
It("reads a stop waiting frame that it wrote", func() {
packetNumber := protocol.PacketNumber(13)
frame := &StopWaitingFrame{
LeastUnacked: 10,
PacketNumber: packetNumber,
Entropy: 0xAC,
PacketNumberLen: protocol.PacketNumberLen4,
}
b := &bytes.Buffer{}
frame.Write(b, 0)
readframe, err := ParseStopWaitingFrame(bytes.NewReader(b.Bytes()), packetNumber, protocol.PacketNumberLen4, protocol.Version33)
Expect(err).ToNot(HaveOccurred())
Expect(readframe.Entropy).To(Equal(frame.Entropy))
Expect(readframe.LeastUnacked).To(Equal(frame.LeastUnacked))
})
})
})

View File

@@ -3,6 +3,7 @@ package frames
import (
"bytes"
"errors"
"io"
"io/ioutil"
"github.com/lucas-clemente/quic-go/protocol"
@@ -73,7 +74,7 @@ func ParseStreamFrame(r *bytes.Reader) (*StreamFrame, error) {
}
} else {
frame.Data = make([]byte, dataLen)
if _, err := r.Read(frame.Data); err != nil {
if _, err := io.ReadFull(r, frame.Data); err != nil {
return nil, err
}
}

View File

@@ -53,6 +53,16 @@ var _ = Describe("StreamFrame", func() {
_, err := ParseStreamFrame(b)
Expect(err).To(MatchError(qerr.Error(qerr.InvalidStreamData, "data len too large")))
})
It("errors on EOFs", func() {
data := []byte{0xa0, 0x1, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'}
_, err := ParseStreamFrame(bytes.NewReader(data))
Expect(err).NotTo(HaveOccurred())
for i := range data {
_, err := ParseStreamFrame(bytes.NewReader(data[0:i]))
Expect(err).To(HaveOccurred())
}
})
})
Context("when writing", func() {

View File

@@ -18,6 +18,16 @@ var _ = Describe("WindowUpdateFrame", func() {
Expect(frame.ByteOffset).To(Equal(protocol.ByteCount(0xDECAFBAD11223344)))
Expect(b.Len()).To(Equal(0))
})
It("errors on EOFs", func() {
data := []byte{0x04, 0xEF, 0xBE, 0xAD, 0xDE, 0x44, 0x33, 0x22, 0x11, 0xAD, 0xFB, 0xCA, 0xDE}
_, err := ParseWindowUpdateFrame(bytes.NewReader(data))
Expect(err).NotTo(HaveOccurred())
for i := range data {
_, err := ParseWindowUpdateFrame(bytes.NewReader(data[0:i]))
Expect(err).To(HaveOccurred())
}
})
})
Context("when writing", func() {