Skip to content

Commit

Permalink
Merge pull request #2973 from lucas-clemente/publicize-varint
Browse files Browse the repository at this point in the history
publicize QUIC varint reading and writing
  • Loading branch information
marten-seemann authored Jan 2, 2021
2 parents 5e7fb50 + f922688 commit d9c7467
Show file tree
Hide file tree
Showing 47 changed files with 372 additions and 339 deletions.
4 changes: 2 additions & 2 deletions framer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (

"github.com/lucas-clemente/quic-go/internal/ackhandler"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/lucas-clemente/quic-go/internal/wire"
"github.com/lucas-clemente/quic-go/quicvarint"
)

type framer interface {
Expand Down Expand Up @@ -114,7 +114,7 @@ func (f *framerI) AppendStreamFrames(frames []ackhandler.Frame, maxLen protocol.
// For the last STREAM frame, we'll remove the DataLen field later.
// Therefore, we can pretend to have more bytes available when popping
// the STREAM frame (which will always have the DataLen set).
remainingLen += utils.VarIntLen(uint64(remainingLen))
remainingLen += quicvarint.Len(uint64(remainingLen))
frame, hasMoreData := str.popStreamFrame(remainingLen)
if hasMoreData { // put the stream back in the queue (at the end)
f.streamQueue = append(f.streamQueue, id)
Expand Down
5 changes: 3 additions & 2 deletions http3/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/qtls"
"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/lucas-clemente/quic-go/quicvarint"
"github.com/marten-seemann/qpack"
)

Expand Down Expand Up @@ -131,7 +132,7 @@ func (c *client) setupSession() error {
return err
}
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypeControlStream)
quicvarint.Write(buf, streamTypeControlStream)
// send the SETTINGS frame
(&settingsFrame{Datagram: c.opts.EnableDatagram}).Write(buf)
_, err = str.Write(buf.Bytes())
Expand All @@ -147,7 +148,7 @@ func (c *client) handleUnidirectionalStreams() {
}

go func() {
streamType, err := utils.ReadVarInt(&byteReaderImpl{str})
streamType, err := quicvarint.Read(&byteReaderImpl{str})
if err != nil {
c.logger.Debugf("reading stream type on stream %d failed: %s", str.StreamID(), err)
return
Expand Down
17 changes: 9 additions & 8 deletions http3/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import (
"time"

"github.com/golang/mock/gomock"
quic "github.com/lucas-clemente/quic-go"
"github.com/lucas-clemente/quic-go"
mockquic "github.com/lucas-clemente/quic-go/internal/mocks/quic"
"github.com/lucas-clemente/quic-go/quicvarint"

"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/utils"
Expand Down Expand Up @@ -217,7 +218,7 @@ var _ = Describe("Client", func() {

It("parses the SETTINGS frame", func() {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypeControlStream)
quicvarint.Write(buf, streamTypeControlStream)
(&settingsFrame{}).Write(buf)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
Expand All @@ -235,7 +236,7 @@ var _ = Describe("Client", func() {

It("ignores streams other than the control stream", func() {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, 1337)
quicvarint.Write(buf, 1337)
str := mockquic.NewMockStream(mockCtrl)
str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
done := make(chan struct{})
Expand All @@ -257,7 +258,7 @@ var _ = Describe("Client", func() {

It("errors when the first frame on the control stream is not a SETTINGS frame", func() {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypeControlStream)
quicvarint.Write(buf, streamTypeControlStream)
(&dataFrame{}).Write(buf)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
Expand All @@ -281,7 +282,7 @@ var _ = Describe("Client", func() {

It("errors when parsing the frame on the control stream fails", func() {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypeControlStream)
quicvarint.Write(buf, streamTypeControlStream)
b := &bytes.Buffer{}
(&settingsFrame{}).Write(b)
buf.Write(b.Bytes()[:b.Len()-1])
Expand All @@ -307,7 +308,7 @@ var _ = Describe("Client", func() {

It("errors when parsing the server opens a push stream", func() {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypePushStream)
quicvarint.Write(buf, streamTypePushStream)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
sess.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
Expand All @@ -331,7 +332,7 @@ var _ = Describe("Client", func() {
It("errors when the server advertises datagram support (and we enabled support for it)", func() {
client.opts.EnableDatagram = true
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypeControlStream)
quicvarint.Write(buf, streamTypeControlStream)
(&settingsFrame{Datagram: true}).Write(buf)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
Expand Down Expand Up @@ -390,7 +391,7 @@ var _ = Describe("Client", func() {
controlStr.EXPECT().Write(gomock.Any()).Do(func(b []byte) {
defer GinkgoRecover()
r := bytes.NewReader(b)
streamType, err := utils.ReadVarInt(r)
streamType, err := quicvarint.Read(r)
Expect(err).ToNot(HaveOccurred())
Expect(streamType).To(BeEquivalentTo(streamTypeControlStream))
close(settingsFrameWritten)
Expand Down
34 changes: 17 additions & 17 deletions http3/frames.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"io/ioutil"

"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/lucas-clemente/quic-go/quicvarint"
)

type byteReader interface {
Expand All @@ -32,11 +32,11 @@ func parseNextFrame(b io.Reader) (frame, error) {
if !ok {
br = &byteReaderImpl{b}
}
t, err := utils.ReadVarInt(br)
t, err := quicvarint.Read(br)
if err != nil {
return nil, err
}
l, err := utils.ReadVarInt(br)
l, err := quicvarint.Read(br)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -72,17 +72,17 @@ type dataFrame struct {
}

func (f *dataFrame) Write(b *bytes.Buffer) {
utils.WriteVarInt(b, 0x0)
utils.WriteVarInt(b, f.Length)
quicvarint.Write(b, 0x0)
quicvarint.Write(b, f.Length)
}

type headersFrame struct {
Length uint64
}

func (f *headersFrame) Write(b *bytes.Buffer) {
utils.WriteVarInt(b, 0x1)
utils.WriteVarInt(b, f.Length)
quicvarint.Write(b, 0x1)
quicvarint.Write(b, f.Length)
}

const settingDatagram = 0x276
Expand All @@ -107,11 +107,11 @@ func parseSettingsFrame(r io.Reader, l uint64) (*settingsFrame, error) {
b := bytes.NewReader(buf)
var readDatagram bool
for b.Len() > 0 {
id, err := utils.ReadVarInt(b)
id, err := quicvarint.Read(b)
if err != nil { // should not happen. We allocated the whole frame already.
return nil, err
}
val, err := utils.ReadVarInt(b)
val, err := quicvarint.Read(b)
if err != nil { // should not happen. We allocated the whole frame already.
return nil, err
}
Expand Down Expand Up @@ -140,21 +140,21 @@ func parseSettingsFrame(r io.Reader, l uint64) (*settingsFrame, error) {
}

func (f *settingsFrame) Write(b *bytes.Buffer) {
utils.WriteVarInt(b, 0x4)
quicvarint.Write(b, 0x4)
var l protocol.ByteCount
for id, val := range f.other {
l += utils.VarIntLen(id) + utils.VarIntLen(val)
l += quicvarint.Len(id) + quicvarint.Len(val)
}
if f.Datagram {
l += utils.VarIntLen(settingDatagram) + utils.VarIntLen(1)
l += quicvarint.Len(settingDatagram) + quicvarint.Len(1)
}
utils.WriteVarInt(b, uint64(l))
quicvarint.Write(b, uint64(l))
if f.Datagram {
utils.WriteVarInt(b, settingDatagram)
utils.WriteVarInt(b, 1)
quicvarint.Write(b, settingDatagram)
quicvarint.Write(b, 1)
}
for id, val := range f.other {
utils.WriteVarInt(b, id)
utils.WriteVarInt(b, val)
quicvarint.Write(b, id)
quicvarint.Write(b, val)
}
}
4 changes: 2 additions & 2 deletions http3/frames_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"io"

"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/lucas-clemente/quic-go/quicvarint"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand All @@ -14,7 +14,7 @@ import (
var _ = Describe("Frames", func() {
appendVarInt := func(b []byte, val uint64) []byte {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, val)
quicvarint.Write(buf, val)
return append(b, buf.Bytes()...)
}

Expand Down
5 changes: 3 additions & 2 deletions http3/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/lucas-clemente/quic-go/internal/handshake"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/lucas-clemente/quic-go/quicvarint"
"github.com/marten-seemann/qpack"
)

Expand Down Expand Up @@ -235,7 +236,7 @@ func (s *Server) handleConn(sess quic.EarlySession) {
return
}
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypeControlStream) // stream type
quicvarint.Write(buf, streamTypeControlStream) // stream type
(&settingsFrame{Datagram: s.EnableDatagrams}).Write(buf)
str.Write(buf.Bytes())

Expand Down Expand Up @@ -281,7 +282,7 @@ func (s *Server) handleUnidirectionalStreams(sess quic.EarlySession) {
}

go func(str quic.ReceiveStream) {
streamType, err := utils.ReadVarInt(&byteReaderImpl{str})
streamType, err := quicvarint.Read(&byteReaderImpl{str})
if err != nil {
s.logger.Debugf("reading stream type on stream %d failed: %s", str.StreamID(), err)
return
Expand Down
16 changes: 9 additions & 7 deletions http3/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import (
"net/http"
"time"

"github.com/golang/mock/gomock"
"github.com/lucas-clemente/quic-go"
mockquic "github.com/lucas-clemente/quic-go/internal/mocks/quic"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/testdata"
"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/lucas-clemente/quic-go/quicvarint"

"github.com/golang/mock/gomock"
"github.com/marten-seemann/qpack"

. "github.com/onsi/ginkgo"
Expand Down Expand Up @@ -193,7 +195,7 @@ var _ = Describe("Server", func() {

It("parses the SETTINGS frame", func() {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypeControlStream)
quicvarint.Write(buf, streamTypeControlStream)
(&settingsFrame{}).Write(buf)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
Expand All @@ -210,7 +212,7 @@ var _ = Describe("Server", func() {

It("ignores streams other than the control stream", func() {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, 1337)
quicvarint.Write(buf, 1337)
str := mockquic.NewMockStream(mockCtrl)
str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
done := make(chan struct{})
Expand All @@ -231,7 +233,7 @@ var _ = Describe("Server", func() {

It("errors when the first frame on the control stream is not a SETTINGS frame", func() {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypeControlStream)
quicvarint.Write(buf, streamTypeControlStream)
(&dataFrame{}).Write(buf)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
Expand All @@ -254,7 +256,7 @@ var _ = Describe("Server", func() {

It("errors when parsing the frame on the control stream fails", func() {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypeControlStream)
quicvarint.Write(buf, streamTypeControlStream)
b := &bytes.Buffer{}
(&settingsFrame{}).Write(b)
buf.Write(b.Bytes()[:b.Len()-1])
Expand All @@ -279,7 +281,7 @@ var _ = Describe("Server", func() {

It("errors when the client opens a push stream", func() {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypePushStream)
quicvarint.Write(buf, streamTypePushStream)
(&dataFrame{}).Write(buf)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
Expand All @@ -303,7 +305,7 @@ var _ = Describe("Server", func() {
It("errors when the client advertises datagram support (and we enabled support for it)", func() {
s.EnableDatagrams = true
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, streamTypeControlStream)
quicvarint.Write(buf, streamTypeControlStream)
(&settingsFrame{Datagram: true}).Write(buf)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
Expand Down
9 changes: 5 additions & 4 deletions internal/handshake/crypto_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/lucas-clemente/quic-go/internal/wire"
"github.com/lucas-clemente/quic-go/logging"
"github.com/lucas-clemente/quic-go/quicvarint"
)

// TLS unexpected_message alert
Expand Down Expand Up @@ -405,8 +406,8 @@ func (h *cryptoSetup) handleTransportParameters(data []byte) {
// must be called after receiving the transport parameters
func (h *cryptoSetup) marshalDataForSessionState() []byte {
buf := &bytes.Buffer{}
utils.WriteVarInt(buf, clientSessionStateRevision)
utils.WriteVarInt(buf, uint64(h.rttStats.SmoothedRTT().Microseconds()))
quicvarint.Write(buf, clientSessionStateRevision)
quicvarint.Write(buf, uint64(h.rttStats.SmoothedRTT().Microseconds()))
h.peerParams.MarshalForSessionTicket(buf)
return buf.Bytes()
}
Expand All @@ -422,14 +423,14 @@ func (h *cryptoSetup) handleDataFromSessionState(data []byte) {

func (h *cryptoSetup) handleDataFromSessionStateImpl(data []byte) (*wire.TransportParameters, error) {
r := bytes.NewReader(data)
ver, err := utils.ReadVarInt(r)
ver, err := quicvarint.Read(r)
if err != nil {
return nil, err
}
if ver != clientSessionStateRevision {
return nil, fmt.Errorf("mismatching version. Got %d, expected %d", ver, clientSessionStateRevision)
}
rtt, err := utils.ReadVarInt(r)
rtt, err := quicvarint.Read(r)
if err != nil {
return nil, err
}
Expand Down
10 changes: 5 additions & 5 deletions internal/handshake/session_ticket.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"fmt"
"time"

"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/lucas-clemente/quic-go/internal/wire"
"github.com/lucas-clemente/quic-go/quicvarint"
)

const sessionTicketRevision = 2
Expand All @@ -19,22 +19,22 @@ type sessionTicket struct {

func (t *sessionTicket) Marshal() []byte {
b := &bytes.Buffer{}
utils.WriteVarInt(b, sessionTicketRevision)
utils.WriteVarInt(b, uint64(t.RTT.Microseconds()))
quicvarint.Write(b, sessionTicketRevision)
quicvarint.Write(b, uint64(t.RTT.Microseconds()))
t.Parameters.MarshalForSessionTicket(b)
return b.Bytes()
}

func (t *sessionTicket) Unmarshal(b []byte) error {
r := bytes.NewReader(b)
rev, err := utils.ReadVarInt(r)
rev, err := quicvarint.Read(r)
if err != nil {
return errors.New("failed to read session ticket revision")
}
if rev != sessionTicketRevision {
return fmt.Errorf("unknown session ticket revision: %d", rev)
}
rtt, err := utils.ReadVarInt(r)
rtt, err := quicvarint.Read(r)
if err != nil {
return errors.New("failed to read RTT")
}
Expand Down
Loading

0 comments on commit d9c7467

Please sign in to comment.