add tests for packet unpacker and fix a couple of bugs :)

This commit is contained in:
Lucas Clemente 2016-04-20 22:13:56 +02:00
parent 7efc7f79d2
commit b3e88f8019
2 changed files with 136 additions and 9 deletions

View file

@ -38,22 +38,22 @@ func (u *packetUnpacker) Unpack(publicHeaderBinary []byte, publicHeader *PublicH
fs := []frames.Frame{} fs := []frames.Frame{}
// Read all frames in the packet // Read all frames in the packet
ReadLoop:
for r.Len() > 0 { for r.Len() > 0 {
typeByte, _ := r.ReadByte() typeByte, _ := r.ReadByte()
r.UnreadByte() r.UnreadByte()
var frame frames.Frame var frame frames.Frame
err = nil
if typeByte&0x80 == 0x80 { if typeByte&0x80 == 0x80 {
frame, err = frames.ParseStreamFrame(r) frame, err = frames.ParseStreamFrame(r)
} else if typeByte&0xca == 0x40 { } else if typeByte&0xc0 == 0x40 {
frame, err = frames.ParseAckFrame(r) frame, err = frames.ParseAckFrame(r)
} else if typeByte&0xe0 == 0x20 { } else if typeByte&0xe0 == 0x20 {
err = errors.New("unimplemented: CONGESTION_FEEDBACK") err = errors.New("unimplemented: CONGESTION_FEEDBACK")
} else { } else {
switch typeByte { switch typeByte {
case 0x0: // PAD, end of frames case 0x0: // PAD, end of frames
break break ReadLoop
case 0x01: case 0x01:
frame, err = frames.ParseRstStreamFrame(r) frame, err = frames.ParseRstStreamFrame(r)
case 0x02: case 0x02:
@ -64,10 +64,12 @@ func (u *packetUnpacker) Unpack(publicHeaderBinary []byte, publicHeader *PublicH
fmt.Println("unimplemented: WINDOW_UPDATE") fmt.Println("unimplemented: WINDOW_UPDATE")
p := make([]byte, 1+4+8) p := make([]byte, 1+4+8)
_, err = r.Read(p) _, err = r.Read(p)
frame = nil
case 0x05: case 0x05:
fmt.Println("unimplemented: BLOCKED") fmt.Println("unimplemented: BLOCKED")
p := make([]byte, 1+4) p := make([]byte, 1+4)
_, err = r.Read(p) _, err = r.Read(p)
frame = nil
case 0x06: case 0x06:
frame, err = frames.ParseStopWaitingFrame(r, publicHeader.PacketNumberLen) frame, err = frames.ParseStopWaitingFrame(r, publicHeader.PacketNumberLen)
case 0x07: case 0x07:
@ -81,8 +83,11 @@ func (u *packetUnpacker) Unpack(publicHeaderBinary []byte, publicHeader *PublicH
if err != nil { if err != nil {
return nil, err return nil, err
} }
// TODO: Remove once all frames are implemented
if frame != nil {
fs = append(fs, frame) fs = append(fs, frame)
} }
}
return &unpackedPacket{ return &unpackedPacket{
entropyBit: entropyBit, entropyBit: entropyBit,

View file

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"github.com/lucas-clemente/quic-go/crypto" "github.com/lucas-clemente/quic-go/crypto"
"github.com/lucas-clemente/quic-go/frames"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
@ -16,29 +17,150 @@ var _ = Describe("Packet unpacker", func() {
hdrBin []byte hdrBin []byte
aead crypto.AEAD aead crypto.AEAD
r *bytes.Reader r *bytes.Reader
buf *bytes.Buffer
) )
BeforeEach(func() { BeforeEach(func() {
aead = &crypto.NullAEAD{} aead = &crypto.NullAEAD{}
hdr = &PublicHeader{ hdr = &PublicHeader{
PacketNumber: 1, PacketNumber: 1,
PacketNumberLen: 1,
} }
hdrBin = []byte{0x04, 0x4c, 0x01} hdrBin = []byte{0x04, 0x4c, 0x01}
unpacker = &packetUnpacker{aead: aead} unpacker = &packetUnpacker{aead: aead}
r = nil r = nil
buf = &bytes.Buffer{}
}) })
setReader := func(data []byte) { setReader := func(data []byte) {
var b bytes.Buffer r = bytes.NewReader(aead.Seal(0, hdrBin, append([]byte{0x01}, data...)))
b.Write(aead.Seal(0, hdrBin, data))
r = bytes.NewReader(b.Bytes())
} }
It("unpacks empty packets", func() { It("unpacks empty packets", func() {
setReader([]byte{0x01}) setReader(nil)
packet, err := unpacker.Unpack(hdrBin, hdr, r) packet, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(packet.entropyBit).To(BeTrue()) Expect(packet.entropyBit).To(BeTrue())
Expect(packet.frames).To(HaveLen(0)) Expect(packet.frames).To(HaveLen(0))
}) })
It("unpacks stream frames", func() {
f := &frames.StreamFrame{
StreamID: 1,
Data: []byte("foobar"),
}
err := f.Write(buf)
Expect(err).ToNot(HaveOccurred())
setReader(buf.Bytes())
packet, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).ToNot(HaveOccurred())
Expect(packet.frames).To(Equal([]frames.Frame{f}))
})
It("unpacks ack frames", func() {
f := &frames.AckFrame{
LargestObserved: 1,
DelayTime: 1,
}
err := f.Write(buf)
Expect(err).ToNot(HaveOccurred())
setReader(buf.Bytes())
packet, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).ToNot(HaveOccurred())
Expect(packet.frames).To(Equal([]frames.Frame{f}))
})
It("unpacks ack frames", func() {
f := &frames.AckFrame{
LargestObserved: 1,
DelayTime: 1,
}
err := f.Write(buf)
Expect(err).ToNot(HaveOccurred())
setReader(buf.Bytes())
packet, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).ToNot(HaveOccurred())
Expect(packet.frames).To(Equal([]frames.Frame{f}))
})
It("errors on CONGESTION_FEEDBACK frames", func() {
setReader([]byte{0x20})
_, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).To(MatchError("unimplemented: CONGESTION_FEEDBACK"))
})
It("handles pad frames", func() {
setReader([]byte{0, 0, 0})
packet, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).ToNot(HaveOccurred())
Expect(packet.frames).To(HaveLen(0))
})
It("unpacks RST_STREAM frames", func() {
setReader([]byte{0x01, 0xEF, 0xBE, 0xAD, 0xDE, 0x44, 0x33, 0x22, 0x11, 0xAD, 0xFB, 0xCA, 0xDE, 0x34, 0x12, 0x37, 0x13})
packet, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).ToNot(HaveOccurred())
Expect(packet.frames).To(Equal([]frames.Frame{
&frames.RstStreamFrame{
StreamID: 0xDEADBEEF,
ByteOffset: 0xDECAFBAD11223344,
ErrorCode: 0x13371234,
},
}))
})
It("unpacks CONNECTION_CLOSE frames", func() {
f := &frames.ConnectionCloseFrame{ReasonPhrase: "foo"}
err := f.Write(buf)
Expect(err).ToNot(HaveOccurred())
setReader(buf.Bytes())
packet, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).ToNot(HaveOccurred())
Expect(packet.frames).To(Equal([]frames.Frame{f}))
})
It("errors on GOAWAY frames", func() {
setReader([]byte{0x03})
_, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).To(MatchError("unimplemented: GOAWAY"))
})
It("accepts WINDOW_UPDATE frames", func() {
setReader([]byte{0x04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
packet, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).ToNot(HaveOccurred())
Expect(packet.frames).To(HaveLen(0))
})
It("accepts BLOCKED frames", func() {
setReader([]byte{0x05, 0, 0, 0, 0})
packet, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).ToNot(HaveOccurred())
Expect(packet.frames).To(HaveLen(0))
})
It("unpacks STOP_WAITING frames", func() {
setReader([]byte{0x06, 0xA4, 0x03})
packet, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).ToNot(HaveOccurred())
Expect(packet.frames).To(Equal([]frames.Frame{
&frames.StopWaitingFrame{
Entropy: 0xA4,
LeastUnackedDelta: 0x03,
},
}))
})
It("accepts PING frames", func() {
setReader([]byte{0x07})
packet, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).ToNot(HaveOccurred())
Expect(packet.frames).To(HaveLen(0))
})
It("errors on invalid type", func() {
setReader([]byte{0x08})
_, err := unpacker.Unpack(hdrBin, hdr, r)
Expect(err).To(MatchError("unknown type byte 0x8"))
})
}) })