From 40650d93f0394e712eccef164516a73a8ec58f70 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 15 Dec 2017 09:53:53 +0700 Subject: [PATCH] add an application-defined error type, for RST_STREAM and STOP_SENDING --- internal/protocol/protocol.go | 3 +++ internal/wire/rst_stream_frame.go | 19 ++++++++++--------- internal/wire/rst_stream_frame_test.go | 10 +++++----- internal/wire/stop_sending_frame.go | 5 ++--- internal/wire/stop_sending_frame_test.go | 3 +-- packet_unpacker_test.go | 2 +- 6 files changed, 22 insertions(+), 20 deletions(-) diff --git a/internal/protocol/protocol.go b/internal/protocol/protocol.go index 4701d7d1..16229836 100644 --- a/internal/protocol/protocol.go +++ b/internal/protocol/protocol.go @@ -64,6 +64,9 @@ type ByteCount uint64 // MaxByteCount is the maximum value of a ByteCount const MaxByteCount = ByteCount(1<<62 - 1) +// An ApplicationErrorCode is an application-defined error code. +type ApplicationErrorCode uint16 + // MaxReceivePacketSize maximum packet size of any QUIC packet, based on // ethernet's max size, minus the IP and UDP headers. IPv6 has a 40 byte header, // UDP adds an additional 8 bytes. This is a total overhead of 48 bytes. diff --git a/internal/wire/rst_stream_frame.go b/internal/wire/rst_stream_frame.go index d659a4a0..3f65a63a 100644 --- a/internal/wire/rst_stream_frame.go +++ b/internal/wire/rst_stream_frame.go @@ -7,10 +7,12 @@ import ( "github.com/lucas-clemente/quic-go/internal/utils" ) -// A RstStreamFrame in QUIC +// A RstStreamFrame is a RST_STREAM frame in QUIC type RstStreamFrame struct { - StreamID protocol.StreamID - ErrorCode uint32 + StreamID protocol.StreamID + // The error code is a uint32 in gQUIC, but a uint16 in IETF QUIC. + // protocol.ApplicaitonErrorCode is a uint16, so larger values in gQUIC frames will be truncated. + ErrorCode protocol.ApplicationErrorCode ByteOffset protocol.ByteCount } @@ -21,7 +23,7 @@ func ParseRstStreamFrame(r *bytes.Reader, version protocol.VersionNumber) (*RstS } var streamID protocol.StreamID - var errorCode uint32 + var errorCode uint16 var byteOffset protocol.ByteCount if version.UsesIETFFrameFormat() { sid, err := utils.ReadVarInt(r) @@ -29,11 +31,10 @@ func ParseRstStreamFrame(r *bytes.Reader, version protocol.VersionNumber) (*RstS return nil, err } streamID = protocol.StreamID(sid) - ec, err := utils.BigEndian.ReadUint16(r) + errorCode, err = utils.BigEndian.ReadUint16(r) if err != nil { return nil, err } - errorCode = uint32(ec) bo, err := utils.ReadVarInt(r) if err != nil { return nil, err @@ -54,12 +55,12 @@ func ParseRstStreamFrame(r *bytes.Reader, version protocol.VersionNumber) (*RstS if err != nil { return nil, err } - errorCode = uint32(ec) + errorCode = uint16(ec) } return &RstStreamFrame{ StreamID: streamID, - ErrorCode: errorCode, + ErrorCode: protocol.ApplicationErrorCode(errorCode), ByteOffset: byteOffset, }, nil } @@ -74,7 +75,7 @@ func (f *RstStreamFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) } else { utils.BigEndian.WriteUint32(b, uint32(f.StreamID)) utils.BigEndian.WriteUint64(b, uint64(f.ByteOffset)) - utils.BigEndian.WriteUint32(b, f.ErrorCode) + utils.BigEndian.WriteUint32(b, uint32(f.ErrorCode)) } return nil } diff --git a/internal/wire/rst_stream_frame_test.go b/internal/wire/rst_stream_frame_test.go index 380c055f..207e3372 100644 --- a/internal/wire/rst_stream_frame_test.go +++ b/internal/wire/rst_stream_frame_test.go @@ -22,7 +22,7 @@ var _ = Describe("RST_STREAM frame", func() { Expect(err).ToNot(HaveOccurred()) Expect(frame.StreamID).To(Equal(protocol.StreamID(0xdeadbeef))) Expect(frame.ByteOffset).To(Equal(protocol.ByteCount(0x987654321))) - Expect(frame.ErrorCode).To(Equal(uint32(0x1337))) + Expect(frame.ErrorCode).To(Equal(protocol.ApplicationErrorCode(0x1337))) }) It("errors on EOFs", func() { @@ -44,13 +44,13 @@ var _ = Describe("RST_STREAM frame", func() { b := bytes.NewReader([]byte{0x1, 0xde, 0xad, 0xbe, 0xef, // stream id 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, // byte offset - 0x34, 0x12, 0x37, 0x13, // error code + 0x0, 0x0, 0xca, 0xfe, // error code }) frame, err := ParseRstStreamFrame(b, versionBigEndian) Expect(err).ToNot(HaveOccurred()) Expect(frame.StreamID).To(Equal(protocol.StreamID(0xdeadbeef))) Expect(frame.ByteOffset).To(Equal(protocol.ByteCount(0x8877665544332211))) - Expect(frame.ErrorCode).To(Equal(uint32(0x34123713))) + Expect(frame.ErrorCode).To(Equal(protocol.ApplicationErrorCode(0xcafe))) }) It("errors on EOFs", func() { @@ -103,7 +103,7 @@ var _ = Describe("RST_STREAM frame", func() { frame := RstStreamFrame{ StreamID: 0x1337, ByteOffset: 0x11223344decafbad, - ErrorCode: 0xdeadbeef, + ErrorCode: 0xcafe, } b := &bytes.Buffer{} err := frame.Write(b, versionBigEndian) @@ -111,7 +111,7 @@ var _ = Describe("RST_STREAM frame", func() { Expect(b.Bytes()).To(Equal([]byte{0x01, 0x0, 0x0, 0x13, 0x37, // stream id 0x11, 0x22, 0x33, 0x44, 0xde, 0xca, 0xfb, 0xad, // byte offset - 0xde, 0xad, 0xbe, 0xef, // error code + 0x0, 0x0, 0xca, 0xfe, // error code })) }) diff --git a/internal/wire/stop_sending_frame.go b/internal/wire/stop_sending_frame.go index 14156494..4cbbce9b 100644 --- a/internal/wire/stop_sending_frame.go +++ b/internal/wire/stop_sending_frame.go @@ -5,13 +5,12 @@ import ( "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/utils" - "github.com/lucas-clemente/quic-go/qerr" ) // A StopSendingFrame is a STOP_SENDING frame type StopSendingFrame struct { StreamID protocol.StreamID - ErrorCode qerr.ErrorCode + ErrorCode protocol.ApplicationErrorCode } // ParseStopSendingFrame parses a STOP_SENDING frame @@ -31,7 +30,7 @@ func ParseStopSendingFrame(r *bytes.Reader, _ protocol.VersionNumber) (*StopSend return &StopSendingFrame{ StreamID: protocol.StreamID(streamID), - ErrorCode: qerr.ErrorCode(errorCode), + ErrorCode: protocol.ApplicationErrorCode(errorCode), }, nil } diff --git a/internal/wire/stop_sending_frame_test.go b/internal/wire/stop_sending_frame_test.go index 76b9d0f4..ab942a07 100644 --- a/internal/wire/stop_sending_frame_test.go +++ b/internal/wire/stop_sending_frame_test.go @@ -5,7 +5,6 @@ import ( "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/utils" - "github.com/lucas-clemente/quic-go/qerr" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -21,7 +20,7 @@ var _ = Describe("STOP_SENDING frame", func() { frame, err := ParseStopSendingFrame(b, versionIETFFrames) Expect(err).ToNot(HaveOccurred()) Expect(frame.StreamID).To(Equal(protocol.StreamID(0xdecafbad))) - Expect(frame.ErrorCode).To(Equal(qerr.ErrorCode(0x1337))) + Expect(frame.ErrorCode).To(Equal(protocol.ApplicationErrorCode(0x1337))) Expect(b.Len()).To(BeZero()) }) diff --git a/packet_unpacker_test.go b/packet_unpacker_test.go index 8934bb7e..6d3b3914 100644 --- a/packet_unpacker_test.go +++ b/packet_unpacker_test.go @@ -102,7 +102,7 @@ var _ = Describe("Packet unpacker", func() { f := &wire.RstStreamFrame{ StreamID: 0xdeadbeef, ByteOffset: 0xdecafbad11223344, - ErrorCode: 0x13371234, + ErrorCode: 0x1337, } err := f.Write(buf, versionGQUICFrames) Expect(err).ToNot(HaveOccurred())