mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 20:57:36 +03:00
refactor packet unpacking
This replaces version.UsesMaxDataFrame by versoin.UsesIETFFrameFormat. That way, we can have two separate code paths in the unpacker to unpack either gQUIC frames or IETF frames.
This commit is contained in:
parent
0ac728f96e
commit
759b0d87b1
15 changed files with 429 additions and 347 deletions
|
@ -54,19 +54,16 @@ var _ = Describe("Packet unpacker", func() {
|
|||
data, _ = unpacker.aead.(*mockAEAD).Seal(nil, p, 0, hdrBin)
|
||||
}
|
||||
|
||||
It("does not read read a private flag for QUIC Version >= 34", func() {
|
||||
f := &wire.ConnectionCloseFrame{ReasonPhrase: "foo"}
|
||||
err := f.Write(buf, 0)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
It("errors if the packet doesn't contain any payload", func() {
|
||||
setData(nil)
|
||||
_, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).To(MatchError(qerr.MissingPayload))
|
||||
})
|
||||
|
||||
It("saves the encryption level", func() {
|
||||
unpacker.version = versionGQUICFrames
|
||||
f := &wire.ConnectionCloseFrame{ReasonPhrase: "foo"}
|
||||
err := f.Write(buf, 0)
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
unpacker.aead.(*mockAEAD).encLevelOpen = protocol.EncryptionSecure
|
||||
|
@ -75,85 +72,247 @@ var _ = Describe("Packet unpacker", func() {
|
|||
Expect(packet.encryptionLevel).To(Equal(protocol.EncryptionSecure))
|
||||
})
|
||||
|
||||
It("unpacks ACK frames", func() {
|
||||
unpacker.version = protocol.VersionWhatever
|
||||
f := &wire.AckFrame{
|
||||
LargestAcked: 0x13,
|
||||
LowestAcked: 1,
|
||||
}
|
||||
err := f.Write(buf, protocol.VersionWhatever)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(HaveLen(1))
|
||||
readFrame := packet.frames[0].(*wire.AckFrame)
|
||||
Expect(readFrame).ToNot(BeNil())
|
||||
Expect(readFrame.LargestAcked).To(Equal(protocol.PacketNumber(0x13)))
|
||||
})
|
||||
|
||||
It("handles PADDING frames", func() {
|
||||
setData([]byte{0, 0, 0}) // 3 bytes PADDING
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("handles PADDING between two other frames", func() {
|
||||
f := &wire.PingFrame{}
|
||||
err := f.Write(buf, protocol.VersionWhatever)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = buf.Write(bytes.Repeat([]byte{0}, 10)) // 10 bytes PADDING
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
err = f.Write(buf, protocol.VersionWhatever)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(HaveLen(2))
|
||||
})
|
||||
|
||||
It("unpacks RST_STREAM frames", func() {
|
||||
f := &wire.RstStreamFrame{
|
||||
StreamID: 0xdeadbeef,
|
||||
ByteOffset: 0xdecafbad11223344,
|
||||
ErrorCode: 0x13371234,
|
||||
}
|
||||
err := f.Write(buf, protocol.VersionWhatever)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks CONNECTION_CLOSE frames", func() {
|
||||
f := &wire.ConnectionCloseFrame{ReasonPhrase: "foo"}
|
||||
err := f.Write(buf, protocol.VersionWhatever)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks GOAWAY frames", func() {
|
||||
f := &wire.GoawayFrame{
|
||||
ErrorCode: 1,
|
||||
LastGoodStream: 2,
|
||||
ReasonPhrase: "foo",
|
||||
}
|
||||
err := f.Write(buf, 0)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
Context("flow control frames, when the crypto stream is stream 0", func() {
|
||||
Context("for gQUIC frames", func() {
|
||||
BeforeEach(func() {
|
||||
unpacker.version = versionCryptoStream0
|
||||
unpacker.version = versionGQUICFrames
|
||||
})
|
||||
|
||||
It("handles PADDING frames", func() {
|
||||
setData([]byte{0, 0, 0}) // 3 bytes PADDING
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("handles PADDING between two other frames", func() {
|
||||
f := &wire.PingFrame{}
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = buf.Write(bytes.Repeat([]byte{0}, 10)) // 10 bytes PADDING
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
err = f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(HaveLen(2))
|
||||
})
|
||||
|
||||
It("unpacks RST_STREAM frames", func() {
|
||||
f := &wire.RstStreamFrame{
|
||||
StreamID: 0xdeadbeef,
|
||||
ByteOffset: 0xdecafbad11223344,
|
||||
ErrorCode: 0x13371234,
|
||||
}
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks CONNECTION_CLOSE frames", func() {
|
||||
f := &wire.ConnectionCloseFrame{ReasonPhrase: "foo"}
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks GOAWAY frames", func() {
|
||||
f := &wire.GoawayFrame{
|
||||
ErrorCode: 1,
|
||||
LastGoodStream: 2,
|
||||
ReasonPhrase: "foo",
|
||||
}
|
||||
err := f.Write(buf, 0)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks a stream-level WINDOW_UPDATE frame", func() {
|
||||
f := &wire.MaxStreamDataFrame{
|
||||
StreamID: 0xdeadbeef,
|
||||
ByteOffset: 0xcafe000000001337,
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks a connection-level WINDOW_UPDATE frame", func() {
|
||||
f := &wire.MaxDataFrame{
|
||||
ByteOffset: 0xcafe000000001337,
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks connection-level BLOCKED frames", func() {
|
||||
f := &wire.BlockedFrame{}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks stream-level BLOCKED frames", func() {
|
||||
f := &wire.StreamBlockedFrame{StreamID: 0xdeadbeef}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks STOP_WAITING frames", func() {
|
||||
setData([]byte{0x06, 0x03})
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{
|
||||
&wire.StopWaitingFrame{LeastUnacked: 7},
|
||||
}))
|
||||
})
|
||||
|
||||
It("unpacks PING frames", func() {
|
||||
setData([]byte{0x07})
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{
|
||||
&wire.PingFrame{},
|
||||
}))
|
||||
})
|
||||
|
||||
It("errors on invalid type", func() {
|
||||
setData([]byte{0xf})
|
||||
_, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).To(MatchError("InvalidFrameData: unknown type byte 0xf"))
|
||||
})
|
||||
|
||||
It("errors on invalid frames", func() {
|
||||
for b, e := range map[byte]qerr.ErrorCode{
|
||||
0x80: qerr.InvalidStreamData,
|
||||
0x40: qerr.InvalidAckData,
|
||||
0x01: qerr.InvalidRstStreamData,
|
||||
0x02: qerr.InvalidConnectionCloseData,
|
||||
0x03: qerr.InvalidGoawayData,
|
||||
0x04: qerr.InvalidWindowUpdateData,
|
||||
0x05: qerr.InvalidBlockedData,
|
||||
0x06: qerr.InvalidStopWaitingData,
|
||||
} {
|
||||
setData([]byte{b})
|
||||
_, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err.(*qerr.QuicError).ErrorCode).To(Equal(e))
|
||||
}
|
||||
})
|
||||
|
||||
It("unpacks ACK frames", func() {
|
||||
f := &wire.AckFrame{
|
||||
LargestAcked: 0x13,
|
||||
LowestAcked: 1,
|
||||
}
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(HaveLen(1))
|
||||
readFrame := packet.frames[0].(*wire.AckFrame)
|
||||
Expect(readFrame).ToNot(BeNil())
|
||||
Expect(readFrame.LargestAcked).To(Equal(protocol.PacketNumber(0x13)))
|
||||
})
|
||||
|
||||
Context("unpacking STREAM frames", func() {
|
||||
It("unpacks unencrypted STREAM frames on the crypto stream", func() {
|
||||
unpacker.aead.(*mockAEAD).encLevelOpen = protocol.EncryptionUnencrypted
|
||||
f := &wire.StreamFrame{
|
||||
StreamID: versionGQUICFrames.CryptoStreamID(),
|
||||
Data: []byte("foobar"),
|
||||
}
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks encrypted STREAM frames on the crypto stream", func() {
|
||||
unpacker.aead.(*mockAEAD).encLevelOpen = protocol.EncryptionSecure
|
||||
f := &wire.StreamFrame{
|
||||
StreamID: versionGQUICFrames.CryptoStreamID(),
|
||||
Data: []byte("foobar"),
|
||||
}
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("does not unpack unencrypted STREAM frames on higher streams", func() {
|
||||
unpacker.aead.(*mockAEAD).encLevelOpen = protocol.EncryptionUnencrypted
|
||||
f := &wire.StreamFrame{
|
||||
StreamID: 3,
|
||||
Data: []byte("foobar"),
|
||||
}
|
||||
err := f.Write(buf, versionGQUICFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
_, err = unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).To(MatchError(qerr.Error(qerr.UnencryptedStreamData, "received unencrypted stream data on stream 3")))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("for IETF draft frames", func() {
|
||||
BeforeEach(func() {
|
||||
unpacker.version = versionIETFFrames
|
||||
})
|
||||
|
||||
It("unpacks RST_STREAM frames", func() {
|
||||
f := &wire.RstStreamFrame{
|
||||
StreamID: 0xdeadbeef,
|
||||
ByteOffset: 0xdecafbad11223344,
|
||||
ErrorCode: 0x13371234,
|
||||
}
|
||||
err := f.Write(buf, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks CONNECTION_CLOSE frames", func() {
|
||||
f := &wire.ConnectionCloseFrame{ReasonPhrase: "foo"}
|
||||
err := f.Write(buf, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks MAX_DATA frames", func() {
|
||||
|
@ -161,7 +320,7 @@ var _ = Describe("Packet unpacker", func() {
|
|||
ByteOffset: 0xcafe000000001337,
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionCryptoStream0)
|
||||
err := f.Write(buf, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
|
@ -175,7 +334,7 @@ var _ = Describe("Packet unpacker", func() {
|
|||
ByteOffset: 0xcafe000000001337,
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionCryptoStream0)
|
||||
err := f.Write(buf, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
|
@ -186,7 +345,7 @@ var _ = Describe("Packet unpacker", func() {
|
|||
It("unpacks connection-level BLOCKED frames", func() {
|
||||
f := &wire.BlockedFrame{}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionCryptoStream0)
|
||||
err := f.Write(buf, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
|
@ -197,7 +356,7 @@ var _ = Describe("Packet unpacker", func() {
|
|||
It("unpacks stream-level BLOCKED frames", func() {
|
||||
f := &wire.StreamBlockedFrame{StreamID: 0xdeadbeef}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionCryptoStream0)
|
||||
err := f.Write(buf, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
|
@ -205,8 +364,16 @@ var _ = Describe("Packet unpacker", func() {
|
|||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("errors on invalid type", func() {
|
||||
setData([]byte{0xf})
|
||||
_, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).To(MatchError("InvalidFrameData: unknown type byte 0xf"))
|
||||
})
|
||||
|
||||
It("errors on invalid frames", func() {
|
||||
for b, e := range map[byte]qerr.ErrorCode{
|
||||
0x01: qerr.InvalidRstStreamData,
|
||||
0x02: qerr.InvalidConnectionCloseData,
|
||||
0x04: qerr.InvalidWindowUpdateData,
|
||||
0x05: qerr.InvalidWindowUpdateData,
|
||||
0x09: qerr.InvalidBlockedData,
|
||||
|
@ -217,152 +384,4 @@ var _ = Describe("Packet unpacker", func() {
|
|||
}
|
||||
})
|
||||
})
|
||||
|
||||
Context("flow control frames, when the crypto stream is stream 1", func() {
|
||||
BeforeEach(func() {
|
||||
unpacker.version = versionCryptoStream1
|
||||
})
|
||||
|
||||
It("unpacks a stream-level WINDOW_UPDATE frame", func() {
|
||||
f := &wire.MaxStreamDataFrame{
|
||||
StreamID: 0xdeadbeef,
|
||||
ByteOffset: 0xcafe000000001337,
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionCryptoStream1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks a connection-level WINDOW_UPDATE frame", func() {
|
||||
f := &wire.MaxDataFrame{
|
||||
ByteOffset: 0xcafe000000001337,
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionCryptoStream1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks connection-level BLOCKED frames", func() {
|
||||
f := &wire.BlockedFrame{}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionCryptoStream1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks stream-level BLOCKED frames", func() {
|
||||
f := &wire.StreamBlockedFrame{StreamID: 0xdeadbeef}
|
||||
buf := &bytes.Buffer{}
|
||||
err := f.Write(buf, versionCryptoStream1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("errors on invalid frames", func() {
|
||||
for b, e := range map[byte]qerr.ErrorCode{
|
||||
0x04: qerr.InvalidWindowUpdateData,
|
||||
0x05: qerr.InvalidBlockedData,
|
||||
} {
|
||||
setData([]byte{b})
|
||||
_, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err.(*qerr.QuicError).ErrorCode).To(Equal(e))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
It("unpacks STOP_WAITING frames", func() {
|
||||
setData([]byte{0x06, 0x03})
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{
|
||||
&wire.StopWaitingFrame{LeastUnacked: 7},
|
||||
}))
|
||||
})
|
||||
|
||||
It("unpacks PING frames", func() {
|
||||
setData([]byte{0x07})
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{
|
||||
&wire.PingFrame{},
|
||||
}))
|
||||
})
|
||||
|
||||
It("errors on invalid type", func() {
|
||||
setData([]byte{0xf})
|
||||
_, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).To(MatchError("InvalidFrameData: unknown type byte 0xf"))
|
||||
})
|
||||
|
||||
It("errors on invalid frames", func() {
|
||||
for b, e := range map[byte]qerr.ErrorCode{
|
||||
0x80: qerr.InvalidStreamData,
|
||||
0x40: qerr.InvalidAckData,
|
||||
0x01: qerr.InvalidRstStreamData,
|
||||
0x02: qerr.InvalidConnectionCloseData,
|
||||
0x03: qerr.InvalidGoawayData,
|
||||
0x06: qerr.InvalidStopWaitingData,
|
||||
} {
|
||||
setData([]byte{b})
|
||||
_, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err.(*qerr.QuicError).ErrorCode).To(Equal(e))
|
||||
}
|
||||
})
|
||||
|
||||
Context("unpacking STREAM frames", func() {
|
||||
It("unpacks unencrypted STREAM frames on the crypto stream", func() {
|
||||
unpacker.aead.(*mockAEAD).encLevelOpen = protocol.EncryptionUnencrypted
|
||||
f := &wire.StreamFrame{
|
||||
StreamID: unpacker.version.CryptoStreamID(),
|
||||
Data: []byte("foobar"),
|
||||
}
|
||||
err := f.Write(buf, 0)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("unpacks encrypted STREAM frames on the crypto stream", func() {
|
||||
unpacker.aead.(*mockAEAD).encLevelOpen = protocol.EncryptionSecure
|
||||
f := &wire.StreamFrame{
|
||||
StreamID: unpacker.version.CryptoStreamID(),
|
||||
Data: []byte("foobar"),
|
||||
}
|
||||
err := f.Write(buf, 0)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
packet, err := unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.frames).To(Equal([]wire.Frame{f}))
|
||||
})
|
||||
|
||||
It("does not unpack unencrypted STREAM frames on higher streams", func() {
|
||||
unpacker.aead.(*mockAEAD).encLevelOpen = protocol.EncryptionUnencrypted
|
||||
f := &wire.StreamFrame{
|
||||
StreamID: 3,
|
||||
Data: []byte("foobar"),
|
||||
}
|
||||
err := f.Write(buf, 0)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
setData(buf.Bytes())
|
||||
_, err = unpacker.Unpack(hdrBin, hdr, data)
|
||||
Expect(err).To(MatchError(qerr.Error(qerr.UnencryptedStreamData, "received unencrypted stream data on stream 3")))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue