Browse Source

Update vendored quic-go

Rod Hynes 7 years ago
parent
commit
526827ba0d

+ 3 - 2
vendor/github.com/lucas-clemente/quic-go/appveyor.yml

@@ -6,6 +6,7 @@ environment:
   GOPATH: c:\gopath
   CGO_ENABLED: 0
   TIMESCALE_FACTOR: 20
+  GO111MODULE: on
   matrix:
     - GOARCH: 386
     - GOARCH: amd64
@@ -17,8 +18,8 @@ clone_folder: c:\gopath\src\github.com\lucas-clemente\quic-go
 
 install:
   - rmdir c:\go /s /q
-  - appveyor DownloadFile https://storage.googleapis.com/golang/go1.11.windows-amd64.zip
-  - 7z x go1.11.windows-amd64.zip -y -oC:\ > NUL
+  - appveyor DownloadFile https://storage.googleapis.com/golang/go1.12.4.windows-amd64.zip
+  - 7z x go1.12.4.windows-amd64.zip -y -oC:\ > NUL
   - set PATH=%PATH%;%GOPATH%\bin\windows_%GOARCH%;%GOPATH%\bin
   - echo %PATH%
   - echo %GOPATH%

+ 9 - 11
vendor/github.com/lucas-clemente/quic-go/client.go

