add an application-defined error type, for RST_STREAM and STOP_SENDING

This commit is contained in:
Marten Seemann 2017-12-15 09:53:53 +07:00
parent efa781b067
commit 40650d93f0
6 changed files with 22 additions and 20 deletions

View file

@ -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.

View file

@ -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
}

View file

@ -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
}))
})

View file

@ -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
}

View file

@ -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())
})

View file

@ -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())