From 23f0d8d6e9c26395576aff403e7ccb221740d835 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 15 Apr 2016 17:46:29 +0700 Subject: [PATCH] read the STOP_WAITING frame --- public_header.go | 25 ++++++++++++----------- session.go | 10 ++++++---- stop_waiting_frame.go | 41 ++++++++++++++++++++++++++++++++++++++ stop_waiting_frame_test.go | 22 ++++++++++++++++++++ 4 files changed, 82 insertions(+), 16 deletions(-) create mode 100644 stop_waiting_frame.go create mode 100644 stop_waiting_frame_test.go diff --git a/public_header.go b/public_header.go index 52863398..6c120f64 100644 --- a/public_header.go +++ b/public_header.go @@ -11,12 +11,13 @@ import ( // The PublicHeader of a QUIC packet type PublicHeader struct { - VersionFlag bool - ResetFlag bool - ConnectionID protocol.ConnectionID - VersionNumber protocol.VersionNumber - PacketNumber protocol.PacketNumber - // packetNumberLen uint8 + VersionFlag bool + ResetFlag bool + ConnectionID protocol.ConnectionID + VersionNumber protocol.VersionNumber + QuicVersion uint32 + PacketNumberLen uint8 + PacketNumber protocol.PacketNumber } // WritePublicHeader writes a public header @@ -50,7 +51,7 @@ func ParsePublicHeader(b io.ByteReader) (*PublicHeader, error) { header.VersionFlag = publicFlagByte&0x01 > 0 header.ResetFlag = publicFlagByte&0x02 > 0 - var connectionIDLen, packetNumberLen uint8 + var connectionIDLen uint8 switch publicFlagByte & 0x0C { case 0x0C: connectionIDLen = 8 @@ -61,13 +62,13 @@ func ParsePublicHeader(b io.ByteReader) (*PublicHeader, error) { } switch publicFlagByte & 0x30 { case 0x30: - packetNumberLen = 6 + header.PacketNumberLen = 6 case 0x20: - packetNumberLen = 4 + header.PacketNumberLen = 4 case 0x10: - packetNumberLen = 2 + header.PacketNumberLen = 2 case 0x00: - packetNumberLen = 1 + header.PacketNumberLen = 1 } // Connection ID @@ -92,7 +93,7 @@ func ParsePublicHeader(b io.ByteReader) (*PublicHeader, error) { } // Packet number - pcktNumber, err := utils.ReadUintN(b, packetNumberLen) + pcktNumber, err := utils.ReadUintN(b, header.PacketNumberLen) if err != nil { return nil, err } diff --git a/session.go b/session.go index b0e64ba2..2a04a8bd 100644 --- a/session.go +++ b/session.go @@ -76,7 +76,7 @@ func (s *Session) HandlePacket(addr *net.UDPAddr, publicHeaderBinary []byte, pub frameCounter++ fmt.Printf("Reading frame %d\n", frameCounter) - if typeByte&0x80 > 0 { // STREAM + if typeByte&0x80 == 0x80 { // STREAM fmt.Println("Detected STREAM") frame, err := ParseStreamFrame(r) if err != nil { @@ -109,9 +109,11 @@ func (s *Session) HandlePacket(addr *net.UDPAddr, publicHeaderBinary []byte, pub return errors.New("Detected CONGESTION_FEEDBACK") } else if typeByte&0x06 == 0x06 { // STOP_WAITING fmt.Println("Detected STOP_WAITING") - r.ReadByte() - r.ReadByte() - continue + _, err := ParseStopWaitingFrame(r, publicHeader.PacketNumberLen) + if err != nil { + return err + } + // ToDo: react to receiving this frame } else if typeByte == 0 { // PAD return nil diff --git a/stop_waiting_frame.go b/stop_waiting_frame.go new file mode 100644 index 00000000..5289d484 --- /dev/null +++ b/stop_waiting_frame.go @@ -0,0 +1,41 @@ +package quic + +import ( + "bytes" + "errors" + + "github.com/lucas-clemente/quic-go/utils" +) + +// A StopWaitingFrame in QUIC +type StopWaitingFrame struct { + Entropy byte + LeastUnackedDelta uint64 +} + +func (f *StopWaitingFrame) Write(b *bytes.Buffer) error { + return errors.New("StopWaitingFrame: Write not yet implemented") +} + +// ParseStopWaitingFrame parses a StopWaiting frame +func ParseStopWaitingFrame(r *bytes.Reader, packetNumberLen uint8) (*StopWaitingFrame, error) { + frame := &StopWaitingFrame{} + + // read the TypeByte + _, err := r.ReadByte() + if err != nil { + return nil, err + } + + frame.Entropy, err = r.ReadByte() + if err != nil { + return nil, err + } + + frame.LeastUnackedDelta, err = utils.ReadUintN(r, packetNumberLen) + if err != nil { + return nil, err + } + + return frame, nil +} diff --git a/stop_waiting_frame_test.go b/stop_waiting_frame_test.go new file mode 100644 index 00000000..670cd59e --- /dev/null +++ b/stop_waiting_frame_test.go @@ -0,0 +1,22 @@ +package quic + +import ( + "bytes" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("StreamFrame", func() { + Context("stream frames", func() { + Context("when parsing", func() { + It("accepts sample frame", func() { + b := bytes.NewReader([]byte{0x06, 0xA4, 0x03}) + frame, err := ParseStopWaitingFrame(b, 1) + Expect(err).ToNot(HaveOccurred()) + Expect(frame.Entropy).To(Equal(byte(0xA4))) + Expect(frame.LeastUnackedDelta).To(Equal(uint64(0x03))) + }) + }) + }) +})