@@ -27,8 +27,7 @@ type client struct {
 
 	packetHandlers packetHandlerManager
 
-	token      []byte
-	numRetries int
+	token []byte
 
 	versionNegotiated                bool // has the server accepted our version
 	receivedVersionNegotiationPacket bool
@@ -487,19 +486,18 @@ func (c *client) handleVersionNegotiationPacket(hdr *wire.Header) error {
 func (c *client) handleRetryPacket(hdr *wire.Header) {
 	c.logger.Debugf("<- Received Retry")
 	hdr.Log(c.logger)
-	// A server that performs multiple retries must use a source connection ID of at least 8 bytes.
-	// Only a server that won't send additional Retries can use shorter connection IDs.
-	if hdr.OrigDestConnectionID.Len() < protocol.MinConnectionIDLenInitial {
-		c.logger.Debugf("Received a Retry with a too short Original Destination Connection ID: %d bytes, must have at least %d bytes.", hdr.OrigDestConnectionID.Len(), protocol.MinConnectionIDLenInitial)
+	if !hdr.OrigDestConnectionID.Equal(c.destConnID) {
+		c.logger.Debugf("Ignoring spoofed Retry. Original Destination Connection ID: %s, expected: %s", hdr.OrigDestConnectionID, c.destConnID)
 		return
 	}
-	if !hdr.OrigDestConnectionID.Equal(c.destConnID) {
-		c.logger.Debugf("Received spoofed Retry. Original Destination Connection ID: %s, expected: %s", hdr.OrigDestConnectionID, c.destConnID)
+	if hdr.SrcConnectionID.Equal(c.destConnID) {
+		c.logger.Debugf("Ignoring Retry, since the server didn't change the Source Connection ID.")
 		return
 	}
-	c.numRetries++
-	if c.numRetries > protocol.MaxRetries {
-		c.session.destroy(qerr.CryptoTooManyRejects)
+	// If a token is already set, this means that we already received a Retry from the server.
+	// Ignore this Retry packet.
+	if len(c.token) > 0 {
+		c.logger.Debugf("Ignoring Retry, since a Retry was already received.")
 		return
 	}
 	c.destConnID = hdr.SrcConnectionID

+ 18 - 0
vendor/github.com/lucas-clemente/quic-go/go.mod

@@ -0,0 +1,18 @@
+module github.com/lucas-clemente/quic-go
+
+go 1.12
+
+require (
+	github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115
+	github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9
+	github.com/golang/mock v1.2.0
+	github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47
+	github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f
+	github.com/lucas-clemente/quic-clients v0.1.0
+	github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced
+	github.com/marten-seemann/qtls v0.2.3
+	github.com/onsi/ginkgo v1.8.0
+	github.com/onsi/gomega v1.5.0
+	golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25
+	golang.org/x/net v0.0.0-20180906233101-161cd47e91fd
+)

+ 48 - 0
vendor/github.com/lucas-clemente/quic-go/go.sum

@@ -0,0 +1,48 @@
+github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115 h1:fUjoj2bT6dG8LoEe+uNsKk8J+sLkDbQkJnB6Z1F02Bc=
+github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU=
+github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9 h1:a1zrFsLFac2xoM6zG1u72DWJwZG3ayttYLfmLbxVETk=
+github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47 h1:UnszMmmmm5vLwWzDjTFVIkfhvWF1NdrmChl8L2NUDCw=
+github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f h1:sSeNEkJrs+0F9TUau0CgWTTNEwF23HST3Eq0A+QIx+A=
+github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f/go.mod h1:JpH9J1c9oX6otFSgdUHwUBUizmKlrMjxWnIAjff4m04=
+github.com/lucas-clemente/quic-clients v0.1.0 h1:/P9n0nICT/GnQJkZovtBqridjxU0ao34m7DpMts79qY=
+github.com/lucas-clemente/quic-clients v0.1.0/go.mod h1:y5xVIEoObKqULIKivu+gD/LU90pL73bTdtQjPBvtCBk=
+github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced h1:zqEC1GJZFbGZA0tRyNZqRjep92K5fujFtFsu5ZW7Aug=
+github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58=
+github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA=
+github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
+github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
+github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU=
+golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c=
+golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

+ 3 - 0
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_handler.go

@@ -148,6 +148,7 @@ func (h *sentPacketHandler) SentPacketsAsRetransmission(packets []*Packet, retra
 
 func (h *sentPacketHandler) sentPacketImpl(packet *Packet) bool /* isRetransmittable */ {
 	for p := h.lastSentPacketNumber + 1; p < packet.PacketNumber; p++ {
+		h.logger.Debugf("Skipping packet number %#x", p)
 		h.skippedPackets = append(h.skippedPackets, p)
 		if len(h.skippedPackets) > protocol.MaxTrackedSkippedPackets {
 			h.skippedPackets = h.skippedPackets[1:]
@@ -464,6 +465,8 @@ func (h *sentPacketHandler) onPacketAcked(p *Packet, rcvTime time.Time) error {
 	}
 	h.rtoCount = 0
 	h.tlpCount = 0
+	h.numRTOs = 0
+	h.allowTLP = false
 	h.handshakeCount = 0
 	return h.packetHistory.Remove(p.PacketNumber)
 }

+ 1 - 5
vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic_sender.go

@@ -89,11 +89,7 @@ func (c *cubicSender) TimeUntilSend(bytesInFlight protocol.ByteCount) time.Durat
 			return 0
 		}
 	}
-	delay := c.rttStats.SmoothedRTT() / time.Duration(2*c.GetCongestionWindow())
-	if !c.InSlowStart() { // adjust delay, such that it's 1.25*cwd/rtt
-		delay = delay * 8 / 5
-	}
-	return delay
+	return c.rttStats.SmoothedRTT() * time.Duration(protocol.DefaultTCPMSS) / time.Duration(2*c.GetCongestionWindow())
 }
 
 func (c *cubicSender) OnPacketSent(

+ 10 - 5
vendor/github.com/lucas-clemente/quic-go/internal/crypto/cert_chain.go

@@ -56,8 +56,7 @@ func (c *certChain) GetLeafCert(sni string) ([]byte, error) {
 }
 
 func (c *certChain) getCertForSNI(sni string) (*tls.Certificate, error) {
-	conf := c.config
-	conf, err := maybeGetConfigForClient(conf, sni)
+	conf, err := maybeGetConfigForClient(c.config, sni)
 	if err != nil {
 		return nil, err
 	}
@@ -107,7 +106,13 @@ func maybeGetConfigForClient(c *tls.Config, sni string) (*tls.Config, error) {
 	if c.GetConfigForClient == nil {
 		return c, nil
 	}
-	return c.GetConfigForClient(&tls.ClientHelloInfo{
-		ServerName: sni,
-	})
+	confForClient, err := c.GetConfigForClient(&tls.ClientHelloInfo{ServerName: sni})
+	if err != nil {
+		return nil, err
+	}
+	// if GetConfigForClient returns nil, use the original config
+	if confForClient == nil {
+		return c, nil
+	}
+	return confForClient, nil
 }

+ 15 - 2
vendor/github.com/lucas-clemente/quic-go/internal/handshake/transport_parameters.go

@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"encoding/binary"
 	"fmt"
+	"sort"
 	"time"
 
 	"github.com/lucas-clemente/quic-go/internal/protocol"
@@ -96,14 +97,18 @@ func (p *TransportParameters) getHelloMap() map[Tag][]byte {
 }
 
 func (p *TransportParameters) unmarshal(data []byte) error {
+	// needed to check that every parameter is only sent at most once
+	var parameterIDs []transportParameterID
+
 	for len(data) >= 4 {
-		paramID := binary.BigEndian.Uint16(data[:2])
+		paramID := transportParameterID(binary.BigEndian.Uint16(data[:2]))
 		paramLen := int(binary.BigEndian.Uint16(data[2:4]))
 		data = data[4:]
 		if len(data) < paramLen {
 			return fmt.Errorf("remaining length (%d) smaller than parameter length (%d)", len(data), paramLen)
 		}
-		switch transportParameterID(paramID) {
+		parameterIDs = append(parameterIDs, paramID)
+		switch paramID {
 		case initialMaxStreamDataParameterID:
 			if paramLen != 4 {
 				return fmt.Errorf("wrong length for initial_max_stream_data: %d (expected 4)", paramLen)
@@ -152,6 +157,14 @@ func (p *TransportParameters) unmarshal(data []byte) error {
 		data = data[paramLen:]
 	}
 
+	// check that every transport parameter was sent at most once
+	sort.Slice(parameterIDs, func(i, j int) bool { return parameterIDs[i] < parameterIDs[j] })
+	for i := 0; i < len(parameterIDs)-1; i++ {
+		if parameterIDs[i] == parameterIDs[i+1] {
+			return fmt.Errorf("received duplicate transport parameter %#x", parameterIDs[i])
+		}
+	}
+
 	if len(data) != 0 {
 		return fmt.Errorf("should have read all data. Still have %d bytes", len(data))
 	}

+ 0 - 3
vendor/github.com/lucas-clemente/quic-go/internal/protocol/server_parameters.go

@@ -149,6 +149,3 @@ const MinPacingDelay time.Duration = 100 * time.Microsecond
 // DefaultConnectionIDLength is the connection ID length that is used for multiplexed connections
 // if no other value is configured.
 const DefaultConnectionIDLength = 4
-
-// MaxRetries is the maximum number of Retries a client will do before failing the connection.
-const MaxRetries = 3

+ 8 - 3
vendor/github.com/lucas-clemente/quic-go/internal/utils/timer.go

@@ -1,6 +1,9 @@
 package utils
 
-import "time"
+import (
+	"math"
+	"time"
+)
 
 // A Timer wrapper that behaves correctly when resetting
 type Timer struct {
@@ -11,7 +14,7 @@ type Timer struct {
 
 // NewTimer creates a new timer that is not set
 func NewTimer() *Timer {
-	return &Timer{t: time.NewTimer(0)}
+	return &Timer{t: time.NewTimer(time.Duration(math.MaxInt64))}
 }
 
 // Chan returns the channel of the wrapped timer
@@ -31,7 +34,9 @@ func (t *Timer) Reset(deadline time.Time) {
 	if !t.t.Stop() && !t.read {
 		<-t.t.C
 	}
-	t.t.Reset(time.Until(deadline))
+	if !deadline.IsZero() {
+		t.t.Reset(time.Until(deadline))
+	}
 
 	t.read = false
 	t.deadline = deadline

+ 8 - 15
vendor/github.com/lucas-clemente/quic-go/packet_number_generator.go

@@ -18,10 +18,12 @@ type packetNumberGenerator struct {
 }
 
 func newPacketNumberGenerator(initial, averagePeriod protocol.PacketNumber) *packetNumberGenerator {
-	return &packetNumberGenerator{
+	g := &packetNumberGenerator{
 		next:          initial,
 		averagePeriod: averagePeriod,
 	}
+	g.generateNewSkip()
+	return g
 }
 
 func (p *packetNumberGenerator) Peek() protocol.PacketNumber {
@@ -42,28 +44,19 @@ func (p *packetNumberGenerator) Pop() protocol.PacketNumber {
 	return next
 }
 
-func (p *packetNumberGenerator) generateNewSkip() error {
-	num, err := p.getRandomNumber()
-	if err != nil {
-		return err
-	}
-
+func (p *packetNumberGenerator) generateNewSkip() {
+	num := p.getRandomNumber()
 	skip := protocol.PacketNumber(num) * (p.averagePeriod - 1) / (math.MaxUint16 / 2)
 	// make sure that there are never two consecutive packet numbers that are skipped
 	p.nextToSkip = p.next + 2 + skip
-
-	return nil
 }
 
 // getRandomNumber() generates a cryptographically secure random number between 0 and MaxUint16 (= 65535)
 // The expectation value is 65535/2
-func (p *packetNumberGenerator) getRandomNumber() (uint16, error) {
+func (p *packetNumberGenerator) getRandomNumber() uint16 {
 	b := make([]byte, 2)
-	_, err := rand.Read(b)
-	if err != nil {
-		return 0, err
-	}
+	rand.Read(b) // ignore the error here
 
 	num := uint16(b[0])<<8 + uint16(b[1])
-	return num, nil
+	return num
 }

+ 14 - 91
vendor/github.com/lucas-clemente/quic-go/packet_packer.go

@@ -70,14 +70,6 @@ type frameSource interface {
 	AppendControlFrames([]wire.Frame, protocol.ByteCount) ([]wire.Frame, protocol.ByteCount)
 }
 
-// sentAndReceivedPacketManager is only needed until STOP_WAITING is removed
-type sentAndReceivedPacketManager struct {
-	ackhandler.SentPacketHandler
-	ackhandler.ReceivedPacketHandler
-}
-
-var _ ackFrameSource = &sentAndReceivedPacketManager{}
-
 type ackFrameSource interface {
 	GetAckFrame() *wire.AckFrame
 	GetStopWaitingFrame(bool) *wire.StopWaitingFrame
@@ -91,8 +83,7 @@ type packetPacker struct {
 	version     protocol.VersionNumber
 	cryptoSetup sealingManager
 
-	token    []byte
-	divNonce []byte
+	token []byte
 
 	packetNumberGenerator *packetNumberGenerator
 	getPacketNumberLen    func(protocol.PacketNumber) protocol.PacketNumberLen
@@ -100,7 +91,6 @@ type packetPacker struct {
 	framer                frameSource
 	acks                  ackFrameSource
 
-	omitConnectionID          bool
 	maxPacketSize             protocol.ByteCount
 	hasSentPacket             bool // has the packetPacker already sent a packet
 	numNonRetransmittableAcks int
@@ -115,7 +105,6 @@ func newPacketPacker(
 	getPacketNumberLen func(protocol.PacketNumber) protocol.PacketNumberLen,
 	remoteAddr net.Addr, // only used for determining the max packet size
 	token []byte,
-	divNonce []byte,
 	cryptoStream cryptoStream,
 	cryptoSetup sealingManager,
 	framer frameSource,
@@ -126,7 +115,6 @@ func newPacketPacker(
 	return &packetPacker{
 		cryptoStream:          cryptoStream,
 		cryptoSetup:           cryptoSetup,
-		divNonce:              divNonce,
 		token:                 token,
 		destConnID:            destConnID,
 		srcConnID:             srcConnID,
@@ -162,14 +150,6 @@ func (p *packetPacker) MaybePackAckPacket() (*packedPacket, error) {
 	encLevel, sealer := p.cryptoSetup.GetSealer()
 	header := p.getHeader(encLevel)
 	frames := []wire.Frame{ack}
-	// add a STOP_WAITING frame, when using gQUIC
-	if p.version.UsesStopWaitingFrames() {
-		if swf := p.acks.GetStopWaitingFrame(false); swf != nil {
-			swf.PacketNumber = header.PacketNumber
-			swf.PacketNumberLen = header.PacketNumberLen
-			frames = append(frames, swf)
-		}
-	}
 	raw, err := p.writeAndSealPacket(header, frames, sealer)
 	return &packedPacket{
 		header:          header,
@@ -201,11 +181,6 @@ func (p *packetPacker) PackRetransmission(packet *ackhandler.Packet) ([]*packedP
 
 	var packets []*packedPacket
 	encLevel, sealer := p.cryptoSetup.GetSealer()
-	var swf *wire.StopWaitingFrame
-	// for gQUIC: add a STOP_WAITING for *every* retransmission
-	if p.version.UsesStopWaitingFrames() {
-		swf = p.acks.GetStopWaitingFrame(true)
-	}
 	for len(controlFrames) > 0 || len(streamFrames) > 0 {
 		var frames []wire.Frame
 		var length protocol.ByteCount
@@ -217,17 +192,6 @@ func (p *packetPacker) PackRetransmission(packet *ackhandler.Packet) ([]*packedP
 		}
 		maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLength
 
-		if p.version.UsesStopWaitingFrames() {
-			// create a new STOP_WAIITNG Frame, since we might need to send more than one packet as a retransmission
-			stopWaitingFrame := &wire.StopWaitingFrame{
-				LeastUnacked:    swf.LeastUnacked,
-				PacketNumber:    header.PacketNumber,
-				PacketNumberLen: header.PacketNumberLen,
-			}
-			length += stopWaitingFrame.Length(p.version)
-			frames = append(frames, stopWaitingFrame)
-		}
-
 		for len(controlFrames) > 0 {
 			frame := controlFrames[0]
 			frameLen := frame.Length(p.version)
@@ -286,20 +250,11 @@ func (p *packetPacker) packHandshakeRetransmission(packet *ackhandler.Packet) (*
 	}
 	header := p.getHeader(packet.EncryptionLevel)
 	header.Type = packet.PacketType
-	var frames []wire.Frame
-	if p.version.UsesStopWaitingFrames() { // for gQUIC: pack a STOP_WAITING first
-		swf := p.acks.GetStopWaitingFrame(true)
-		swf.PacketNumber = header.PacketNumber
-		swf.PacketNumberLen = header.PacketNumberLen
-		frames = append([]wire.Frame{swf}, packet.Frames...)
-	} else {
-		frames = packet.Frames
-	}
-	raw, err := p.writeAndSealPacket(header, frames, sealer)
+	raw, err := p.writeAndSealPacket(header, packet.Frames, sealer)
 	return &packedPacket{
 		header:          header,
 		raw:             raw,
-		frames:          frames,
+		frames:          packet.Frames,
 		encryptionLevel: packet.EncryptionLevel,
 	}, err
 }
@@ -328,7 +283,7 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
 	}
 
 	maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLength
-	frames, err := p.composeNextPacket(header, maxSize, p.canSendData(encLevel))
+	frames, err := p.composeNextPacket(maxSize, p.canSendData(encLevel))
 	if err != nil {
 		return nil, err
 	}
@@ -337,7 +292,7 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
 	if len(frames) == 0 {
 		return nil, nil
 	}
-	// check if this packet only contains an ACK (and maybe a STOP_WAITING)
+	// check if this packet only contains an ACK
 	if !ackhandler.HasRetransmittableFrames(frames) {
 		if p.numNonRetransmittableAcks >= protocol.MaxNonRetransmittableAcks {
 			frames = append(frames, &wire.PingFrame{})
@@ -388,27 +343,16 @@ func (p *packetPacker) maybePackCryptoPacket() (*packedPacket, error) {
 }
 
 func (p *packetPacker) composeNextPacket(
-	header *wire.Header, // only needed to fill in the STOP_WAITING frame
 	maxFrameSize protocol.ByteCount,
 	canSendStreamFrames bool,
 ) ([]wire.Frame, error) {
 	var length protocol.ByteCount
 	var frames []wire.Frame
 
-	// STOP_WAITING and ACK will always fit
 	// ACKs need to go first, so that the sentPacketHandler will recognize them
 	if ack := p.acks.GetAckFrame(); ack != nil {
 		frames = append(frames, ack)
 		length += ack.Length(p.version)
-		// add a STOP_WAITING, for gQUIC
-		if p.version.UsesStopWaitingFrames() {
-			if swf := p.acks.GetStopWaitingFrame(false); swf != nil {
-				swf.PacketNumber = header.PacketNumber
-				swf.PacketNumberLen = header.PacketNumberLen
-				frames = append(frames, swf)
-				length += swf.Length(p.version)
-			}
-		}
 	}
 
 	var lengthAdded protocol.ByteCount
@@ -420,15 +364,10 @@ func (p *packetPacker) composeNextPacket(
 	}
 
 	// temporarily increase the maxFrameSize by the (minimum) length of the DataLen field
-	// this leads to a properly sized packet in all cases, since we do all the packet length calculations with StreamFrames that have the DataLen set
+	// this leads to a properly sized packet in all cases, since we do all the packet length calculations with STREAM frames that have the DataLen set
 	// however, for the last STREAM frame in the packet, we can omit the DataLen, thus yielding a packet of exactly the correct size
-	// for gQUIC STREAM frames, DataLen is always 2 bytes
-	// for IETF draft style STREAM frames, the length is encoded to either 1 or 2 bytes
-	if p.version.UsesIETFFrameFormat() {
-		maxFrameSize++
-	} else {
-		maxFrameSize += 2
-	}
+	// the length is encoded to either 1 or 2 bytes
+	maxFrameSize++
 
 	frames = p.framer.AppendStreamFrames(frames, maxFrameSize-length)
 	if len(frames) > 0 {
@@ -445,17 +384,15 @@ func (p *packetPacker) getHeader(encLevel protocol.EncryptionLevel) *wire.Header
 	packetNumberLen := p.getPacketNumberLen(pnum)
 
 	header := &wire.Header{
-		PacketNumber:    pnum,
-		PacketNumberLen: packetNumberLen,
-		Version:         p.version,
+		PacketNumber:     pnum,
+		PacketNumberLen:  packetNumberLen,
+		Version:          p.version,
+		DestConnectionID: p.destConnID,
 	}
 
-	if p.version.UsesIETFHeaderFormat() && encLevel != protocol.EncryptionForwardSecure {
+	if encLevel != protocol.EncryptionForwardSecure {
 		header.IsLongHeader = true
 		header.SrcConnectionID = p.srcConnID
-		if !p.version.UsesVarintPacketNumbers() {
-			header.PacketNumberLen = protocol.PacketNumberLen4
-		}
 		// Set the payload len to maximum size.
 		// Since it is encoded as a varint, this guarantees us that the header will end up at most as big as GetLength() returns.
 		header.PayloadLen = p.maxPacketSize
@@ -467,18 +404,6 @@ func (p *packetPacker) getHeader(encLevel protocol.EncryptionLevel) *wire.Header
 		}
 	}
 
-	if !p.omitConnectionID || encLevel != protocol.EncryptionForwardSecure {
-		header.DestConnectionID = p.destConnID
-	}
-	if !p.version.UsesTLS() {
-		if p.perspective == protocol.PerspectiveServer && encLevel == protocol.EncryptionSecure {
-			header.Type = protocol.PacketType0RTT
-			header.DiversificationNonce = p.divNonce
-		}
-		if p.perspective == protocol.PerspectiveClient && encLevel != protocol.EncryptionForwardSecure {
-			header.VersionFlag = true
-		}
-	}
 	return header
 }
 
@@ -521,8 +446,7 @@ func (p *packetPacker) writeAndSealPacket(
 			return nil, err
 		}
 	}
-	// if this is an IETF QUIC Initial packet, we need to pad it to fulfill the minimum size requirement
-	// in gQUIC, padding is handled in the CHLO
+	// if this is an Initial packet, we need to pad it to fulfill the minimum size requirement
 	if header.Type == protocol.PacketTypeInitial {
 		paddingLen := protocol.MinInitialPacketSize - sealer.Overhead() - buffer.Len()
 		if paddingLen > 0 {
@@ -558,7 +482,6 @@ func (p *packetPacker) ChangeDestConnectionID(connID protocol.ConnectionID) {
 }
 
 func (p *packetPacker) HandleTransportParameters(params *handshake.TransportParameters) {
-	p.omitConnectionID = params.OmitConnectionID
 	if params.MaxPacketSize != 0 {
 		p.maxPacketSize = utils.MinByteCount(p.maxPacketSize, params.MaxPacketSize)
 	}

+ 455 - 0
vendor/github.com/lucas-clemente/quic-go/packet_packer_legacy.go

@@ -0,0 +1,455 @@
+package quic
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"net"
+
+	"github.com/lucas-clemente/quic-go/internal/ackhandler"
+	"github.com/lucas-clemente/quic-go/internal/handshake"
+	"github.com/lucas-clemente/quic-go/internal/protocol"
+	"github.com/lucas-clemente/quic-go/internal/wire"
+)
+
+// sentAndReceivedPacketManager is only needed until STOP_WAITING is removed
+type sentAndReceivedPacketManager struct {
+	ackhandler.SentPacketHandler
+	ackhandler.ReceivedPacketHandler
+}
+
+var _ ackFrameSource = &sentAndReceivedPacketManager{}
+
+type packetPackerLegacy struct {
+	destConnID protocol.ConnectionID
+	srcConnID  protocol.ConnectionID
+
+	perspective protocol.Perspective
+	version     protocol.VersionNumber
+	cryptoSetup sealingManager
+
+	divNonce []byte
+
+	packetNumberGenerator *packetNumberGenerator
+	getPacketNumberLen    func(protocol.PacketNumber) protocol.PacketNumberLen
+	cryptoStream          cryptoStream
+	framer                frameSource
+	acks                  ackFrameSource
+
+	omitConnectionID          bool
+	maxPacketSize             protocol.ByteCount
+	hasSentPacket             bool // has the packetPacker already sent a packet
+	numNonRetransmittableAcks int
+}
+
+var _ packer = &packetPackerLegacy{}
+
+func newPacketPackerLegacy(
+	destConnID protocol.ConnectionID,
+	srcConnID protocol.ConnectionID,
+	getPacketNumberLen func(protocol.PacketNumber) protocol.PacketNumberLen,
+	remoteAddr net.Addr, // only used for determining the max packet size
+	divNonce []byte,
+	cryptoStream cryptoStream,
+	cryptoSetup sealingManager,
+	framer frameSource,
+	acks ackFrameSource,
+	perspective protocol.Perspective,
+	version protocol.VersionNumber,
+) *packetPackerLegacy {
+	return &packetPackerLegacy{
+		cryptoStream:          cryptoStream,
+		cryptoSetup:           cryptoSetup,
+		divNonce:              divNonce,
+		destConnID:            destConnID,
+		srcConnID:             srcConnID,
+		perspective:           perspective,
+		version:               version,
+		framer:                framer,
+		acks:                  acks,
+		getPacketNumberLen:    getPacketNumberLen,
+		packetNumberGenerator: newPacketNumberGenerator(1, protocol.SkipPacketAveragePeriodLength),
+		maxPacketSize:         getMaxPacketSize(remoteAddr),
+	}
+}
+
+// PackConnectionClose packs a packet that ONLY contains a ConnectionCloseFrame
+func (p *packetPackerLegacy) PackConnectionClose(ccf *wire.ConnectionCloseFrame) (*packedPacket, error) {
+	frames := []wire.Frame{ccf}
+	encLevel, sealer := p.cryptoSetup.GetSealer()
+	header := p.getHeader(encLevel)
+	raw, err := p.writeAndSealPacket(header, frames, sealer)
+	return &packedPacket{
+		header:          header,
+		raw:             raw,
+		frames:          frames,
+		encryptionLevel: encLevel,
+	}, err
+}
+
+func (p *packetPackerLegacy) MaybePackAckPacket() (*packedPacket, error) {
+	ack := p.acks.GetAckFrame()
+	if ack == nil {
+		return nil, nil
+	}
+	encLevel, sealer := p.cryptoSetup.GetSealer()
+	header := p.getHeader(encLevel)
+	frames := []wire.Frame{ack}
+	// add a STOP_WAITING frame, if necessary
+	if p.version.UsesStopWaitingFrames() {
+		if swf := p.acks.GetStopWaitingFrame(false); swf != nil {
+			swf.PacketNumber = header.PacketNumber
+			swf.PacketNumberLen = header.PacketNumberLen
+			frames = append(frames, swf)
+		}
+	}
+	raw, err := p.writeAndSealPacket(header, frames, sealer)
+	return &packedPacket{
+		header:          header,
+		raw:             raw,
+		frames:          frames,
+		encryptionLevel: encLevel,
+	}, err
+}
+
+// PackRetransmission packs a retransmission
+// For packets sent after completion of the handshake, it might happen that 2 packets have to be sent.
+// This can happen e.g. when a longer packet number is used in the header.
+func (p *packetPackerLegacy) PackRetransmission(packet *ackhandler.Packet) ([]*packedPacket, error) {
+	if packet.EncryptionLevel != protocol.EncryptionForwardSecure {
+		p, err := p.packHandshakeRetransmission(packet)
+		return []*packedPacket{p}, err
+	}
+
+	var controlFrames []wire.Frame
+	var streamFrames []*wire.StreamFrame
+	for _, f := range packet.Frames {
+		if sf, ok := f.(*wire.StreamFrame); ok {
+			sf.DataLenPresent = true
+			streamFrames = append(streamFrames, sf)
+		} else {
+			controlFrames = append(controlFrames, f)
+		}
+	}
+
+	var packets []*packedPacket
+	encLevel, sealer := p.cryptoSetup.GetSealer()
+	var swf *wire.StopWaitingFrame
+	// add a STOP_WAITING for *every* retransmission
+	if p.version.UsesStopWaitingFrames() {
+		swf = p.acks.GetStopWaitingFrame(true)
+	}
+	for len(controlFrames) > 0 || len(streamFrames) > 0 {
+		var frames []wire.Frame
+		var length protocol.ByteCount
+
+		header := p.getHeader(encLevel)
+		headerLength, err := header.GetLength(p.version)
+		if err != nil {
+			return nil, err
+		}
+		maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLength
+
+		if p.version.UsesStopWaitingFrames() {
+			// create a new STOP_WAIITNG Frame, since we might need to send more than one packet as a retransmission
+			stopWaitingFrame := &wire.StopWaitingFrame{
+				LeastUnacked:    swf.LeastUnacked,
+				PacketNumber:    header.PacketNumber,
+				PacketNumberLen: header.PacketNumberLen,
+			}
+			length += stopWaitingFrame.Length(p.version)
+			frames = append(frames, stopWaitingFrame)
+		}
+
+		for len(controlFrames) > 0 {
+			frame := controlFrames[0]
+			frameLen := frame.Length(p.version)
+			if length+frameLen > maxSize {
+				break
+			}
+			length += frameLen
+			frames = append(frames, frame)
+			controlFrames = controlFrames[1:]
+		}
+
+		// temporarily increase the maxFrameSize by the (minimum) length of the DataLen field
+		// this leads to a properly sized packet in all cases, since we do all the packet length calculations with StreamFrames that have the DataLen set
+		// however, for the last STREAM frame in the packet, we can omit the DataLen, thus yielding a packet of exactly the correct size
+		maxSize += 2
+
+		for len(streamFrames) > 0 && length+protocol.MinStreamFrameSize < maxSize {
+			frame := streamFrames[0]
+			frameToAdd := frame
+
+			sf, err := frame.MaybeSplitOffFrame(maxSize-length, p.version)
+			if err != nil {
+				return nil, err
+			}
+			if sf != nil {
+				frameToAdd = sf
+			} else {
+				streamFrames = streamFrames[1:]
+			}
+			length += frameToAdd.Length(p.version)
+			frames = append(frames, frameToAdd)
+		}
+		if sf, ok := frames[len(frames)-1].(*wire.StreamFrame); ok {
+			sf.DataLenPresent = false
+		}
+		raw, err := p.writeAndSealPacket(header, frames, sealer)
+		if err != nil {
+			return nil, err
+		}
+		packets = append(packets, &packedPacket{
+			header:          header,
+			raw:             raw,
+			frames:          frames,
+			encryptionLevel: encLevel,
+		})
+	}
+	return packets, nil
+}
+
+// packHandshakeRetransmission retransmits a handshake packet, that was sent with less than forward-secure encryption
+func (p *packetPackerLegacy) packHandshakeRetransmission(packet *ackhandler.Packet) (*packedPacket, error) {
+	sealer, err := p.cryptoSetup.GetSealerWithEncryptionLevel(packet.EncryptionLevel)
+	if err != nil {
+		return nil, err
+	}
+	// make sure that the retransmission for an Initial packet is sent as an Initial packet
+	if packet.PacketType == protocol.PacketTypeInitial {
+		p.hasSentPacket = false
+	}
+	header := p.getHeader(packet.EncryptionLevel)
+	header.Type = packet.PacketType
+	var frames []wire.Frame
+	if p.version.UsesStopWaitingFrames() { // pack a STOP_WAITING first
+		swf := p.acks.GetStopWaitingFrame(true)
+		swf.PacketNumber = header.PacketNumber
+		swf.PacketNumberLen = header.PacketNumberLen
+		frames = append([]wire.Frame{swf}, packet.Frames...)
+	} else {
+		frames = packet.Frames
+	}
+	raw, err := p.writeAndSealPacket(header, frames, sealer)
+	return &packedPacket{
+		header:          header,
+		raw:             raw,
+		frames:          frames,
+		encryptionLevel: packet.EncryptionLevel,
+	}, err
+}
+
+// PackPacket packs a new packet
+// the other controlFrames are sent in the next packet, but might be queued and sent in the next packet if the packet would overflow MaxPacketSize otherwise
+func (p *packetPackerLegacy) PackPacket() (*packedPacket, error) {
+	packet, err := p.maybePackCryptoPacket()
+	if err != nil {
+		return nil, err
+	}
+	if packet != nil {
+		return packet, nil
+	}
+	// if this is the first packet to be send, make sure it contains stream data
+	if !p.hasSentPacket && packet == nil {
+		return nil, nil
+	}
+
+	encLevel, sealer := p.cryptoSetup.GetSealer()
+
+	header := p.getHeader(encLevel)
+	headerLength, err := header.GetLength(p.version)
+	if err != nil {
+		return nil, err
+	}
+
+	maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLength
+	frames, err := p.composeNextPacket(header, maxSize, p.canSendData(encLevel))
+	if err != nil {
+		return nil, err
+	}
+
+	// Check if we have enough frames to send
+	if len(frames) == 0 {
+		return nil, nil
+	}
+	// check if this packet only contains an ACK (and maybe a STOP_WAITING)
+	if !ackhandler.HasRetransmittableFrames(frames) {
+		if p.numNonRetransmittableAcks >= protocol.MaxNonRetransmittableAcks {
+			frames = append(frames, &wire.PingFrame{})
+			p.numNonRetransmittableAcks = 0
+		} else {
+			p.numNonRetransmittableAcks++
+		}
+	} else {
+		p.numNonRetransmittableAcks = 0
+	}
+
+	raw, err := p.writeAndSealPacket(header, frames, sealer)
+	if err != nil {
+		return nil, err
+	}
+	return &packedPacket{
+		header:          header,
+		raw:             raw,
+		frames:          frames,
+		encryptionLevel: encLevel,
+	}, nil
+}
+
+func (p *packetPackerLegacy) maybePackCryptoPacket() (*packedPacket, error) {
+	if !p.cryptoStream.hasData() {
+		return nil, nil
+	}
+	encLevel, sealer := p.cryptoSetup.GetSealerForCryptoStream()
+	header := p.getHeader(encLevel)
+	headerLength, err := header.GetLength(p.version)
+	if err != nil {
+		return nil, err
+	}
+	maxLen := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - protocol.NonForwardSecurePacketSizeReduction - headerLength
+	sf, _ := p.cryptoStream.popStreamFrame(maxLen)
+	sf.DataLenPresent = false
+	frames := []wire.Frame{sf}
+	raw, err := p.writeAndSealPacket(header, frames, sealer)
+	if err != nil {
+		return nil, err
+	}
+	return &packedPacket{
+		header:          header,
+		raw:             raw,
+		frames:          frames,
+		encryptionLevel: encLevel,
+	}, nil
+}
+
+func (p *packetPackerLegacy) composeNextPacket(
+	header *wire.Header, // only needed to fill in the STOP_WAITING frame
+	maxFrameSize protocol.ByteCount,
+	canSendStreamFrames bool,
+) ([]wire.Frame, error) {
+	var length protocol.ByteCount
+	var frames []wire.Frame
+
+	// STOP_WAITING and ACK will always fit
+	// ACKs need to go first, so that the sentPacketHandler will recognize them
+	if ack := p.acks.GetAckFrame(); ack != nil {
+		frames = append(frames, ack)
+		length += ack.Length(p.version)
+		// add a STOP_WAITING, for gQUIC
+		if p.version.UsesStopWaitingFrames() {
+			if swf := p.acks.GetStopWaitingFrame(false); swf != nil {
+				swf.PacketNumber = header.PacketNumber
+				swf.PacketNumberLen = header.PacketNumberLen
+				frames = append(frames, swf)
+				length += swf.Length(p.version)
+			}
+		}
+	}
+
+	var lengthAdded protocol.ByteCount
+	frames, lengthAdded = p.framer.AppendControlFrames(frames, maxFrameSize-length)
+	length += lengthAdded
+
+	if !canSendStreamFrames {
+		return frames, nil
+	}
+
+	// temporarily increase the maxFrameSize by the (minimum) length of the DataLen field
+	// this leads to a properly sized packet in all cases, since we do all the packet length calculations with StreamFrames that have the DataLen set
+	// however, for the last STREAM frame in the packet, we can omit the DataLen, thus yielding a packet of exactly the correct size
+	maxFrameSize += 2
+
+	frames = p.framer.AppendStreamFrames(frames, maxFrameSize-length)
+	if len(frames) > 0 {
+		lastFrame := frames[len(frames)-1]
+		if sf, ok := lastFrame.(*wire.StreamFrame); ok {
+			sf.DataLenPresent = false
+		}
+	}
+	return frames, nil
+}
+
+func (p *packetPackerLegacy) getHeader(encLevel protocol.EncryptionLevel) *wire.Header {
+	pnum := p.packetNumberGenerator.Peek()
+	packetNumberLen := p.getPacketNumberLen(pnum)
+
+	header := &wire.Header{
+		PacketNumber:    pnum,
+		PacketNumberLen: packetNumberLen,
+		Version:         p.version,
+	}
+
+	if p.version.UsesIETFHeaderFormat() && encLevel != protocol.EncryptionForwardSecure {
+		header.IsLongHeader = true
+		header.SrcConnectionID = p.srcConnID
+		header.PacketNumberLen = protocol.PacketNumberLen4
+		if !p.hasSentPacket && p.perspective == protocol.PerspectiveClient {
+			header.Type = protocol.PacketTypeInitial
+		} else {
+			header.Type = protocol.PacketTypeHandshake
+		}
+	}
+
+	if !p.omitConnectionID || encLevel != protocol.EncryptionForwardSecure {
+		header.DestConnectionID = p.destConnID
+	}
+	if p.perspective == protocol.PerspectiveServer && encLevel == protocol.EncryptionSecure {
+		header.Type = protocol.PacketType0RTT
+		header.DiversificationNonce = p.divNonce
+	}
+	if p.perspective == protocol.PerspectiveClient && encLevel != protocol.EncryptionForwardSecure {
+		header.VersionFlag = true
+	}
+	return header
+}
+
+func (p *packetPackerLegacy) writeAndSealPacket(
+	header *wire.Header,
+	frames []wire.Frame,
+	sealer handshake.Sealer,
+) ([]byte, error) {
+	raw := *getPacketBuffer()
+	buffer := bytes.NewBuffer(raw[:0])
+
+	if err := header.Write(buffer, p.perspective, p.version); err != nil {
+		return nil, err
+	}
+	payloadStartIndex := buffer.Len()
+
+	for _, frame := range frames {
+		if err := frame.Write(buffer, p.version); err != nil {
+			return nil, err
+		}
+	}
+
+	if size := protocol.ByteCount(buffer.Len() + sealer.Overhead()); size > p.maxPacketSize {
+		return nil, fmt.Errorf("PacketPacker BUG: packet too large (%d bytes, allowed %d bytes)", size, p.maxPacketSize)
+	}
+
+	raw = raw[0:buffer.Len()]
+	_ = sealer.Seal(raw[payloadStartIndex:payloadStartIndex], raw[payloadStartIndex:], header.PacketNumber, raw[:payloadStartIndex])
+	raw = raw[0 : buffer.Len()+sealer.Overhead()]
+
+	num := p.packetNumberGenerator.Pop()
+	if num != header.PacketNumber {
+		return nil, errors.New("packetPacker BUG: Peeked and Popped packet numbers do not match")
+	}
+	p.hasSentPacket = true
+	return raw, nil
+}
+
+func (p *packetPackerLegacy) canSendData(encLevel protocol.EncryptionLevel) bool {
+	if p.perspective == protocol.PerspectiveClient {
+		return encLevel >= protocol.EncryptionSecure
+	}
+	return encLevel == protocol.EncryptionForwardSecure
+}
+
+func (p *packetPackerLegacy) ChangeDestConnectionID(connID protocol.ConnectionID) {
+	panic("changing connection IDs not supported by gQUIC")
+}
+
+func (p *packetPackerLegacy) HandleTransportParameters(params *handshake.TransportParameters) {
+	p.omitConnectionID = params.OmitConnectionID
+}

+ 17 - 12
vendor/github.com/lucas-clemente/quic-go/receive_stream.go

@@ -8,6 +8,7 @@ import (
 
 	"github.com/lucas-clemente/quic-go/internal/flowcontrol"
 	"github.com/lucas-clemente/quic-go/internal/protocol"
+	"github.com/lucas-clemente/quic-go/internal/utils"
 	"github.com/lucas-clemente/quic-go/internal/wire"
 )
 
@@ -43,8 +44,8 @@ type receiveStream struct {
 	canceledRead      bool // set when CancelRead() is called
 	resetRemotely     bool // set when HandleRstStreamFrame() is called
 
-	readChan     chan struct{}
-	readDeadline time.Time
+	readChan chan struct{}
+	deadline time.Time
 
 	flowController flowcontrol.StreamFlowController
 	version        protocol.VersionNumber
@@ -108,6 +109,7 @@ func (s *receiveStream) readImpl(p []byte) (bool /*stream completed */, int, err
 			return false, bytesRead, s.closeForShutdownErr
 		}
 
+		var deadlineTimer *utils.Timer
 		for {
 			// Stop waiting on errors
 			if s.closedForShutdown {
@@ -120,9 +122,15 @@ func (s *receiveStream) readImpl(p []byte) (bool /*stream completed */, int, err
 				return false, bytesRead, s.resetRemotelyErr
 			}
 
-			deadline := s.readDeadline
-			if !deadline.IsZero() && !time.Now().Before(deadline) {
-				return false, bytesRead, errDeadline
+			deadline := s.deadline
+			if !deadline.IsZero() {
+				if !time.Now().Before(deadline) {
+					return false, bytesRead, errDeadline
+				}
+				if deadlineTimer == nil {
+					deadlineTimer = utils.NewTimer()
+				}
+				deadlineTimer.Reset(deadline)
 			}
 
 			if s.currentFrame != nil || s.currentFrameIsLast {
@@ -135,7 +143,8 @@ func (s *receiveStream) readImpl(p []byte) (bool /*stream completed */, int, err
 			} else {
 				select {
 				case <-s.readChan:
-				case <-time.After(time.Until(deadline)):
+				case <-deadlineTimer.Chan():
+					deadlineTimer.SetRead()
 				}
 			}
 			s.mutex.Lock()
@@ -272,13 +281,9 @@ func (s *receiveStream) onClose(offset protocol.ByteCount) {
 
 func (s *receiveStream) SetReadDeadline(t time.Time) error {
 	s.mutex.Lock()
-	oldDeadline := s.readDeadline
-	s.readDeadline = t
+	s.deadline = t
 	s.mutex.Unlock()
-	// if the new deadline is before the currently set deadline, wake up Read()
-	if t.Before(oldDeadline) {
-		s.signalRead()
-	}
+	s.signalRead()
 	return nil
 }
 

+ 44 - 31
vendor/github.com/lucas-clemente/quic-go/send_stream.go

@@ -41,8 +41,9 @@ type sendStream struct {
 	finSent           bool // set when a STREAM_FRAME with FIN bit has b
 
 	dataForWriting []byte
-	writeChan      chan struct{}
-	writeDeadline  time.Time
+
+	writeChan chan struct{}
+	deadline  time.Time
 
 	flowController flowcontrol.StreamFlowController
 
@@ -86,49 +87,60 @@ func (s *sendStream) Write(p []byte) (int, error) {
 	if s.closeForShutdownErr != nil {
 		return 0, s.closeForShutdownErr
 	}
-	if !s.writeDeadline.IsZero() && !time.Now().Before(s.writeDeadline) {
+	if !s.deadline.IsZero() && !time.Now().Before(s.deadline) {
 		return 0, errDeadline
 	}
 	if len(p) == 0 {
 		return 0, nil
 	}
 
-	s.dataForWriting = make([]byte, len(p))
-	copy(s.dataForWriting, p)
-	s.sender.onHasStreamData(s.streamID)
+	s.dataForWriting = p
 
-	var bytesWritten int
-	var err error
+	var (
+		deadlineTimer  *utils.Timer
+		bytesWritten   int
+		notifiedSender bool
+	)
 	for {
 		bytesWritten = len(p) - len(s.dataForWriting)
-		deadline := s.writeDeadline
-		if !deadline.IsZero() && !time.Now().Before(deadline) {
-			s.dataForWriting = nil
-			err = errDeadline
-			break
+		deadline := s.deadline
+		if !deadline.IsZero() {
+			if !time.Now().Before(deadline) {
+				s.dataForWriting = nil
+				return bytesWritten, errDeadline
+			}
+			if deadlineTimer == nil {
+				deadlineTimer = utils.NewTimer()
+			}
+			deadlineTimer.Reset(deadline)
 		}
 		if s.dataForWriting == nil || s.canceledWrite || s.closedForShutdown {
 			break
 		}
 
 		s.mutex.Unlock()
+		if !notifiedSender {
+			s.sender.onHasStreamData(s.streamID) // must be called without holding the mutex
+			notifiedSender = true
+		}
 		if deadline.IsZero() {
 			<-s.writeChan
 		} else {
 			select {
 			case <-s.writeChan:
-			case <-time.After(time.Until(deadline)):
+			case <-deadlineTimer.Chan():
+				deadlineTimer.SetRead()
 			}
 		}
 		s.mutex.Lock()
 	}
 
 	if s.closeForShutdownErr != nil {
-		err = s.closeForShutdownErr
+		return bytesWritten, s.closeForShutdownErr
 	} else if s.cancelWriteErr != nil {
-		err = s.cancelWriteErr
+		return bytesWritten, s.cancelWriteErr
 	}
-	return bytesWritten, err
+	return bytesWritten, nil
 }
 
 // popStreamFrame returns the next STREAM frame that is supposed to be sent on this stream
@@ -203,10 +215,12 @@ func (s *sendStream) getDataForWriting(maxBytes protocol.ByteCount) ([]byte, boo
 
 	var ret []byte
 	if protocol.ByteCount(len(s.dataForWriting)) > maxBytes {
-		ret = s.dataForWriting[:maxBytes]
+		ret = make([]byte, int(maxBytes))
+		copy(ret, s.dataForWriting[:maxBytes])
 		s.dataForWriting = s.dataForWriting[maxBytes:]
 	} else {
-		ret = s.dataForWriting
+		ret = make([]byte, len(s.dataForWriting))
+		copy(ret, s.dataForWriting)
 		s.dataForWriting = nil
 		s.signalWrite()
 	}
@@ -217,13 +231,14 @@ func (s *sendStream) getDataForWriting(maxBytes protocol.ByteCount) ([]byte, boo
 
 func (s *sendStream) Close() error {
 	s.mutex.Lock()
-	defer s.mutex.Unlock()
-
 	if s.canceledWrite {
+		s.mutex.Unlock()
 		return fmt.Errorf("Close called for canceled stream %d", s.streamID)
 	}
 	s.finishedWriting = true
-	s.sender.onHasStreamData(s.streamID) // need to send the FIN
+	s.mutex.Unlock()
+
+	s.sender.onHasStreamData(s.streamID) // need to send the FIN, must be called without holding the mutex
 	s.ctxCancel()
 	return nil
 }
@@ -234,7 +249,7 @@ func (s *sendStream) CancelWrite(errorCode protocol.ApplicationErrorCode) error
 	s.mutex.Unlock()
 
 	if completed {
-		s.sender.onStreamCompleted(s.streamID)
+		s.sender.onStreamCompleted(s.streamID) // must be called without holding the mutex
 	}
 	return err
 }
@@ -267,12 +282,13 @@ func (s *sendStream) handleStopSendingFrame(frame *wire.StopSendingFrame) {
 }
 
 func (s *sendStream) handleMaxStreamDataFrame(frame *wire.MaxStreamDataFrame) {
-	s.flowController.UpdateSendWindow(frame.ByteOffset)
 	s.mutex.Lock()
-	if s.dataForWriting != nil {
+	hasStreamData := s.dataForWriting != nil
+	s.mutex.Unlock()
+	s.flowController.UpdateSendWindow(frame.ByteOffset)
+	if hasStreamData {
 		s.sender.onHasStreamData(s.streamID)
 	}
-	s.mutex.Unlock()
 }
 
 // must be called after locking the mutex
@@ -298,12 +314,9 @@ func (s *sendStream) Context() context.Context {
 
 func (s *sendStream) SetWriteDeadline(t time.Time) error {
 	s.mutex.Lock()
-	oldDeadline := s.writeDeadline
-	s.writeDeadline = t
+	s.deadline = t
 	s.mutex.Unlock()
-	if t.Before(oldDeadline) {
-		s.signalWrite()
-	}
+	s.signalWrite()
 	return nil
 }
 

+ 3 - 0
vendor/github.com/lucas-clemente/quic-go/server.go

@@ -123,6 +123,9 @@ func Listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (Listener,
 }
 
 func listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (*server, error) {
+	if tlsConf == nil || (len(tlsConf.Certificates) == 0 && tlsConf.GetCertificate == nil) {
+		return nil, errors.New("quic: neither Certificates nor GetCertificate set in tls.Config")
+	}
 	certChain := crypto.NewCertChain(tlsConf)
 	kex, err := crypto.NewCurve25519KEX()
 	if err != nil {

+ 3 - 6
vendor/github.com/lucas-clemente/quic-go/server_tls.go

@@ -25,7 +25,7 @@ type serverTLS struct {
 	params          *handshake.TransportParameters
 	cookieGenerator *handshake.CookieGenerator
 
-	newSession func(connection, sessionRunner, protocol.ConnectionID, protocol.ConnectionID, protocol.ConnectionID, protocol.PacketNumber, *Config, *mint.Config, *handshake.TransportParameters, utils.Logger, protocol.VersionNumber) (quicSession, error)
+	newSession func(connection, sessionRunner, protocol.ConnectionID, protocol.ConnectionID, protocol.ConnectionID, protocol.PacketNumber, *Config, *mint.Config, <-chan handshake.TransportParameters, utils.Logger, protocol.VersionNumber) (quicSession, error)
 
 	sessionRunner sessionRunner
 	sessionChan   chan<- tlsSession
@@ -118,9 +118,6 @@ func (s *serverTLS) handleInitialImpl(p *receivedPacket) (quicSession, protocol.
 	mconf := s.mintConf.Clone()
 	mconf.ExtensionHandler = extHandler
 
-	// A server is allowed to perform multiple Retries.
-	// It doesn't make much sense, but it's something that our API allows.
-	// In that case it must use a source connection ID of at least 8 bytes.
 	connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength)
 	if err != nil {
 		return nil, nil, err
@@ -135,7 +132,7 @@ func (s *serverTLS) handleInitialImpl(p *receivedPacket) (quicSession, protocol.
 		1,
 		s.config,
 		mconf,
-		s.params,
+		extHandler.GetPeerParams(),
 		s.logger,
 		hdr.Version,
 	)
@@ -152,7 +149,7 @@ func (s *serverTLS) sendRetry(remoteAddr net.Addr, hdr *wire.Header) error {
 	if err != nil {
 		return err
 	}
-	connID, err := protocol.GenerateConnectionIDForInitial()
+	connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength)
 	if err != nil {
 		return err
 	}

+ 4 - 11
vendor/github.com/lucas-clemente/quic-go/session.go

@@ -206,13 +206,11 @@ func newSession(
 	s.unpacker = newPacketUnpackerGQUIC(cs, s.version)
 	s.streamsMap = newStreamsMapLegacy(s.newStream, s.config.MaxIncomingStreams, s.perspective)
 	s.framer = newFramer(s.cryptoStream, s.streamsMap, s.version)
-	s.packer = newPacketPacker(
+	s.packer = newPacketPackerLegacy(
 		destConnID,
 		srcConnID,
-		1,
 		s.sentPacketHandler.GetPacketNumberLen,
 		s.RemoteAddr(),
-		nil, // no token
 		divNonce,
 		s.cryptoStream,
 		cs,
@@ -279,13 +277,11 @@ var newClientSession = func(
 	s.unpacker = newPacketUnpackerGQUIC(cs, s.version)
 	s.streamsMap = newStreamsMapLegacy(s.newStream, s.config.MaxIncomingStreams, s.perspective)
 	s.framer = newFramer(s.cryptoStream, s.streamsMap, s.version)
-	s.packer = newPacketPacker(
+	s.packer = newPacketPackerLegacy(
 		destConnID,
 		srcConnID,
-		1,
 		s.sentPacketHandler.GetPacketNumberLen,
 		s.RemoteAddr(),
-		nil, // no token
 		nil, // no diversification nonce
 		s.cryptoStream,
 		cs,
@@ -306,7 +302,7 @@ func newTLSServerSession(
 	initialPacketNumber protocol.PacketNumber,
 	config *Config,
 	mintConf *mint.Config,
-	peerParams *handshake.TransportParameters,
+	paramsChan <-chan handshake.TransportParameters,
 	logger utils.Logger,
 	v protocol.VersionNumber,
 ) (quicSession, error) {
@@ -320,6 +316,7 @@ func newTLSServerSession(
 		perspective:    protocol.PerspectiveServer,
 		version:        v,
 		handshakeEvent: handshakeEvent,
+		paramsChan:     paramsChan,
 		logger:         logger,
 	}
 	s.preSetup()
@@ -343,7 +340,6 @@ func newTLSServerSession(
 		s.sentPacketHandler.GetPacketNumberLen,
 		s.RemoteAddr(),
 		nil, // no token
-		nil, // no diversification nonce
 		s.cryptoStream,
 		cs,
 		s.framer,
@@ -354,8 +350,6 @@ func newTLSServerSession(
 	if err := s.postSetup(); err != nil {
 		return nil, err
 	}
-	s.peerParams = peerParams
-	s.processTransportParameters(peerParams)
 	s.unpacker = newPacketUnpacker(cs, s.version)
 	return s, nil
 }
@@ -409,7 +403,6 @@ var newTLSClientSession = func(
 		s.sentPacketHandler.GetPacketNumberLen,
 		s.RemoteAddr(),
 		token,
-		nil, // no diversification nonce
 		s.cryptoStream,
 		cs,
 		s.framer,

+ 47 - 27
vendor/vendor.json

@@ -285,10 +285,12 @@
 			"revisionTime": "2017-10-27T16:34:21Z"
 		},
 		{
-			"checksumSHA1": "escUmRFlk6I1tqI7WLOBSm3y8vk=",
+			"checksumSHA1": "PbxxDGeoep1NC9ueE44z2Z4YDdQ=",
 			"path": "github.com/lucas-clemente/quic-go",
-			"revision": "225106b58c78ac8aaad497c98f1ca7021a4e57b3",
-			"revisionTime": "2018-10-09T08:30:24Z"
+			"revision": "24fed6dc9757399d276689fb4008b09e51f69308",
+			"revisionTime": "2019-04-16T05:23:26Z",
+			"version": "=gquic",
+			"versionExact": "gquic"
 		},
 		{
 			"checksumSHA1": "OA9E+y7g05x/mWJJHmA7oPxWKQo=",
@@ -297,58 +299,76 @@
 			"revisionTime": "2016-08-23T09:51:56Z"
 		},
 		{
-			"checksumSHA1": "KHLnkk73j1KLvolUEJvJgVcg+4I=",
+			"checksumSHA1": "3ln/ewUovXrNnPySlGTJ/tqaAcU=",
 			"path": "github.com/lucas-clemente/quic-go/internal/ackhandler",
-			"revision": "225106b58c78ac8aaad497c98f1ca7021a4e57b3",
-			"revisionTime": "2018-10-09T08:30:24Z"
+			"revision": "24fed6dc9757399d276689fb4008b09e51f69308",
+			"revisionTime": "2019-04-16T05:23:26Z",
+			"version": "=gquic",
+			"versionExact": "gquic"
 		},
 		{
-			"checksumSHA1": "y6iH4e+f/o//eL6f8xwxSe9Q3FI=",
+			"checksumSHA1": "S88pE/UIJ2FI6DQ9qKe9hMBddlE=",
 			"path": "github.com/lucas-clemente/quic-go/internal/congestion",
-			"revision": "225106b58c78ac8aaad497c98f1ca7021a4e57b3",
-			"revisionTime": "2018-10-09T08:30:24Z"
+			"revision": "24fed6dc9757399d276689fb4008b09e51f69308",
+			"revisionTime": "2019-04-16T05:23:26Z",
+			"version": "=gquic",
+			"versionExact": "gquic"
 		},
 		{
-			"checksumSHA1": "YbTMl8MrfTJdm6ZlnXIIPUSTT/w=",
+			"checksumSHA1": "55QOkMYhfNrMVHNSG2PiDoAznnM=",
 			"path": "github.com/lucas-clemente/quic-go/internal/crypto",
-			"revision": "225106b58c78ac8aaad497c98f1ca7021a4e57b3",
-			"revisionTime": "2018-10-09T08:30:24Z"
+			"revision": "24fed6dc9757399d276689fb4008b09e51f69308",
+			"revisionTime": "2019-04-16T05:23:26Z",
+			"version": "=gquic",
+			"versionExact": "gquic"
 		},
 		{
 			"checksumSHA1": "hLazAfY6qHoV3USMxA7pSPnTqy8=",
 			"path": "github.com/lucas-clemente/quic-go/internal/flowcontrol",
-			"revision": "225106b58c78ac8aaad497c98f1ca7021a4e57b3",
-			"revisionTime": "2018-10-09T08:30:24Z"
+			"revision": "24fed6dc9757399d276689fb4008b09e51f69308",
+			"revisionTime": "2019-04-16T05:23:26Z",
+			"version": "=gquic",
+			"versionExact": "gquic"
 		},
 		{
-			"checksumSHA1": "VVbSeFKYFd5OHQVK+O5KDqANnb0=",
+			"checksumSHA1": "xZvDRCL3QmKLqPc8DL7N8Y7nFSY=",
 			"path": "github.com/lucas-clemente/quic-go/internal/handshake",
-			"revision": "225106b58c78ac8aaad497c98f1ca7021a4e57b3",
-			"revisionTime": "2018-10-09T08:30:24Z"
+			"revision": "24fed6dc9757399d276689fb4008b09e51f69308",
+			"revisionTime": "2019-04-16T05:23:26Z",
+			"version": "=gquic",
+			"versionExact": "gquic"
 		},
 		{
-			"checksumSHA1": "jG7h6FwuKQgXQI+pgymjud5m3Co=",
+			"checksumSHA1": "l/5aZg9t6+W1uThZk20Fn4/NUCo=",
 			"path": "github.com/lucas-clemente/quic-go/internal/protocol",
-			"revision": "225106b58c78ac8aaad497c98f1ca7021a4e57b3",
-			"revisionTime": "2018-10-09T08:30:24Z"
+			"revision": "24fed6dc9757399d276689fb4008b09e51f69308",
+			"revisionTime": "2019-04-16T05:23:26Z",
+			"version": "=gquic",
+			"versionExact": "gquic"
 		},
 		{
-			"checksumSHA1": "0vSbWIQ7O34u4kDMR+FHr7/FINk=",
+			"checksumSHA1": "EYJC4eRzEgVdumThw5ApaAVx7/M=",
 			"path": "github.com/lucas-clemente/quic-go/internal/utils",
-			"revision": "225106b58c78ac8aaad497c98f1ca7021a4e57b3",
-			"revisionTime": "2018-10-09T08:30:24Z"
+			"revision": "24fed6dc9757399d276689fb4008b09e51f69308",
+			"revisionTime": "2019-04-16T05:23:26Z",
+			"version": "=gquic",
+			"versionExact": "gquic"
 		},
 		{
 			"checksumSHA1": "XgecNbm4PtsEfUDX2unzmKE/nGA=",
 			"path": "github.com/lucas-clemente/quic-go/internal/wire",
-			"revision": "225106b58c78ac8aaad497c98f1ca7021a4e57b3",
-			"revisionTime": "2018-10-09T08:30:24Z"
+			"revision": "24fed6dc9757399d276689fb4008b09e51f69308",
+			"revisionTime": "2019-04-16T05:23:26Z",
+			"version": "=gquic",
+			"versionExact": "gquic"
 		},
 		{
 			"checksumSHA1": "bFSC4TOZGOZGBJEFmLAT3V4ieoo=",
 			"path": "github.com/lucas-clemente/quic-go/qerr",
-			"revision": "225106b58c78ac8aaad497c98f1ca7021a4e57b3",
-			"revisionTime": "2018-10-09T08:30:24Z"
+			"revision": "24fed6dc9757399d276689fb4008b09e51f69308",
+			"revisionTime": "2019-04-16T05:23:26Z",
+			"version": "=gquic",
+			"versionExact": "gquic"
 		},
 		{
 			"checksumSHA1": "sY8sshVIEXnJgg3S6C5FcN33Vq4=",