implement the RETIRE_CONNECTION_ID frame

This commit is contained in:
Marten Seemann
2018-11-13 11:13:27 +07:00
parent 2021a21916
commit 42edcf6258
5 changed files with 101 additions and 1 deletions

View File

@@ -60,7 +60,8 @@ func parseFrame(r *bytes.Reader, typeByte byte, v protocol.VersionNumber) (Frame
frame, err = parseStreamsBlockedFrame(r, v)
case 0x18:
frame, err = parseNewConnectionIDFrame(r, v)
// TODO: implement RETIRE_CONNECTION_ID frame
case 0x19:
frame, err = parseRetireConnectionIDFrame(r, v)
case 0x1a:
frame, err = parsePathChallengeFrame(r, v)
case 0x1b:

View File

@@ -196,6 +196,15 @@ var _ = Describe("Frame parsing", func() {
Expect(frame).To(Equal(f))
})
It("unpacks RETIRE_CONNECTION_ID frames", func() {
f := &RetireConnectionIDFrame{SequenceNumber: 0x1337}
buf := &bytes.Buffer{}
Expect(f.Write(buf, versionIETFFrames)).To(Succeed())
frame, err := ParseNextFrame(bytes.NewReader(buf.Bytes()), versionIETFFrames)
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(Equal(f))
})
It("unpacks PATH_CHALLENGE frames", func() {
f := &PathChallengeFrame{Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}}
err := f.Write(buf, versionIETFFrames)

View File

@@ -0,0 +1,36 @@
package wire
import (
"bytes"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/utils"
)
// A RetireConnectionIDFrame is a RETIRE_CONNECTION_ID frame
type RetireConnectionIDFrame struct {
SequenceNumber uint64
}
func parseRetireConnectionIDFrame(r *bytes.Reader, _ protocol.VersionNumber) (*RetireConnectionIDFrame, error) {
if _, err := r.ReadByte(); err != nil {
return nil, err
}
seq, err := utils.ReadVarInt(r)
if err != nil {
return nil, err
}
return &RetireConnectionIDFrame{SequenceNumber: seq}, nil
}
func (f *RetireConnectionIDFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error {
b.WriteByte(0x19)
utils.WriteVarInt(b, f.SequenceNumber)
return nil
}
// Length of a written frame
func (f *RetireConnectionIDFrame) Length(protocol.VersionNumber) protocol.ByteCount {
return 1 + utils.VarIntLen(f.SequenceNumber)
}

View File

@@ -0,0 +1,51 @@
package wire
import (
"bytes"
"io"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("NEW_CONNECTION_ID frame", func() {
Context("when parsing", func() {
It("accepts a sample frame", func() {
data := []byte{0x19}
data = append(data, encodeVarInt(0xdeadbeef)...) // sequence number
b := bytes.NewReader(data)
frame, err := parseRetireConnectionIDFrame(b, versionIETFFrames)
Expect(err).ToNot(HaveOccurred())
Expect(frame.SequenceNumber).To(Equal(uint64(0xdeadbeef)))
})
It("errors on EOFs", func() {
data := []byte{0x18}
data = append(data, encodeVarInt(0xdeadbeef)...) // sequence number
_, err := parseRetireConnectionIDFrame(bytes.NewReader(data), versionIETFFrames)
Expect(err).NotTo(HaveOccurred())
for i := range data {
_, err := parseRetireConnectionIDFrame(bytes.NewReader(data[0:i]), versionIETFFrames)
Expect(err).To(MatchError(io.EOF))
}
})
})
Context("when writing", func() {
It("writes a sample frame", func() {
frame := &RetireConnectionIDFrame{SequenceNumber: 0x1337}
b := &bytes.Buffer{}
Expect(frame.Write(b, versionIETFFrames)).To(Succeed())
expected := []byte{0x19}
expected = append(expected, encodeVarInt(0x1337)...)
Expect(b.Bytes()).To(Equal(expected))
})
It("has the correct length", func() {
frame := &RetireConnectionIDFrame{SequenceNumber: 0xdecafbad}
b := &bytes.Buffer{}
Expect(frame.Write(b, versionIETFFrames)).To(Succeed())
Expect(frame.Length(versionIETFFrames)).To(BeEquivalentTo(b.Len()))
})
})
})