mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-01 00:23:48 +03:00
vendor: Update quic-go
This commit is contained in:
parent
95514da91b
commit
1580169e2b
66 changed files with 1423 additions and 720 deletions
13
vendor/github.com/lucas-clemente/quic-go/buffer_pool.go
generated
vendored
13
vendor/github.com/lucas-clemente/quic-go/buffer_pool.go
generated
vendored
|
@ -8,19 +8,20 @@ import (
|
|||
|
||||
var bufferPool sync.Pool
|
||||
|
||||
func getPacketBuffer() []byte {
|
||||
return bufferPool.Get().([]byte)
|
||||
func getPacketBuffer() *[]byte {
|
||||
return bufferPool.Get().(*[]byte)
|
||||
}
|
||||
|
||||
func putPacketBuffer(buf []byte) {
|
||||
if cap(buf) != int(protocol.MaxReceivePacketSize) {
|
||||
func putPacketBuffer(buf *[]byte) {
|
||||
if cap(*buf) != int(protocol.MaxReceivePacketSize) {
|
||||
panic("putPacketBuffer called with packet of wrong size!")
|
||||
}
|
||||
bufferPool.Put(buf[:0])
|
||||
bufferPool.Put(buf)
|
||||
}
|
||||
|
||||
func init() {
|
||||
bufferPool.New = func() interface{} {
|
||||
return make([]byte, 0, protocol.MaxReceivePacketSize)
|
||||
b := make([]byte, 0, protocol.MaxReceivePacketSize)
|
||||
return &b
|
||||
}
|
||||
}
|
||||
|
|
33
vendor/github.com/lucas-clemente/quic-go/client.go
generated
vendored
33
vendor/github.com/lucas-clemente/quic-go/client.go
generated
vendored
|
@ -85,6 +85,14 @@ func Dial(
|
|||
}
|
||||
}
|
||||
|
||||
// check that all versions are actually supported
|
||||
if config != nil {
|
||||
for _, v := range config.Versions {
|
||||
if !protocol.IsValidVersion(v) {
|
||||
return nil, fmt.Errorf("%s is not a valid QUIC version", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
clientConfig := populateClientConfig(config)
|
||||
c := &client{
|
||||
conn: &conn{pconn: pconn, currentAddr: remoteAddr},
|
||||
|
@ -132,6 +140,18 @@ func populateClientConfig(config *Config) *Config {
|
|||
if maxReceiveConnectionFlowControlWindow == 0 {
|
||||
maxReceiveConnectionFlowControlWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindowClient
|
||||
}
|
||||
maxIncomingStreams := config.MaxIncomingStreams
|
||||
if maxIncomingStreams == 0 {
|
||||
maxIncomingStreams = protocol.DefaultMaxIncomingStreams
|
||||
} else if maxIncomingStreams < 0 {
|
||||
maxIncomingStreams = 0
|
||||
}
|
||||
maxIncomingUniStreams := config.MaxIncomingUniStreams
|
||||
if maxIncomingUniStreams == 0 {
|
||||
maxIncomingUniStreams = protocol.DefaultMaxIncomingUniStreams
|
||||
} else if maxIncomingUniStreams < 0 {
|
||||
maxIncomingUniStreams = 0
|
||||
}
|
||||
|
||||
return &Config{
|
||||
Versions: versions,
|
||||
|
@ -140,7 +160,9 @@ func populateClientConfig(config *Config) *Config {
|
|||
RequestConnectionIDOmission: config.RequestConnectionIDOmission,
|
||||
MaxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow,
|
||||
MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow,
|
||||
KeepAlive: config.KeepAlive,
|
||||
MaxIncomingStreams: maxIncomingStreams,
|
||||
MaxIncomingUniStreams: maxIncomingUniStreams,
|
||||
KeepAlive: config.KeepAlive,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,9 +193,8 @@ func (c *client) dialTLS() error {
|
|||
ConnectionFlowControlWindow: protocol.ReceiveConnectionFlowControlWindow,
|
||||
IdleTimeout: c.config.IdleTimeout,
|
||||
OmitConnectionID: c.config.RequestConnectionIDOmission,
|
||||
// TODO(#523): make these values configurable
|
||||
MaxBidiStreamID: protocol.MaxBidiStreamID(protocol.MaxIncomingStreams, protocol.PerspectiveClient),
|
||||
MaxUniStreamID: protocol.MaxUniStreamID(protocol.MaxIncomingStreams, protocol.PerspectiveClient),
|
||||
MaxBidiStreams: uint16(c.config.MaxIncomingStreams),
|
||||
MaxUniStreams: uint16(c.config.MaxIncomingUniStreams),
|
||||
}
|
||||
csc := handshake.NewCryptoStreamConn(nil)
|
||||
extHandler := handshake.NewExtensionHandlerClient(params, c.initialVersion, c.config.Versions, c.version)
|
||||
|
@ -245,7 +266,7 @@ func (c *client) listen() {
|
|||
for {
|
||||
var n int
|
||||
var addr net.Addr
|
||||
data := getPacketBuffer()
|
||||
data := *getPacketBuffer()
|
||||
data = data[:protocol.MaxReceivePacketSize]
|
||||
// The packet size should not exceed protocol.MaxReceivePacketSize bytes
|
||||
// If it does, we only read a truncated packet, which will then end up undecryptable
|
||||
|
@ -347,6 +368,8 @@ func (c *client) handleVersionNegotiationPacket(hdr *wire.Header) error {
|
|||
}
|
||||
}
|
||||
|
||||
utils.Infof("Received a Version Negotiation Packet. Supported Versions: %s", hdr.SupportedVersions)
|
||||
|
||||
newVersion, ok := protocol.ChooseSupportedVersion(c.config.Versions, hdr.SupportedVersions)
|
||||
if !ok {
|
||||
return qerr.InvalidVersion
|
||||
|
|
15
vendor/github.com/lucas-clemente/quic-go/h2quic/client.go
generated
vendored
15
vendor/github.com/lucas-clemente/quic-go/h2quic/client.go
generated
vendored
|
@ -108,7 +108,9 @@ func (c *client) handleHeaderStream() {
|
|||
for err == nil {
|
||||
err = c.readResponse(h2framer, decoder)
|
||||
}
|
||||
utils.Debugf("Error handling header stream: %s", err)
|
||||
if quicErr, ok := err.(*qerr.QuicError); !ok || quicErr.ErrorCode != qerr.PeerGoingAway {
|
||||
utils.Debugf("Error handling header stream: %s", err)
|
||||
}
|
||||
c.headerErr = qerr.Error(qerr.InvalidHeadersStreamData, err.Error())
|
||||
// stop all running request
|
||||
close(c.headerErrored)
|
||||
|
@ -202,6 +204,7 @@ func (c *client) RoundTrip(req *http.Request) (*http.Response, error) {
|
|||
bodySent = true
|
||||
}
|
||||
|
||||
ctx := req.Context()
|
||||
for !(bodySent && receivedResponse) {
|
||||
select {
|
||||
case res = <-responseChan:
|
||||
|
@ -214,8 +217,16 @@ func (c *client) RoundTrip(req *http.Request) (*http.Response, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case <-ctx.Done():
|
||||
// error code 6 signals that stream was canceled
|
||||
dataStream.CancelRead(6)
|
||||
dataStream.CancelWrite(6)
|
||||
c.mutex.Lock()
|
||||
delete(c.responses, dataStream.StreamID())
|
||||
c.mutex.Unlock()
|
||||
return nil, ctx.Err()
|
||||
case <-c.headerErrored:
|
||||
// an error occured on the header stream
|
||||
// an error occurred on the header stream
|
||||
_ = c.CloseWithError(c.headerErr)
|
||||
return nil, c.headerErr
|
||||
}
|
||||
|
|
3
vendor/github.com/lucas-clemente/quic-go/h2quic/request_writer.go
generated
vendored
3
vendor/github.com/lucas-clemente/quic-go/h2quic/request_writer.go
generated
vendored
|
@ -76,9 +76,8 @@ func (w *requestWriter) encodeHeaders(req *http.Request, addGzipHeader bool, tra
|
|||
if !validPseudoPath(path) {
|
||||
if req.URL.Opaque != "" {
|
||||
return nil, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque)
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid request :path %q", orig)
|
||||
}
|
||||
return nil, fmt.Errorf("invalid request :path %q", orig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
20
vendor/github.com/lucas-clemente/quic-go/h2quic/response.go
generated
vendored
20
vendor/github.com/lucas-clemente/quic-go/h2quic/response.go
generated
vendored
|
@ -3,7 +3,6 @@ package h2quic
|
|||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
|
@ -16,7 +15,7 @@ import (
|
|||
// copied from net/http2/transport.go
|
||||
|
||||
var errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit")
|
||||
var noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil))
|
||||
var noBody = ioutil.NopCloser(bytes.NewReader(nil))
|
||||
|
||||
// from the handleResponse function
|
||||
func responseFromHeaders(f *http2.MetaHeadersFrame) (*http.Response, error) {
|
||||
|
@ -33,16 +32,7 @@ func responseFromHeaders(f *http2.MetaHeadersFrame) (*http.Response, error) {
|
|||
return nil, errors.New("malformed non-numeric status pseudo header")
|
||||
}
|
||||
|
||||
if statusCode == 100 {
|
||||
// TODO: handle this
|
||||
|
||||
// traceGot100Continue(cs.trace)
|
||||
// if cs.on100 != nil {
|
||||
// cs.on100() // forces any write delay timer to fire
|
||||
// }
|
||||
// cs.pastHeaders = false // do it all again
|
||||
// return nil, nil
|
||||
}
|
||||
// TODO: handle statusCode == 100
|
||||
|
||||
header := make(http.Header)
|
||||
res := &http.Response{
|
||||
|
@ -78,13 +68,7 @@ func setLength(res *http.Response, isHead, streamEnded bool) *http.Response {
|
|||
if clens := res.Header["Content-Length"]; len(clens) == 1 {
|
||||
if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil {
|
||||
res.ContentLength = clen64
|
||||
} else {
|
||||
// TODO: care? unlike http/1, it won't mess up our framing, so it's
|
||||
// more safe smuggling-wise to ignore.
|
||||
}
|
||||
} else if len(clens) > 1 {
|
||||
// TODO: care? unlike http/1, it won't mess up our framing, so it's
|
||||
// more safe smuggling-wise to ignore.
|
||||
}
|
||||
}
|
||||
return res
|
||||
|
|
35
vendor/github.com/lucas-clemente/quic-go/integrationtests/tools/proxy/proxy.go
generated
vendored
35
vendor/github.com/lucas-clemente/quic-go/integrationtests/tools/proxy/proxy.go
generated
vendored
|
@ -7,6 +7,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
)
|
||||
|
||||
// Connection is a UDP connection
|
||||
|
@ -43,6 +44,8 @@ func (d Direction) String() string {
|
|||
}
|
||||
}
|
||||
|
||||
// Is says if one direction matches another direction.
|
||||
// For example, incoming matches both incoming and both, but not outgoing.
|
||||
func (d Direction) Is(dir Direction) bool {
|
||||
if d == DirectionBoth || dir == DirectionBoth {
|
||||
return true
|
||||
|
@ -131,12 +134,20 @@ func NewQuicProxy(local string, version protocol.VersionNumber, opts *Opts) (*Qu
|
|||
version: version,
|
||||
}
|
||||
|
||||
utils.Debugf("Starting UDP Proxy %s <-> %s", conn.LocalAddr(), raddr)
|
||||
go p.runProxy()
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
// Close stops the UDP Proxy
|
||||
func (p *QuicProxy) Close() error {
|
||||
p.mutex.Lock()
|
||||
defer p.mutex.Unlock()
|
||||
for _, c := range p.clientDict {
|
||||
if err := c.ServerConn.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return p.conn.Close()
|
||||
}
|
||||
|
||||
|
@ -189,19 +200,27 @@ func (p *QuicProxy) runProxy() error {
|
|||
packetCount := atomic.AddUint64(&conn.incomingPacketCounter, 1)
|
||||
|
||||
if p.dropPacket(DirectionIncoming, packetCount) {
|
||||
if utils.Debug() {
|
||||
utils.Debugf("dropping incoming packet %d (%d bytes)", packetCount, n)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Send the packet to the server
|
||||
delay := p.delayPacket(DirectionIncoming, packetCount)
|
||||
if delay != 0 {
|
||||
if utils.Debug() {
|
||||
utils.Debugf("delaying incoming packet %d (%d bytes) to %s by %s", packetCount, n, conn.ServerConn.RemoteAddr(), delay)
|
||||
}
|
||||
time.AfterFunc(delay, func() {
|
||||
// TODO: handle error
|
||||
_, _ = conn.ServerConn.Write(raw)
|
||||
})
|
||||
} else {
|
||||
_, err := conn.ServerConn.Write(raw)
|
||||
if err != nil {
|
||||
if utils.Debug() {
|
||||
utils.Debugf("forwarding incoming packet %d (%d bytes) to %s", packetCount, n, conn.ServerConn.RemoteAddr())
|
||||
}
|
||||
if _, err := conn.ServerConn.Write(raw); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -221,18 +240,26 @@ func (p *QuicProxy) runConnection(conn *connection) error {
|
|||
packetCount := atomic.AddUint64(&conn.outgoingPacketCounter, 1)
|
||||
|
||||
if p.dropPacket(DirectionOutgoing, packetCount) {
|
||||
if utils.Debug() {
|
||||
utils.Debugf("dropping outgoing packet %d (%d bytes)", packetCount, n)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
delay := p.delayPacket(DirectionOutgoing, packetCount)
|
||||
if delay != 0 {
|
||||
if utils.Debug() {
|
||||
utils.Debugf("delaying outgoing packet %d (%d bytes) to %s by %s", packetCount, n, conn.ClientAddr, delay)
|
||||
}
|
||||
time.AfterFunc(delay, func() {
|
||||
// TODO: handle error
|
||||
_, _ = p.conn.WriteToUDP(raw, conn.ClientAddr)
|
||||
})
|
||||
} else {
|
||||
_, err := p.conn.WriteToUDP(raw, conn.ClientAddr)
|
||||
if err != nil {
|
||||
if utils.Debug() {
|
||||
utils.Debugf("forwarding outgoing packet %d (%d bytes) to %s", packetCount, n, conn.ClientAddr)
|
||||
}
|
||||
if _, err := p.conn.WriteToUDP(raw, conn.ClientAddr); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
6
vendor/github.com/lucas-clemente/quic-go/integrationtests/tools/testserver/server.go
generated
vendored
6
vendor/github.com/lucas-clemente/quic-go/integrationtests/tools/testserver/server.go
generated
vendored
|
@ -22,7 +22,9 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
PRData = GeneratePRData(dataLen)
|
||||
// PRData contains dataLen bytes of pseudo-random data.
|
||||
PRData = GeneratePRData(dataLen)
|
||||
// PRDataLong contains dataLenLong bytes of pseudo-random data.
|
||||
PRDataLong = GeneratePRData(dataLenLong)
|
||||
|
||||
server *h2quic.Server
|
||||
|
@ -105,11 +107,13 @@ func StartQuicServer(versions []protocol.VersionNumber) {
|
|||
}()
|
||||
}
|
||||
|
||||
// StopQuicServer stops the h2quic.Server.
|
||||
func StopQuicServer() {
|
||||
Expect(server.Close()).NotTo(HaveOccurred())
|
||||
Eventually(stoppedServing).Should(BeClosed())
|
||||
}
|
||||
|
||||
// Port returns the UDP port of the QUIC server.
|
||||
func Port() string {
|
||||
return port
|
||||
}
|
||||
|
|
31
vendor/github.com/lucas-clemente/quic-go/interface.go
generated
vendored
31
vendor/github.com/lucas-clemente/quic-go/interface.go
generated
vendored
|
@ -113,15 +113,23 @@ type StreamError interface {
|
|||
// A Session is a QUIC connection between two peers.
|
||||
type Session interface {
|
||||
// AcceptStream returns the next stream opened by the peer, blocking until one is available.
|
||||
// Since stream 1 is reserved for the crypto stream, the first stream is either 2 (for a client) or 3 (for a server).
|
||||
AcceptStream() (Stream, error)
|
||||
// OpenStream opens a new QUIC stream, returning a special error when the peer's concurrent stream limit is reached.
|
||||
// New streams always have the smallest possible stream ID.
|
||||
// TODO: Enable testing for the special error
|
||||
// AcceptUniStream returns the next unidirectional stream opened by the peer, blocking until one is available.
|
||||
AcceptUniStream() (ReceiveStream, error)
|
||||
// OpenStream opens a new bidirectional QUIC stream.
|
||||
// It returns a special error when the peer's concurrent stream limit is reached.
|
||||
// TODO(#1152): Enable testing for the special error
|
||||
OpenStream() (Stream, error)
|
||||
// OpenStreamSync opens a new QUIC stream, blocking until the peer's concurrent stream limit allows a new stream to be opened.
|
||||
// It always picks the smallest possible stream ID.
|
||||
// OpenStreamSync opens a new bidirectional QUIC stream.
|
||||
// It blocks until the peer's concurrent stream limit allows a new stream to be opened.
|
||||
OpenStreamSync() (Stream, error)
|
||||
// OpenUniStream opens a new outgoing unidirectional QUIC stream.
|
||||
// It returns a special error when the peer's concurrent stream limit is reached.
|
||||
// TODO(#1152): Enable testing for the special error
|
||||
OpenUniStream() (SendStream, error)
|
||||
// OpenUniStreamSync opens a new outgoing unidirectional QUIC stream.
|
||||
// It blocks until the peer's concurrent stream limit allows a new stream to be opened.
|
||||
OpenUniStreamSync() (SendStream, error)
|
||||
// LocalAddr returns the local address.
|
||||
LocalAddr() net.Addr
|
||||
// RemoteAddr returns the address of the peer.
|
||||
|
@ -166,6 +174,17 @@ type Config struct {
|
|||
// MaxReceiveConnectionFlowControlWindow is the connection-level flow control window for receiving data.
|
||||
// If this value is zero, it will default to 1.5 MB for the server and 15 MB for the client.
|
||||
MaxReceiveConnectionFlowControlWindow uint64
|
||||
// MaxIncomingStreams is the maximum number of concurrent bidirectional streams that a peer is allowed to open.
|
||||
// If not set, it will default to 100.
|
||||
// If set to a negative value, it doesn't allow any bidirectional streams.
|
||||
// Values larger than 65535 (math.MaxUint16) are invalid.
|
||||
MaxIncomingStreams int
|
||||
// MaxIncomingUniStreams is the maximum number of concurrent unidirectional streams that a peer is allowed to open.
|
||||
// This value doesn't have any effect in Google QUIC.
|
||||
// If not set, it will default to 100.
|
||||
// If set to a negative value, it doesn't allow any unidirectional streams.
|
||||
// Values larger than 65535 (math.MaxUint16) are invalid.
|
||||
MaxIncomingUniStreams int
|
||||
// KeepAlive defines whether this peer will periodically send PING frames to keep the connection alive.
|
||||
KeepAlive bool
|
||||
}
|
||||
|
|
14
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/interfaces.go
generated
vendored
14
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/interfaces.go
generated
vendored
|
@ -10,15 +10,13 @@ import (
|
|||
// SentPacketHandler handles ACKs received for outgoing packets
|
||||
type SentPacketHandler interface {
|
||||
// SentPacket may modify the packet
|
||||
SentPacket(packet *Packet) error
|
||||
SentPacket(packet *Packet)
|
||||
SentPacketsAsRetransmission(packets []*Packet, retransmissionOf protocol.PacketNumber)
|
||||
ReceivedAck(ackFrame *wire.AckFrame, withPacketNumber protocol.PacketNumber, encLevel protocol.EncryptionLevel, recvTime time.Time) error
|
||||
SetHandshakeComplete()
|
||||
|
||||
// SendingAllowed says if a packet can be sent.
|
||||
// Sending packets might not be possible because:
|
||||
// * we're congestion limited
|
||||
// * we're tracking the maximum number of sent packets
|
||||
SendingAllowed() bool
|
||||
// The SendMode determines if and what kind of packets can be sent.
|
||||
SendMode() SendMode
|
||||
// TimeUntilSend is the time when the next packet should be sent.
|
||||
// It is used for pacing packets.
|
||||
TimeUntilSend() time.Time
|
||||
|
@ -32,10 +30,10 @@ type SentPacketHandler interface {
|
|||
GetStopWaitingFrame(force bool) *wire.StopWaitingFrame
|
||||
GetLowestPacketNotConfirmedAcked() protocol.PacketNumber
|
||||
DequeuePacketForRetransmission() (packet *Packet)
|
||||
GetLeastUnacked() protocol.PacketNumber
|
||||
GetPacketNumberLen(protocol.PacketNumber) protocol.PacketNumberLen
|
||||
|
||||
GetAlarmTimeout() time.Time
|
||||
OnAlarm()
|
||||
OnAlarm() error
|
||||
}
|
||||
|
||||
// ReceivedPacketHandler handles ACKs needed to send for incoming packets
|
||||
|
|
7
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet.go
generated
vendored
7
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet.go
generated
vendored
|
@ -11,12 +11,19 @@ import (
|
|||
// +gen linkedlist
|
||||
type Packet struct {
|
||||
PacketNumber protocol.PacketNumber
|
||||
PacketType protocol.PacketType
|
||||
Frames []wire.Frame
|
||||
Length protocol.ByteCount
|
||||
EncryptionLevel protocol.EncryptionLevel
|
||||
|
||||
largestAcked protocol.PacketNumber // if the packet contains an ACK, the LargestAcked value of that ACK
|
||||
sendTime time.Time
|
||||
|
||||
queuedForRetransmission bool
|
||||
includedInBytesInFlight bool
|
||||
retransmittedAs []protocol.PacketNumber
|
||||
isRetransmission bool // we need a separate bool here because 0 is a valid packet number
|
||||
retransmissionOf protocol.PacketNumber
|
||||
}
|
||||
|
||||
// GetFramesForRetransmission gets all the frames for retransmission
|
||||
|
|
110
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_handler.go
generated
vendored
110
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_handler.go
generated
vendored
|
@ -3,7 +3,9 @@ package ackhandler
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/congestion"
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
)
|
||||
|
||||
|
@ -15,6 +17,7 @@ type receivedPacketHandler struct {
|
|||
packetHistory *receivedPacketHistory
|
||||
|
||||
ackSendDelay time.Duration
|
||||
rttStats *congestion.RTTStats
|
||||
|
||||
packetsReceivedSinceLastAck int
|
||||
retransmittablePacketsReceivedSinceLastAck int
|
||||
|
@ -25,29 +28,54 @@ type receivedPacketHandler struct {
|
|||
version protocol.VersionNumber
|
||||
}
|
||||
|
||||
const (
|
||||
// maximum delay that can be applied to an ACK for a retransmittable packet
|
||||
ackSendDelay = 25 * time.Millisecond
|
||||
// initial maximum number of retransmittable packets received before sending an ack.
|
||||
initialRetransmittablePacketsBeforeAck = 2
|
||||
// number of retransmittable that an ACK is sent for
|
||||
retransmittablePacketsBeforeAck = 10
|
||||
// 1/5 RTT delay when doing ack decimation
|
||||
ackDecimationDelay = 1.0 / 4
|
||||
// 1/8 RTT delay when doing ack decimation
|
||||
shortAckDecimationDelay = 1.0 / 8
|
||||
// Minimum number of packets received before ack decimation is enabled.
|
||||
// This intends to avoid the beginning of slow start, when CWNDs may be
|
||||
// rapidly increasing.
|
||||
minReceivedBeforeAckDecimation = 100
|
||||
// Maximum number of packets to ack immediately after a missing packet for
|
||||
// fast retransmission to kick in at the sender. This limit is created to
|
||||
// reduce the number of acks sent that have no benefit for fast retransmission.
|
||||
// Set to the number of nacks needed for fast retransmit plus one for protection
|
||||
// against an ack loss
|
||||
maxPacketsAfterNewMissing = 4
|
||||
)
|
||||
|
||||
// NewReceivedPacketHandler creates a new receivedPacketHandler
|
||||
func NewReceivedPacketHandler(version protocol.VersionNumber) ReceivedPacketHandler {
|
||||
func NewReceivedPacketHandler(rttStats *congestion.RTTStats, version protocol.VersionNumber) ReceivedPacketHandler {
|
||||
return &receivedPacketHandler{
|
||||
packetHistory: newReceivedPacketHistory(),
|
||||
ackSendDelay: protocol.AckSendDelay,
|
||||
ackSendDelay: ackSendDelay,
|
||||
rttStats: rttStats,
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *receivedPacketHandler) ReceivedPacket(packetNumber protocol.PacketNumber, rcvTime time.Time, shouldInstigateAck bool) error {
|
||||
if packetNumber < h.ignoreBelow {
|
||||
return nil
|
||||
}
|
||||
|
||||
isMissing := h.isMissing(packetNumber)
|
||||
if packetNumber > h.largestObserved {
|
||||
h.largestObserved = packetNumber
|
||||
h.largestObservedReceivedTime = rcvTime
|
||||
}
|
||||
|
||||
if packetNumber < h.ignoreBelow {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := h.packetHistory.ReceivedPacket(packetNumber); err != nil {
|
||||
return err
|
||||
}
|
||||
h.maybeQueueAck(packetNumber, rcvTime, shouldInstigateAck)
|
||||
h.maybeQueueAck(packetNumber, rcvTime, shouldInstigateAck, isMissing)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -58,35 +86,68 @@ func (h *receivedPacketHandler) IgnoreBelow(p protocol.PacketNumber) {
|
|||
h.packetHistory.DeleteBelow(p)
|
||||
}
|
||||
|
||||
func (h *receivedPacketHandler) maybeQueueAck(packetNumber protocol.PacketNumber, rcvTime time.Time, shouldInstigateAck bool) {
|
||||
h.packetsReceivedSinceLastAck++
|
||||
|
||||
if shouldInstigateAck {
|
||||
h.retransmittablePacketsReceivedSinceLastAck++
|
||||
// isMissing says if a packet was reported missing in the last ACK.
|
||||
func (h *receivedPacketHandler) isMissing(p protocol.PacketNumber) bool {
|
||||
if h.lastAck == nil {
|
||||
return false
|
||||
}
|
||||
return p < h.lastAck.LargestAcked && !h.lastAck.AcksPacket(p)
|
||||
}
|
||||
|
||||
func (h *receivedPacketHandler) hasNewMissingPackets() bool {
|
||||
if h.lastAck == nil {
|
||||
return false
|
||||
}
|
||||
highestRange := h.packetHistory.GetHighestAckRange()
|
||||
return highestRange.First >= h.lastAck.LargestAcked && highestRange.Len() <= maxPacketsAfterNewMissing
|
||||
}
|
||||
|
||||
// maybeQueueAck queues an ACK, if necessary.
|
||||
// It is implemented analogously to Chrome's QuicConnection::MaybeQueueAck()
|
||||
// in ACK_DECIMATION_WITH_REORDERING mode.
|
||||
func (h *receivedPacketHandler) maybeQueueAck(packetNumber protocol.PacketNumber, rcvTime time.Time, shouldInstigateAck, wasMissing bool) {
|
||||
h.packetsReceivedSinceLastAck++
|
||||
|
||||
// always ack the first packet
|
||||
if h.lastAck == nil {
|
||||
h.ackQueued = true
|
||||
return
|
||||
}
|
||||
|
||||
// if the packet number is smaller than the largest acked packet, it must have been reported missing with the last ACK
|
||||
// note that it cannot be a duplicate because they're already filtered out by ReceivedPacket()
|
||||
if h.lastAck != nil && packetNumber < h.lastAck.LargestAcked {
|
||||
h.ackQueued = true
|
||||
}
|
||||
|
||||
// check if a new missing range above the previously was created
|
||||
if h.lastAck != nil && h.packetHistory.GetHighestAckRange().First > h.lastAck.LargestAcked {
|
||||
// Send an ACK if this packet was reported missing in an ACK sent before.
|
||||
// Ack decimation with reordering relies on the timer to send an ACK, but if
|
||||
// missing packets we reported in the previous ack, send an ACK immediately.
|
||||
if wasMissing {
|
||||
h.ackQueued = true
|
||||
}
|
||||
|
||||
if !h.ackQueued && shouldInstigateAck {
|
||||
if h.retransmittablePacketsReceivedSinceLastAck >= protocol.RetransmittablePacketsBeforeAck {
|
||||
h.ackQueued = true
|
||||
h.retransmittablePacketsReceivedSinceLastAck++
|
||||
|
||||
if packetNumber > minReceivedBeforeAckDecimation {
|
||||
// ack up to 10 packets at once
|
||||
if h.retransmittablePacketsReceivedSinceLastAck >= retransmittablePacketsBeforeAck {
|
||||
h.ackQueued = true
|
||||
} else if h.ackAlarm.IsZero() {
|
||||
// wait for the minimum of the ack decimation delay or the delayed ack time before sending an ack
|
||||
ackDelay := utils.MinDuration(ackSendDelay, time.Duration(float64(h.rttStats.MinRTT())*float64(ackDecimationDelay)))
|
||||
h.ackAlarm = rcvTime.Add(ackDelay)
|
||||
}
|
||||
} else {
|
||||
if h.ackAlarm.IsZero() {
|
||||
h.ackAlarm = rcvTime.Add(h.ackSendDelay)
|
||||
// send an ACK every 2 retransmittable packets
|
||||
if h.retransmittablePacketsReceivedSinceLastAck >= initialRetransmittablePacketsBeforeAck {
|
||||
h.ackQueued = true
|
||||
} else if h.ackAlarm.IsZero() {
|
||||
h.ackAlarm = rcvTime.Add(ackSendDelay)
|
||||
}
|
||||
}
|
||||
// If there are new missing packets to report, set a short timer to send an ACK.
|
||||
if h.hasNewMissingPackets() {
|
||||
// wait the minimum of 1/8 min RTT and the existing ack time
|
||||
ackDelay := float64(h.rttStats.MinRTT()) * float64(shortAckDecimationDelay)
|
||||
ackTime := rcvTime.Add(time.Duration(ackDelay))
|
||||
if h.ackAlarm.IsZero() || h.ackAlarm.After(ackTime) {
|
||||
h.ackAlarm = ackTime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +179,6 @@ func (h *receivedPacketHandler) GetAckFrame() *wire.AckFrame {
|
|||
h.ackQueued = false
|
||||
h.packetsReceivedSinceLastAck = 0
|
||||
h.retransmittablePacketsReceivedSinceLastAck = 0
|
||||
|
||||
return ack
|
||||
}
|
||||
|
||||
|
|
32
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/send_mode.go
generated
vendored
Normal file
32
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/send_mode.go
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
package ackhandler
|
||||
|
||||
import "fmt"
|
||||
|
||||
// The SendMode says what kind of packets can be sent.
|
||||
type SendMode uint8
|
||||
|
||||
const (
|
||||
// SendNone means that no packets should be sent
|
||||
SendNone SendMode = iota
|
||||
// SendAck means an ACK-only packet should be sent
|
||||
SendAck
|
||||
// SendRetransmission means that retransmissions should be sent
|
||||
SendRetransmission
|
||||
// SendAny packet should be sent
|
||||
SendAny
|
||||
)
|
||||
|
||||
func (s SendMode) String() string {
|
||||
switch s {
|
||||
case SendNone:
|
||||
return "none"
|
||||
case SendAck:
|
||||
return "ack"
|
||||
case SendRetransmission:
|
||||
return "retransmission"
|
||||
case SendAny:
|
||||
return "any"
|
||||
default:
|
||||
return fmt.Sprintf("invalid send mode: %d", s)
|
||||
}
|
||||
}
|
391
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_handler.go
generated
vendored
391
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_handler.go
generated
vendored
|
@ -1,7 +1,6 @@
|
|||
package ackhandler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
@ -30,13 +29,12 @@ const (
|
|||
maxRTOTimeout = 60 * time.Second
|
||||
)
|
||||
|
||||
// ErrDuplicateOrOutOfOrderAck occurs when a duplicate or an out-of-order ACK is received
|
||||
var ErrDuplicateOrOutOfOrderAck = errors.New("SentPacketHandler: Duplicate or out-of-order ACK")
|
||||
|
||||
type sentPacketHandler struct {
|
||||
lastSentPacketNumber protocol.PacketNumber
|
||||
nextPacketSendTime time.Time
|
||||
skippedPackets []protocol.PacketNumber
|
||||
lastSentPacketNumber protocol.PacketNumber
|
||||
lastSentRetransmittablePacketTime time.Time
|
||||
|
||||
nextPacketSendTime time.Time
|
||||
skippedPackets []protocol.PacketNumber
|
||||
|
||||
largestAcked protocol.PacketNumber
|
||||
largestReceivedPacketWithAck protocol.PacketNumber
|
||||
|
@ -45,7 +43,7 @@ type sentPacketHandler struct {
|
|||
// once we receive an ACK from the peer for packet 20, the lowestPacketNotConfirmedAcked is 101
|
||||
lowestPacketNotConfirmedAcked protocol.PacketNumber
|
||||
|
||||
packetHistory *PacketList
|
||||
packetHistory *sentPacketHistory
|
||||
stopWaitingManager stopWaitingManager
|
||||
|
||||
retransmissionQueue []*Packet
|
||||
|
@ -80,7 +78,7 @@ func NewSentPacketHandler(rttStats *congestion.RTTStats) SentPacketHandler {
|
|||
)
|
||||
|
||||
return &sentPacketHandler{
|
||||
packetHistory: NewPacketList(),
|
||||
packetHistory: newSentPacketHistory(),
|
||||
stopWaitingManager: stopWaitingManager{},
|
||||
rttStats: rttStats,
|
||||
congestion: congestion,
|
||||
|
@ -88,8 +86,8 @@ func NewSentPacketHandler(rttStats *congestion.RTTStats) SentPacketHandler {
|
|||
}
|
||||
|
||||
func (h *sentPacketHandler) lowestUnacked() protocol.PacketNumber {
|
||||
if f := h.packetHistory.Front(); f != nil {
|
||||
return f.Value.PacketNumber
|
||||
if p := h.packetHistory.FirstOutstanding(); p != nil {
|
||||
return p.PacketNumber
|
||||
}
|
||||
return h.largestAcked + 1
|
||||
}
|
||||
|
@ -101,24 +99,49 @@ func (h *sentPacketHandler) SetHandshakeComplete() {
|
|||
queue = append(queue, packet)
|
||||
}
|
||||
}
|
||||
var handshakePackets []*Packet
|
||||
h.packetHistory.Iterate(func(p *Packet) (bool, error) {
|
||||
if p.EncryptionLevel != protocol.EncryptionForwardSecure {
|
||||
handshakePackets = append(handshakePackets, p)
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
for _, p := range handshakePackets {
|
||||
h.packetHistory.Remove(p.PacketNumber)
|
||||
}
|
||||
h.retransmissionQueue = queue
|
||||
h.handshakeComplete = true
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) SentPacket(packet *Packet) error {
|
||||
if protocol.PacketNumber(len(h.retransmissionQueue)+h.packetHistory.Len()+1) > protocol.MaxTrackedSentPackets {
|
||||
return errors.New("Too many outstanding non-acked and non-retransmitted packets")
|
||||
func (h *sentPacketHandler) SentPacket(packet *Packet) {
|
||||
packet.sendTime = time.Now()
|
||||
if isRetransmittable := h.sentPacketImpl(packet); isRetransmittable {
|
||||
h.packetHistory.SentPacket(packet)
|
||||
h.updateLossDetectionAlarm()
|
||||
}
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) SentPacketsAsRetransmission(packets []*Packet, retransmissionOf protocol.PacketNumber) {
|
||||
now := time.Now()
|
||||
var p []*Packet
|
||||
for _, packet := range packets {
|
||||
packet.sendTime = now
|
||||
if isRetransmittable := h.sentPacketImpl(packet); isRetransmittable {
|
||||
p = append(p, packet)
|
||||
}
|
||||
}
|
||||
h.packetHistory.SentPacketsAsRetransmission(p, retransmissionOf)
|
||||
h.updateLossDetectionAlarm()
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) sentPacketImpl(packet *Packet) bool /* isRetransmittable */ {
|
||||
for p := h.lastSentPacketNumber + 1; p < packet.PacketNumber; p++ {
|
||||
h.skippedPackets = append(h.skippedPackets, p)
|
||||
|
||||
if len(h.skippedPackets) > protocol.MaxTrackedSkippedPackets {
|
||||
h.skippedPackets = h.skippedPackets[1:]
|
||||
}
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
h.lastSentPacketNumber = packet.PacketNumber
|
||||
|
||||
var largestAcked protocol.PacketNumber
|
||||
|
@ -132,24 +155,15 @@ func (h *sentPacketHandler) SentPacket(packet *Packet) error {
|
|||
isRetransmittable := len(packet.Frames) != 0
|
||||
|
||||
if isRetransmittable {
|
||||
packet.sendTime = now
|
||||
packet.largestAcked = largestAcked
|
||||
h.lastSentRetransmittablePacketTime = packet.sendTime
|
||||
packet.includedInBytesInFlight = true
|
||||
h.bytesInFlight += packet.Length
|
||||
h.packetHistory.PushBack(*packet)
|
||||
}
|
||||
h.congestion.OnPacketSent(packet.sendTime, h.bytesInFlight, packet.PacketNumber, packet.Length, isRetransmittable)
|
||||
|
||||
h.congestion.OnPacketSent(
|
||||
now,
|
||||
h.bytesInFlight,
|
||||
packet.PacketNumber,
|
||||
packet.Length,
|
||||
isRetransmittable,
|
||||
)
|
||||
|
||||
h.nextPacketSendTime = utils.MaxTime(h.nextPacketSendTime, now).Add(h.congestion.TimeUntilSend(h.bytesInFlight))
|
||||
|
||||
h.updateLossDetectionAlarm(now)
|
||||
return nil
|
||||
h.nextPacketSendTime = utils.MaxTime(h.nextPacketSendTime, packet.sendTime).Add(h.congestion.TimeUntilSend(h.bytesInFlight))
|
||||
return isRetransmittable
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) ReceivedAck(ackFrame *wire.AckFrame, withPacketNumber protocol.PacketNumber, encLevel protocol.EncryptionLevel, rcvTime time.Time) error {
|
||||
|
@ -157,26 +171,19 @@ func (h *sentPacketHandler) ReceivedAck(ackFrame *wire.AckFrame, withPacketNumbe
|
|||
return qerr.Error(qerr.InvalidAckData, "Received ACK for an unsent package")
|
||||
}
|
||||
|
||||
// duplicate or out-of-order ACK
|
||||
// if withPacketNumber <= h.largestReceivedPacketWithAck && withPacketNumber != 0 {
|
||||
if withPacketNumber <= h.largestReceivedPacketWithAck {
|
||||
return ErrDuplicateOrOutOfOrderAck
|
||||
}
|
||||
h.largestReceivedPacketWithAck = withPacketNumber
|
||||
|
||||
// ignore repeated ACK (ACKs that don't have a higher LargestAcked than the last ACK)
|
||||
if ackFrame.LargestAcked < h.lowestUnacked() {
|
||||
// duplicate or out of order ACK
|
||||
if withPacketNumber != 0 && withPacketNumber <= h.largestReceivedPacketWithAck {
|
||||
utils.Debugf("Ignoring ACK frame (duplicate or out of order).")
|
||||
return nil
|
||||
}
|
||||
h.largestAcked = ackFrame.LargestAcked
|
||||
h.largestReceivedPacketWithAck = withPacketNumber
|
||||
h.largestAcked = utils.MaxPacketNumber(h.largestAcked, ackFrame.LargestAcked)
|
||||
|
||||
if h.skippedPacketsAcked(ackFrame) {
|
||||
return qerr.Error(qerr.InvalidAckData, "Received an ACK for a skipped packet number")
|
||||
}
|
||||
|
||||
rttUpdated := h.maybeUpdateRTT(ackFrame.LargestAcked, ackFrame.DelayTime, rcvTime)
|
||||
|
||||
if rttUpdated {
|
||||
if rttUpdated := h.maybeUpdateRTT(ackFrame.LargestAcked, ackFrame.DelayTime, rcvTime); rttUpdated {
|
||||
h.congestion.MaybeExitSlowStart()
|
||||
}
|
||||
|
||||
|
@ -185,24 +192,28 @@ func (h *sentPacketHandler) ReceivedAck(ackFrame *wire.AckFrame, withPacketNumbe
|
|||
return err
|
||||
}
|
||||
|
||||
if len(ackedPackets) > 0 {
|
||||
for _, p := range ackedPackets {
|
||||
if encLevel < p.Value.EncryptionLevel {
|
||||
return fmt.Errorf("Received ACK with encryption level %s that acks a packet %d (encryption level %s)", encLevel, p.Value.PacketNumber, p.Value.EncryptionLevel)
|
||||
}
|
||||
// largestAcked == 0 either means that the packet didn't contain an ACK, or it just acked packet 0
|
||||
// It is safe to ignore the corner case of packets that just acked packet 0, because
|
||||
// the lowestPacketNotConfirmedAcked is only used to limit the number of ACK ranges we will send.
|
||||
if p.Value.largestAcked != 0 {
|
||||
h.lowestPacketNotConfirmedAcked = utils.MaxPacketNumber(h.lowestPacketNotConfirmedAcked, p.Value.largestAcked+1)
|
||||
}
|
||||
h.onPacketAcked(p)
|
||||
h.congestion.OnPacketAcked(p.Value.PacketNumber, p.Value.Length, h.bytesInFlight)
|
||||
for _, p := range ackedPackets {
|
||||
if encLevel < p.EncryptionLevel {
|
||||
return fmt.Errorf("Received ACK with encryption level %s that acks a packet %d (encryption level %s)", encLevel, p.PacketNumber, p.EncryptionLevel)
|
||||
}
|
||||
// largestAcked == 0 either means that the packet didn't contain an ACK, or it just acked packet 0
|
||||
// It is safe to ignore the corner case of packets that just acked packet 0, because
|
||||
// the lowestPacketNotConfirmedAcked is only used to limit the number of ACK ranges we will send.
|
||||
if p.largestAcked != 0 {
|
||||
h.lowestPacketNotConfirmedAcked = utils.MaxPacketNumber(h.lowestPacketNotConfirmedAcked, p.largestAcked+1)
|
||||
}
|
||||
if err := h.onPacketAcked(p); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(p.retransmittedAs) == 0 {
|
||||
h.congestion.OnPacketAcked(p.PacketNumber, p.Length, h.bytesInFlight)
|
||||
}
|
||||
}
|
||||
|
||||
h.detectLostPackets(rcvTime)
|
||||
h.updateLossDetectionAlarm(rcvTime)
|
||||
if err := h.detectLostPackets(rcvTime); err != nil {
|
||||
return err
|
||||
}
|
||||
h.updateLossDetectionAlarm()
|
||||
|
||||
h.garbageCollectSkippedPackets()
|
||||
h.stopWaitingManager.ReceivedAck(ackFrame)
|
||||
|
@ -214,59 +225,50 @@ func (h *sentPacketHandler) GetLowestPacketNotConfirmedAcked() protocol.PacketNu
|
|||
return h.lowestPacketNotConfirmedAcked
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) determineNewlyAckedPackets(ackFrame *wire.AckFrame) ([]*PacketElement, error) {
|
||||
var ackedPackets []*PacketElement
|
||||
func (h *sentPacketHandler) determineNewlyAckedPackets(ackFrame *wire.AckFrame) ([]*Packet, error) {
|
||||
var ackedPackets []*Packet
|
||||
ackRangeIndex := 0
|
||||
for el := h.packetHistory.Front(); el != nil; el = el.Next() {
|
||||
packet := el.Value
|
||||
packetNumber := packet.PacketNumber
|
||||
|
||||
err := h.packetHistory.Iterate(func(p *Packet) (bool, error) {
|
||||
// Ignore packets below the LowestAcked
|
||||
if packetNumber < ackFrame.LowestAcked {
|
||||
continue
|
||||
if p.PacketNumber < ackFrame.LowestAcked {
|
||||
return true, nil
|
||||
}
|
||||
// Break after LargestAcked is reached
|
||||
if packetNumber > ackFrame.LargestAcked {
|
||||
break
|
||||
if p.PacketNumber > ackFrame.LargestAcked {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if ackFrame.HasMissingRanges() {
|
||||
ackRange := ackFrame.AckRanges[len(ackFrame.AckRanges)-1-ackRangeIndex]
|
||||
|
||||
for packetNumber > ackRange.Last && ackRangeIndex < len(ackFrame.AckRanges)-1 {
|
||||
for p.PacketNumber > ackRange.Last && ackRangeIndex < len(ackFrame.AckRanges)-1 {
|
||||
ackRangeIndex++
|
||||
ackRange = ackFrame.AckRanges[len(ackFrame.AckRanges)-1-ackRangeIndex]
|
||||
}
|
||||
|
||||
if packetNumber >= ackRange.First { // packet i contained in ACK range
|
||||
if packetNumber > ackRange.Last {
|
||||
return nil, fmt.Errorf("BUG: ackhandler would have acked wrong packet 0x%x, while evaluating range 0x%x -> 0x%x", packetNumber, ackRange.First, ackRange.Last)
|
||||
if p.PacketNumber >= ackRange.First { // packet i contained in ACK range
|
||||
if p.PacketNumber > ackRange.Last {
|
||||
return false, fmt.Errorf("BUG: ackhandler would have acked wrong packet 0x%x, while evaluating range 0x%x -> 0x%x", p.PacketNumber, ackRange.First, ackRange.Last)
|
||||
}
|
||||
ackedPackets = append(ackedPackets, el)
|
||||
ackedPackets = append(ackedPackets, p)
|
||||
}
|
||||
} else {
|
||||
ackedPackets = append(ackedPackets, el)
|
||||
ackedPackets = append(ackedPackets, p)
|
||||
}
|
||||
}
|
||||
return ackedPackets, nil
|
||||
return true, nil
|
||||
})
|
||||
return ackedPackets, err
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) maybeUpdateRTT(largestAcked protocol.PacketNumber, ackDelay time.Duration, rcvTime time.Time) bool {
|
||||
for el := h.packetHistory.Front(); el != nil; el = el.Next() {
|
||||
packet := el.Value
|
||||
if packet.PacketNumber == largestAcked {
|
||||
h.rttStats.UpdateRTT(rcvTime.Sub(packet.sendTime), ackDelay, rcvTime)
|
||||
return true
|
||||
}
|
||||
// Packets are sorted by number, so we can stop searching
|
||||
if packet.PacketNumber > largestAcked {
|
||||
break
|
||||
}
|
||||
if p := h.packetHistory.GetPacket(largestAcked); p != nil {
|
||||
h.rttStats.UpdateRTT(rcvTime.Sub(p.sendTime), ackDelay, rcvTime)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) updateLossDetectionAlarm(now time.Time) {
|
||||
func (h *sentPacketHandler) updateLossDetectionAlarm() {
|
||||
// Cancel the alarm if no packets are outstanding
|
||||
if h.packetHistory.Len() == 0 {
|
||||
h.alarm = time.Time{}
|
||||
|
@ -275,76 +277,137 @@ func (h *sentPacketHandler) updateLossDetectionAlarm(now time.Time) {
|
|||
|
||||
// TODO(#497): TLP
|
||||
if !h.handshakeComplete {
|
||||
h.alarm = now.Add(h.computeHandshakeTimeout())
|
||||
h.alarm = h.lastSentRetransmittablePacketTime.Add(h.computeHandshakeTimeout())
|
||||
} else if !h.lossTime.IsZero() {
|
||||
// Early retransmit timer or time loss detection.
|
||||
h.alarm = h.lossTime
|
||||
} else {
|
||||
// RTO
|
||||
h.alarm = now.Add(h.computeRTOTimeout())
|
||||
h.alarm = h.lastSentRetransmittablePacketTime.Add(h.computeRTOTimeout())
|
||||
}
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) detectLostPackets(now time.Time) {
|
||||
func (h *sentPacketHandler) detectLostPackets(now time.Time) error {
|
||||
h.lossTime = time.Time{}
|
||||
|
||||
maxRTT := float64(utils.MaxDuration(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT()))
|
||||
delayUntilLost := time.Duration((1.0 + timeReorderingFraction) * maxRTT)
|
||||
|
||||
var lostPackets []*PacketElement
|
||||
for el := h.packetHistory.Front(); el != nil; el = el.Next() {
|
||||
packet := el.Value
|
||||
|
||||
var lostPackets []*Packet
|
||||
h.packetHistory.Iterate(func(packet *Packet) (bool, error) {
|
||||
if packet.PacketNumber > h.largestAcked {
|
||||
break
|
||||
return false, nil
|
||||
}
|
||||
if packet.queuedForRetransmission { // don't retransmit packets twice
|
||||
return true, nil
|
||||
}
|
||||
|
||||
timeSinceSent := now.Sub(packet.sendTime)
|
||||
if timeSinceSent > delayUntilLost {
|
||||
lostPackets = append(lostPackets, el)
|
||||
lostPackets = append(lostPackets, packet)
|
||||
} else if h.lossTime.IsZero() {
|
||||
// Note: This conditional is only entered once per call
|
||||
h.lossTime = now.Add(delayUntilLost - timeSinceSent)
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
|
||||
if len(lostPackets) > 0 {
|
||||
for _, p := range lostPackets {
|
||||
h.queuePacketForRetransmission(p)
|
||||
h.congestion.OnPacketLost(p.Value.PacketNumber, p.Value.Length, h.bytesInFlight)
|
||||
for _, p := range lostPackets {
|
||||
if err := h.queuePacketForRetransmission(p); err != nil {
|
||||
return err
|
||||
}
|
||||
h.bytesInFlight -= p.Length
|
||||
p.includedInBytesInFlight = false
|
||||
h.congestion.OnPacketLost(p.PacketNumber, p.Length, h.bytesInFlight)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) OnAlarm() {
|
||||
func (h *sentPacketHandler) OnAlarm() error {
|
||||
now := time.Now()
|
||||
|
||||
// TODO(#497): TLP
|
||||
var err error
|
||||
if !h.handshakeComplete {
|
||||
h.queueHandshakePacketsForRetransmission()
|
||||
h.handshakeCount++
|
||||
err = h.queueHandshakePacketsForRetransmission()
|
||||
} else if !h.lossTime.IsZero() {
|
||||
// Early retransmit or time loss detection
|
||||
h.detectLostPackets(now)
|
||||
err = h.detectLostPackets(now)
|
||||
} else {
|
||||
// RTO
|
||||
h.retransmitOldestTwoPackets()
|
||||
h.rtoCount++
|
||||
err = h.queueRTOs()
|
||||
}
|
||||
|
||||
h.updateLossDetectionAlarm(now)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
h.updateLossDetectionAlarm()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) GetAlarmTimeout() time.Time {
|
||||
return h.alarm
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) onPacketAcked(packetElement *PacketElement) {
|
||||
h.bytesInFlight -= packetElement.Value.Length
|
||||
func (h *sentPacketHandler) onPacketAcked(p *Packet) error {
|
||||
// This happens if a packet and its retransmissions is acked in the same ACK.
|
||||
// As soon as we process the first one, this will remove all the retransmissions,
|
||||
// so we won't find the retransmitted packet number later.
|
||||
if packet := h.packetHistory.GetPacket(p.PacketNumber); packet == nil {
|
||||
return nil
|
||||
}
|
||||
h.rtoCount = 0
|
||||
h.handshakeCount = 0
|
||||
// TODO(#497): h.tlpCount = 0
|
||||
h.packetHistory.Remove(packetElement)
|
||||
|
||||
// find the first packet, from which on we can delete all retransmissions
|
||||
// example: packet 10 was retransmitted as packet 11 and 12, and
|
||||
// packet 12 was then retransmitted as 13.
|
||||
// When receiving an ACK for packet 13, we can remove packets 12 and 13,
|
||||
// but still need to keep 10 and 11.
|
||||
first := p
|
||||
for first.isRetransmission {
|
||||
previous := h.packetHistory.GetPacket(first.retransmissionOf)
|
||||
if previous == nil {
|
||||
return fmt.Errorf("sent packet handler BUG: retransmitted packet for %d not found (should have been %d)", first.PacketNumber, first.retransmissionOf)
|
||||
}
|
||||
// if the retransmission of a packet was split, we can't remove it yet
|
||||
if len(previous.retransmittedAs) > 1 {
|
||||
break
|
||||
}
|
||||
first = previous
|
||||
}
|
||||
if first.isRetransmission {
|
||||
root := h.packetHistory.GetPacket(first.retransmissionOf)
|
||||
retransmittedAs := make([]protocol.PacketNumber, 0, len(root.retransmittedAs)-1)
|
||||
for _, pn := range root.retransmittedAs {
|
||||
if pn != first.PacketNumber {
|
||||
retransmittedAs = append(retransmittedAs, pn)
|
||||
}
|
||||
}
|
||||
root.retransmittedAs = retransmittedAs
|
||||
}
|
||||
return h.removeAllRetransmissions(first)
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) removeAllRetransmissions(p *Packet) error {
|
||||
if p.includedInBytesInFlight {
|
||||
h.bytesInFlight -= p.Length
|
||||
p.includedInBytesInFlight = false
|
||||
}
|
||||
if p.queuedForRetransmission {
|
||||
for _, r := range p.retransmittedAs {
|
||||
packet := h.packetHistory.GetPacket(r)
|
||||
if packet == nil {
|
||||
return fmt.Errorf("sent packet handler BUG: removing packet %d (retransmission of %d) not found in history", r, p.PacketNumber)
|
||||
}
|
||||
if err := h.removeAllRetransmissions(packet); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return h.packetHistory.Remove(p.PacketNumber)
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) DequeuePacketForRetransmission() *Packet {
|
||||
|
@ -359,26 +422,39 @@ func (h *sentPacketHandler) DequeuePacketForRetransmission() *Packet {
|
|||
return packet
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) GetLeastUnacked() protocol.PacketNumber {
|
||||
return h.lowestUnacked()
|
||||
func (h *sentPacketHandler) GetPacketNumberLen(p protocol.PacketNumber) protocol.PacketNumberLen {
|
||||
return protocol.GetPacketNumberLengthForHeader(p, h.lowestUnacked())
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) GetStopWaitingFrame(force bool) *wire.StopWaitingFrame {
|
||||
return h.stopWaitingManager.GetStopWaitingFrame(force)
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) SendingAllowed() bool {
|
||||
cwnd := h.congestion.GetCongestionWindow()
|
||||
congestionLimited := h.bytesInFlight > cwnd
|
||||
maxTrackedLimited := protocol.PacketNumber(len(h.retransmissionQueue)+h.packetHistory.Len()) >= protocol.MaxTrackedSentPackets
|
||||
if congestionLimited {
|
||||
utils.Debugf("Congestion limited: bytes in flight %d, window %d", h.bytesInFlight, cwnd)
|
||||
func (h *sentPacketHandler) SendMode() SendMode {
|
||||
numTrackedPackets := len(h.retransmissionQueue) + h.packetHistory.Len()
|
||||
|
||||
// Don't send any packets if we're keeping track of the maximum number of packets.
|
||||
// Note that since MaxOutstandingSentPackets is smaller than MaxTrackedSentPackets,
|
||||
// we will stop sending out new data when reaching MaxOutstandingSentPackets,
|
||||
// but still allow sending of retransmissions and ACKs.
|
||||
if numTrackedPackets >= protocol.MaxTrackedSentPackets {
|
||||
utils.Debugf("Limited by the number of tracked packets: tracking %d packets, maximum %d", numTrackedPackets, protocol.MaxTrackedSentPackets)
|
||||
return SendNone
|
||||
}
|
||||
// Workaround for #555:
|
||||
// Always allow sending of retransmissions. This should probably be limited
|
||||
// to RTOs, but we currently don't have a nice way of distinguishing them.
|
||||
haveRetransmissions := len(h.retransmissionQueue) > 0
|
||||
return !maxTrackedLimited && (!congestionLimited || haveRetransmissions)
|
||||
// Send retransmissions first, if there are any.
|
||||
if len(h.retransmissionQueue) > 0 {
|
||||
return SendRetransmission
|
||||
}
|
||||
// Only send ACKs if we're congestion limited.
|
||||
if cwnd := h.congestion.GetCongestionWindow(); h.bytesInFlight > cwnd {
|
||||
utils.Debugf("Congestion limited: bytes in flight %d, window %d", h.bytesInFlight, cwnd)
|
||||
return SendAck
|
||||
}
|
||||
if numTrackedPackets >= protocol.MaxOutstandingSentPackets {
|
||||
utils.Debugf("Max outstanding limited: tracking %d packets, maximum: %d", numTrackedPackets, protocol.MaxOutstandingSentPackets)
|
||||
return SendAck
|
||||
}
|
||||
return SendAny
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) TimeUntilSend() time.Time {
|
||||
|
@ -393,45 +469,44 @@ func (h *sentPacketHandler) ShouldSendNumPackets() int {
|
|||
return int(math.Ceil(float64(protocol.MinPacingDelay) / float64(delay)))
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) retransmitOldestTwoPackets() {
|
||||
if p := h.packetHistory.Front(); p != nil {
|
||||
h.queueRTO(p)
|
||||
}
|
||||
if p := h.packetHistory.Front(); p != nil {
|
||||
h.queueRTO(p)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) queueRTO(el *PacketElement) {
|
||||
packet := &el.Value
|
||||
utils.Debugf(
|
||||
"\tQueueing packet 0x%x for retransmission (RTO), %d outstanding",
|
||||
packet.PacketNumber,
|
||||
h.packetHistory.Len(),
|
||||
)
|
||||
h.queuePacketForRetransmission(el)
|
||||
h.congestion.OnPacketLost(packet.PacketNumber, packet.Length, h.bytesInFlight)
|
||||
h.congestion.OnRetransmissionTimeout(true)
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) queueHandshakePacketsForRetransmission() {
|
||||
var handshakePackets []*PacketElement
|
||||
for el := h.packetHistory.Front(); el != nil; el = el.Next() {
|
||||
if el.Value.EncryptionLevel < protocol.EncryptionForwardSecure {
|
||||
handshakePackets = append(handshakePackets, el)
|
||||
// retransmit the oldest two packets
|
||||
func (h *sentPacketHandler) queueRTOs() error {
|
||||
for i := 0; i < 2; i++ {
|
||||
if p := h.packetHistory.FirstOutstanding(); p != nil {
|
||||
utils.Debugf("\tQueueing packet %#x for retransmission (RTO), %d outstanding", p.PacketNumber, h.packetHistory.Len())
|
||||
if err := h.queuePacketForRetransmission(p); err != nil {
|
||||
return err
|
||||
}
|
||||
h.congestion.OnPacketLost(p.PacketNumber, p.Length, h.bytesInFlight)
|
||||
h.congestion.OnRetransmissionTimeout(true)
|
||||
}
|
||||
}
|
||||
for _, el := range handshakePackets {
|
||||
h.queuePacketForRetransmission(el)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) queuePacketForRetransmission(packetElement *PacketElement) {
|
||||
packet := &packetElement.Value
|
||||
h.bytesInFlight -= packet.Length
|
||||
h.retransmissionQueue = append(h.retransmissionQueue, packet)
|
||||
h.packetHistory.Remove(packetElement)
|
||||
h.stopWaitingManager.QueuedRetransmissionForPacketNumber(packet.PacketNumber)
|
||||
func (h *sentPacketHandler) queueHandshakePacketsForRetransmission() error {
|
||||
var handshakePackets []*Packet
|
||||
h.packetHistory.Iterate(func(p *Packet) (bool, error) {
|
||||
if !p.queuedForRetransmission && p.EncryptionLevel < protocol.EncryptionForwardSecure {
|
||||
handshakePackets = append(handshakePackets, p)
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
for _, p := range handshakePackets {
|
||||
if err := h.queuePacketForRetransmission(p); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) queuePacketForRetransmission(p *Packet) error {
|
||||
if _, err := h.packetHistory.QueuePacketForRetransmission(p.PacketNumber); err != nil {
|
||||
return err
|
||||
}
|
||||
h.retransmissionQueue = append(h.retransmissionQueue, p)
|
||||
h.stopWaitingManager.QueuedRetransmissionForPacketNumber(p.PacketNumber)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) computeHandshakeTimeout() time.Duration {
|
||||
|
|
130
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_history.go
generated
vendored
Normal file
130
vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_history.go
generated
vendored
Normal file
|
@ -0,0 +1,130 @@
|
|||
package ackhandler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
)
|
||||
|
||||
type sentPacketHistory struct {
|
||||
packetList *PacketList
|
||||
packetMap map[protocol.PacketNumber]*PacketElement
|
||||
|
||||
firstOutstanding *PacketElement
|
||||
}
|
||||
|
||||
func newSentPacketHistory() *sentPacketHistory {
|
||||
return &sentPacketHistory{
|
||||
packetList: NewPacketList(),
|
||||
packetMap: make(map[protocol.PacketNumber]*PacketElement),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *sentPacketHistory) SentPacket(p *Packet) {
|
||||
h.sentPacketImpl(p)
|
||||
}
|
||||
|
||||
func (h *sentPacketHistory) sentPacketImpl(p *Packet) *PacketElement {
|
||||
el := h.packetList.PushBack(*p)
|
||||
h.packetMap[p.PacketNumber] = el
|
||||
if h.firstOutstanding == nil {
|
||||
h.firstOutstanding = el
|
||||
}
|
||||
return el
|
||||
}
|
||||
|
||||
func (h *sentPacketHistory) SentPacketsAsRetransmission(packets []*Packet, retransmissionOf protocol.PacketNumber) {
|
||||
retransmission, ok := h.packetMap[retransmissionOf]
|
||||
// The retransmitted packet is not present anymore.
|
||||
// This can happen if it was acked in between dequeueing of the retransmission and sending.
|
||||
// Just treat the retransmissions as normal packets.
|
||||
// TODO: This won't happen if we clear packets queued for retransmission on new ACKs.
|
||||
if !ok {
|
||||
for _, packet := range packets {
|
||||
h.sentPacketImpl(packet)
|
||||
}
|
||||
return
|
||||
}
|
||||
retransmission.Value.retransmittedAs = make([]protocol.PacketNumber, len(packets))
|
||||
for i, packet := range packets {
|
||||
retransmission.Value.retransmittedAs[i] = packet.PacketNumber
|
||||
el := h.sentPacketImpl(packet)
|
||||
el.Value.isRetransmission = true
|
||||
el.Value.retransmissionOf = retransmissionOf
|
||||
}
|
||||
}
|
||||
|
||||
func (h *sentPacketHistory) GetPacket(p protocol.PacketNumber) *Packet {
|
||||
if el, ok := h.packetMap[p]; ok {
|
||||
return &el.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Iterate iterates through all packets.
|
||||
// The callback must not modify the history.
|
||||
func (h *sentPacketHistory) Iterate(cb func(*Packet) (cont bool, err error)) error {
|
||||
cont := true
|
||||
for el := h.packetList.Front(); cont && el != nil; el = el.Next() {
|
||||
var err error
|
||||
cont, err = cb(&el.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FirstOutStanding returns the first outstanding packet.
|
||||
// It must not be modified (e.g. retransmitted).
|
||||
// Use DequeueFirstPacketForRetransmission() to retransmit it.
|
||||
func (h *sentPacketHistory) FirstOutstanding() *Packet {
|
||||
if h.firstOutstanding == nil {
|
||||
return nil
|
||||
}
|
||||
return &h.firstOutstanding.Value
|
||||
}
|
||||
|
||||
// QueuePacketForRetransmission marks a packet for retransmission.
|
||||
// A packet can only be queued once.
|
||||
func (h *sentPacketHistory) QueuePacketForRetransmission(pn protocol.PacketNumber) (*Packet, error) {
|
||||
el, ok := h.packetMap[pn]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("sent packet history: packet %d not found", pn)
|
||||
}
|
||||
if el.Value.queuedForRetransmission {
|
||||
return nil, fmt.Errorf("sent packet history BUG: packet %d already queued for retransmission", pn)
|
||||
}
|
||||
el.Value.queuedForRetransmission = true
|
||||
if el == h.firstOutstanding {
|
||||
h.readjustFirstOutstanding()
|
||||
}
|
||||
return &el.Value, nil
|
||||
}
|
||||
|
||||
// readjustFirstOutstanding readjusts the pointer to the first outstanding packet.
|
||||
// This is necessary every time the first outstanding packet is deleted or retransmitted.
|
||||
func (h *sentPacketHistory) readjustFirstOutstanding() {
|
||||
el := h.firstOutstanding.Next()
|
||||
for el != nil && el.Value.queuedForRetransmission {
|
||||
el = el.Next()
|
||||
}
|
||||
h.firstOutstanding = el
|
||||
}
|
||||
|
||||
func (h *sentPacketHistory) Len() int {
|
||||
return len(h.packetMap)
|
||||
}
|
||||
|
||||
func (h *sentPacketHistory) Remove(p protocol.PacketNumber) error {
|
||||
el, ok := h.packetMap[p]
|
||||
if !ok {
|
||||
return fmt.Errorf("packet %d not found in sent packet history", p)
|
||||
}
|
||||
if el == h.firstOutstanding {
|
||||
h.readjustFirstOutstanding()
|
||||
}
|
||||
h.packetList.Remove(el)
|
||||
delete(h.packetMap, p)
|
||||
return nil
|
||||
}
|
22
vendor/github.com/lucas-clemente/quic-go/internal/crypto/cert_chain.go
generated
vendored
22
vendor/github.com/lucas-clemente/quic-go/internal/crypto/cert_chain.go
generated
vendored
|
@ -55,28 +55,28 @@ func (c *certChain) GetLeafCert(sni string) ([]byte, error) {
|
|||
return cert.Certificate[0], nil
|
||||
}
|
||||
|
||||
func (cc *certChain) getCertForSNI(sni string) (*tls.Certificate, error) {
|
||||
c := cc.config
|
||||
c, err := maybeGetConfigForClient(c, sni)
|
||||
func (c *certChain) getCertForSNI(sni string) (*tls.Certificate, error) {
|
||||
conf := c.config
|
||||
conf, err := maybeGetConfigForClient(conf, sni)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// The rest of this function is mostly copied from crypto/tls.getCertificate
|
||||
|
||||
if c.GetCertificate != nil {
|
||||
cert, err := c.GetCertificate(&tls.ClientHelloInfo{ServerName: sni})
|
||||
if conf.GetCertificate != nil {
|
||||
cert, err := conf.GetCertificate(&tls.ClientHelloInfo{ServerName: sni})
|
||||
if cert != nil || err != nil {
|
||||
return cert, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(c.Certificates) == 0 {
|
||||
if len(conf.Certificates) == 0 {
|
||||
return nil, errNoMatchingCertificate
|
||||
}
|
||||
|
||||
if len(c.Certificates) == 1 || c.NameToCertificate == nil {
|
||||
if len(conf.Certificates) == 1 || conf.NameToCertificate == nil {
|
||||
// There's only one choice, so no point doing any work.
|
||||
return &c.Certificates[0], nil
|
||||
return &conf.Certificates[0], nil
|
||||
}
|
||||
|
||||
name := strings.ToLower(sni)
|
||||
|
@ -84,7 +84,7 @@ func (cc *certChain) getCertForSNI(sni string) (*tls.Certificate, error) {
|
|||
name = name[:len(name)-1]
|
||||
}
|
||||
|
||||
if cert, ok := c.NameToCertificate[name]; ok {
|
||||
if cert, ok := conf.NameToCertificate[name]; ok {
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
|
@ -94,13 +94,13 @@ func (cc *certChain) getCertForSNI(sni string) (*tls.Certificate, error) {
|
|||
for i := range labels {
|
||||
labels[i] = "*"
|
||||
candidate := strings.Join(labels, ".")
|
||||
if cert, ok := c.NameToCertificate[candidate]; ok {
|
||||
if cert, ok := conf.NameToCertificate[candidate]; ok {
|
||||
return cert, nil
|
||||
}
|
||||
}
|
||||
|
||||
// If nothing matches, return the first certificate.
|
||||
return &c.Certificates[0], nil
|
||||
return &conf.Certificates[0], nil
|
||||
}
|
||||
|
||||
func maybeGetConfigForClient(c *tls.Config, sni string) (*tls.Config, error) {
|
||||
|
|
21
vendor/github.com/lucas-clemente/quic-go/internal/crypto/key_derivation.go
generated
vendored
21
vendor/github.com/lucas-clemente/quic-go/internal/crypto/key_derivation.go
generated
vendored
|
@ -1,13 +1,16 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/bifurcation/mint"
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
)
|
||||
|
||||
const (
|
||||
clientExporterLabel = "EXPORTER-QUIC client 1-RTT Secret"
|
||||
serverExporterLabel = "EXPORTER-QUIC server 1-RTT Secret"
|
||||
clientExporterLabel = "EXPORTER-QUIC client 1rtt"
|
||||
serverExporterLabel = "EXPORTER-QUIC server 1rtt"
|
||||
)
|
||||
|
||||
// A TLSExporter gets the negotiated ciphersuite and computes exporter
|
||||
|
@ -16,6 +19,16 @@ type TLSExporter interface {
|
|||
ComputeExporter(label string, context []byte, keyLength int) ([]byte, error)
|
||||
}
|
||||
|
||||
func qhkdfExpand(secret []byte, label string, length int) []byte {
|
||||
// The last byte should be 0x0.
|
||||
// Since Go initializes the slice to 0, we don't need to set it explicitly.
|
||||
qlabel := make([]byte, 2+1+5+len(label)+1)
|
||||
binary.BigEndian.PutUint16(qlabel[0:2], uint16(length))
|
||||
qlabel[2] = uint8(5 + len(label))
|
||||
copy(qlabel[3:], []byte("QUIC "+label))
|
||||
return mint.HkdfExpand(crypto.SHA256, secret, qlabel, length)
|
||||
}
|
||||
|
||||
// DeriveAESKeys derives the AES keys and creates a matching AES-GCM AEAD instance
|
||||
func DeriveAESKeys(tls TLSExporter, pers protocol.Perspective) (AEAD, error) {
|
||||
var myLabel, otherLabel string
|
||||
|
@ -43,7 +56,7 @@ func computeKeyAndIV(tls TLSExporter, label string) (key, iv []byte, err error)
|
|||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
key = mint.HkdfExpandLabel(cs.Hash, secret, "key", nil, cs.KeyLen)
|
||||
iv = mint.HkdfExpandLabel(cs.Hash, secret, "iv", nil, cs.IvLen)
|
||||
key = qhkdfExpand(secret, "key", cs.KeyLen)
|
||||
iv = qhkdfExpand(secret, "iv", cs.IvLen)
|
||||
return key, iv, nil
|
||||
}
|
||||
|
|
10
vendor/github.com/lucas-clemente/quic-go/internal/crypto/null_aead_aesgcm.go
generated
vendored
10
vendor/github.com/lucas-clemente/quic-go/internal/crypto/null_aead_aesgcm.go
generated
vendored
|
@ -31,14 +31,14 @@ func newNullAEADAESGCM(connectionID protocol.ConnectionID, pers protocol.Perspec
|
|||
func computeSecrets(connectionID protocol.ConnectionID) (clientSecret, serverSecret []byte) {
|
||||
connID := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(connID, uint64(connectionID))
|
||||
cleartextSecret := mint.HkdfExtract(crypto.SHA256, []byte(quicVersion1Salt), connID)
|
||||
clientSecret = mint.HkdfExpandLabel(crypto.SHA256, cleartextSecret, "QUIC client cleartext Secret", []byte{}, crypto.SHA256.Size())
|
||||
serverSecret = mint.HkdfExpandLabel(crypto.SHA256, cleartextSecret, "QUIC server cleartext Secret", []byte{}, crypto.SHA256.Size())
|
||||
handshakeSecret := mint.HkdfExtract(crypto.SHA256, quicVersion1Salt, connID)
|
||||
clientSecret = qhkdfExpand(handshakeSecret, "client hs", crypto.SHA256.Size())
|
||||
serverSecret = qhkdfExpand(handshakeSecret, "server hs", crypto.SHA256.Size())
|
||||
return
|
||||
}
|
||||
|
||||
func computeNullAEADKeyAndIV(secret []byte) (key, iv []byte) {
|
||||
key = mint.HkdfExpandLabel(crypto.SHA256, secret, "key", nil, 16)
|
||||
iv = mint.HkdfExpandLabel(crypto.SHA256, secret, "iv", nil, 12)
|
||||
key = qhkdfExpand(secret, "key", 16)
|
||||
iv = qhkdfExpand(secret, "iv", 12)
|
||||
return
|
||||
}
|
||||
|
|
6
vendor/github.com/lucas-clemente/quic-go/internal/handshake/cookie_handler.go
generated
vendored
6
vendor/github.com/lucas-clemente/quic-go/internal/handshake/cookie_handler.go
generated
vendored
|
@ -7,6 +7,9 @@ import (
|
|||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
)
|
||||
|
||||
// A CookieHandler generates and validates cookies.
|
||||
// The cookie is sent in the TLS Retry.
|
||||
// By including the cookie in its ClientHello, a client can proof ownership of its source address.
|
||||
type CookieHandler struct {
|
||||
callback func(net.Addr, *Cookie) bool
|
||||
|
||||
|
@ -15,6 +18,7 @@ type CookieHandler struct {
|
|||
|
||||
var _ mint.CookieHandler = &CookieHandler{}
|
||||
|
||||
// NewCookieHandler creates a new CookieHandler.
|
||||
func NewCookieHandler(callback func(net.Addr, *Cookie) bool) (*CookieHandler, error) {
|
||||
cookieGenerator, err := NewCookieGenerator()
|
||||
if err != nil {
|
||||
|
@ -26,6 +30,7 @@ func NewCookieHandler(callback func(net.Addr, *Cookie) bool) (*CookieHandler, er
|
|||
}, nil
|
||||
}
|
||||
|
||||
// Generate a new cookie for a mint connection.
|
||||
func (h *CookieHandler) Generate(conn *mint.Conn) ([]byte, error) {
|
||||
if h.callback(conn.RemoteAddr(), nil) {
|
||||
return nil, nil
|
||||
|
@ -33,6 +38,7 @@ func (h *CookieHandler) Generate(conn *mint.Conn) ([]byte, error) {
|
|||
return h.cookieGenerator.NewToken(conn.RemoteAddr())
|
||||
}
|
||||
|
||||
// Validate a cookie.
|
||||
func (h *CookieHandler) Validate(conn *mint.Conn, token []byte) bool {
|
||||
data, err := h.cookieGenerator.DecodeToken(token)
|
||||
if err != nil {
|
||||
|
|
2
vendor/github.com/lucas-clemente/quic-go/internal/handshake/crypto_setup_server.go
generated
vendored
2
vendor/github.com/lucas-clemente/quic-go/internal/handshake/crypto_setup_server.go
generated
vendored
|
@ -429,7 +429,7 @@ func (h *cryptoSetupServer) handleCHLO(sni string, data []byte, cryptoData map[T
|
|||
replyMap := h.params.getHelloMap()
|
||||
// add crypto parameters
|
||||
verTag := &bytes.Buffer{}
|
||||
for _, v := range protocol.GetGreasedVersions(h.supportedVersions) {
|
||||
for _, v := range h.supportedVersions {
|
||||
utils.BigEndian.WriteUint32(verTag, uint32(v))
|
||||
}
|
||||
replyMap[TagPUBS] = ephermalKex.PublicKey()
|
||||
|
|
5
vendor/github.com/lucas-clemente/quic-go/internal/handshake/handshake_message.go
generated
vendored
5
vendor/github.com/lucas-clemente/quic-go/internal/handshake/handshake_message.go
generated
vendored
|
@ -84,7 +84,7 @@ func (h HandshakeMessage) Write(b *bytes.Buffer) {
|
|||
|
||||
offset := uint32(0)
|
||||
for i, t := range h.getTagsSorted() {
|
||||
v := data[Tag(t)]
|
||||
v := data[t]
|
||||
b.Write(v)
|
||||
offset += uint32(len(v))
|
||||
binary.LittleEndian.PutUint32(indexData[i*8:], uint32(t))
|
||||
|
@ -111,8 +111,7 @@ func (h *HandshakeMessage) getTagsSorted() []Tag {
|
|||
func (h HandshakeMessage) String() string {
|
||||
var pad string
|
||||
res := tagToString(h.Tag) + ":\n"
|
||||
for _, t := range h.getTagsSorted() {
|
||||
tag := Tag(t)
|
||||
for _, tag := range h.getTagsSorted() {
|
||||
if tag == TagPAD {
|
||||
pad = fmt.Sprintf("\t%s: (%d bytes)\n", tagToString(tag), len(h.Data[tag]))
|
||||
} else {
|
||||
|
|
16
vendor/github.com/lucas-clemente/quic-go/internal/handshake/server_config.go
generated
vendored
16
vendor/github.com/lucas-clemente/quic-go/internal/handshake/server_config.go
generated
vendored
|
@ -9,10 +9,10 @@ import (
|
|||
|
||||
// ServerConfig is a server config
|
||||
type ServerConfig struct {
|
||||
kex crypto.KeyExchange
|
||||
certChain crypto.CertChain
|
||||
ID []byte
|
||||
obit []byte
|
||||
kex crypto.KeyExchange
|
||||
certChain crypto.CertChain
|
||||
ID []byte
|
||||
obit []byte
|
||||
cookieGenerator *CookieGenerator
|
||||
}
|
||||
|
||||
|
@ -36,10 +36,10 @@ func NewServerConfig(kex crypto.KeyExchange, certChain crypto.CertChain) (*Serve
|
|||
}
|
||||
|
||||
return &ServerConfig{
|
||||
kex: kex,
|
||||
certChain: certChain,
|
||||
ID: id,
|
||||
obit: obit,
|
||||
kex: kex,
|
||||
certChain: certChain,
|
||||
ID: id,
|
||||
obit: obit,
|
||||
cookieGenerator: cookieGenerator,
|
||||
}, nil
|
||||
}
|
||||
|
|
28
vendor/github.com/lucas-clemente/quic-go/internal/handshake/server_config_client.go
generated
vendored
28
vendor/github.com/lucas-clemente/quic-go/internal/handshake/server_config_client.go
generated
vendored
|
@ -102,32 +102,37 @@ func (s *serverConfigClient) parseValues(tagMap map[Tag][]byte) error {
|
|||
return qerr.Error(qerr.CryptoMessageParameterNotFound, "PUBS")
|
||||
}
|
||||
|
||||
var pubs_kexs []struct{Length uint32; Value []byte}
|
||||
var last_len uint32
|
||||
|
||||
for i := 0; i < len(pubs)-3; i += int(last_len)+3 {
|
||||
var pubsKexs []struct {
|
||||
Length uint32
|
||||
Value []byte
|
||||
}
|
||||
var lastLen uint32
|
||||
for i := 0; i < len(pubs)-3; i += int(lastLen) + 3 {
|
||||
// the PUBS value is always prepended by 3 byte little endian length field
|
||||
|
||||
err := binary.Read(bytes.NewReader([]byte{pubs[i], pubs[i+1], pubs[i+2], 0x00}), binary.LittleEndian, &last_len);
|
||||
err := binary.Read(bytes.NewReader([]byte{pubs[i], pubs[i+1], pubs[i+2], 0x00}), binary.LittleEndian, &lastLen)
|
||||
if err != nil {
|
||||
return qerr.Error(qerr.CryptoInvalidValueLength, "PUBS not decodable")
|
||||
}
|
||||
if last_len == 0 {
|
||||
if lastLen == 0 {
|
||||
return qerr.Error(qerr.CryptoInvalidValueLength, "PUBS")
|
||||
}
|
||||
|
||||
if i+3+int(last_len) > len(pubs) {
|
||||
if i+3+int(lastLen) > len(pubs) {
|
||||
return qerr.Error(qerr.CryptoInvalidValueLength, "PUBS")
|
||||
}
|
||||
|
||||
pubs_kexs = append(pubs_kexs, struct{Length uint32; Value []byte}{last_len, pubs[i+3:i+3+int(last_len)]})
|
||||
pubsKexs = append(pubsKexs, struct {
|
||||
Length uint32
|
||||
Value []byte
|
||||
}{lastLen, pubs[i+3 : i+3+int(lastLen)]})
|
||||
}
|
||||
|
||||
if c255Foundat >= len(pubs_kexs) {
|
||||
if c255Foundat >= len(pubsKexs) {
|
||||
return qerr.Error(qerr.CryptoMessageParameterNotFound, "KEXS not in PUBS")
|
||||
}
|
||||
|
||||
if pubs_kexs[c255Foundat].Length != 32 {
|
||||
if pubsKexs[c255Foundat].Length != 32 {
|
||||
return qerr.Error(qerr.CryptoInvalidValueLength, "PUBS")
|
||||
}
|
||||
|
||||
|
@ -137,8 +142,7 @@ func (s *serverConfigClient) parseValues(tagMap map[Tag][]byte) error {
|
|||
return err
|
||||
}
|
||||
|
||||
|
||||
s.sharedSecret, err = s.kex.CalculateSharedKey(pubs_kexs[c255Foundat].Value)
|
||||
s.sharedSecret, err = s.kex.CalculateSharedKey(pubsKexs[c255Foundat].Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
16
vendor/github.com/lucas-clemente/quic-go/internal/handshake/tls_extension.go
generated
vendored
16
vendor/github.com/lucas-clemente/quic-go/internal/handshake/tls_extension.go
generated
vendored
|
@ -9,14 +9,14 @@ type transportParameterID uint16
|
|||
const quicTLSExtensionType = 26
|
||||
|
||||
const (
|
||||
initialMaxStreamDataParameterID transportParameterID = 0x0
|
||||
initialMaxDataParameterID transportParameterID = 0x1
|
||||
initialMaxStreamIDBiDiParameterID transportParameterID = 0x2
|
||||
idleTimeoutParameterID transportParameterID = 0x3
|
||||
omitConnectionIDParameterID transportParameterID = 0x4
|
||||
maxPacketSizeParameterID transportParameterID = 0x5
|
||||
statelessResetTokenParameterID transportParameterID = 0x6
|
||||
initialMaxStreamIDUniParameterID transportParameterID = 0x8
|
||||
initialMaxStreamDataParameterID transportParameterID = 0x0
|
||||
initialMaxDataParameterID transportParameterID = 0x1
|
||||
initialMaxStreamsBiDiParameterID transportParameterID = 0x2
|
||||
idleTimeoutParameterID transportParameterID = 0x3
|
||||
omitConnectionIDParameterID transportParameterID = 0x4
|
||||
maxPacketSizeParameterID transportParameterID = 0x5
|
||||
statelessResetTokenParameterID transportParameterID = 0x6
|
||||
initialMaxStreamsUniParameterID transportParameterID = 0x8
|
||||
)
|
||||
|
||||
type transportParameter struct {
|
||||
|
|
|
@ -3,13 +3,13 @@ package handshake
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/qerr"
|
||||
|
||||
"github.com/bifurcation/mint"
|
||||
"github.com/bifurcation/mint/syntax"
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
)
|
||||
|
||||
type extensionHandlerClient struct {
|
||||
|
@ -31,7 +31,10 @@ func NewExtensionHandlerClient(
|
|||
supportedVersions []protocol.VersionNumber,
|
||||
version protocol.VersionNumber,
|
||||
) TLSExtensionHandler {
|
||||
paramsChan := make(chan TransportParameters, 1)
|
||||
// The client reads the transport parameters from the Encrypted Extensions message.
|
||||
// The paramsChan is used in the session's run loop's select statement.
|
||||
// We have to use an unbuffered channel here to make sure that the session actually processes the transport parameters immediately.
|
||||
paramsChan := make(chan TransportParameters)
|
||||
return &extensionHandlerClient{
|
||||
ourParams: params,
|
||||
paramsChan: paramsChan,
|
||||
|
@ -46,6 +49,7 @@ func (h *extensionHandlerClient) Send(hType mint.HandshakeType, el *mint.Extensi
|
|||
return nil
|
||||
}
|
||||
|
||||
utils.Debugf("Sending Transport Parameters: %s", h.ourParams)
|
||||
data, err := syntax.Marshal(clientHelloTransportParameters{
|
||||
InitialVersion: uint32(h.initialVersion),
|
||||
Parameters: h.ourParams.getTransportParameters(),
|
||||
|
@ -63,17 +67,12 @@ func (h *extensionHandlerClient) Receive(hType mint.HandshakeType, el *mint.Exte
|
|||
return err
|
||||
}
|
||||
|
||||
if hType != mint.HandshakeTypeEncryptedExtensions && hType != mint.HandshakeTypeNewSessionTicket {
|
||||
if hType != mint.HandshakeTypeEncryptedExtensions {
|
||||
if found {
|
||||
return fmt.Errorf("Unexpected QUIC extension in handshake message %d", hType)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if hType == mint.HandshakeTypeNewSessionTicket {
|
||||
// the extension it's optional in the NewSessionTicket message
|
||||
// TODO: handle this
|
||||
return nil
|
||||
}
|
||||
|
||||
// hType == mint.HandshakeTypeEncryptedExtensions
|
||||
if !found {
|
||||
|
@ -119,12 +118,11 @@ func (h *extensionHandlerClient) Receive(hType mint.HandshakeType, el *mint.Exte
|
|||
// TODO: return the right error here
|
||||
return errors.New("server didn't sent stateless_reset_token")
|
||||
}
|
||||
params, err := readTransportParamters(eetp.Parameters)
|
||||
params, err := readTransportParameters(eetp.Parameters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO(#878): remove this when implementing the MAX_STREAM_ID frame
|
||||
params.MaxStreams = math.MaxUint32
|
||||
utils.Debugf("Received Transport Parameters: %s", params)
|
||||
h.paramsChan <- *params
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/bifurcation/mint"
|
||||
"github.com/bifurcation/mint/syntax"
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
)
|
||||
|
||||
type extensionHandlerServer struct {
|
||||
|
@ -29,6 +30,8 @@ func NewExtensionHandlerServer(
|
|||
supportedVersions []protocol.VersionNumber,
|
||||
version protocol.VersionNumber,
|
||||
) TLSExtensionHandler {
|
||||
// Processing the ClientHello is performed statelessly (and from a single go-routine).
|
||||
// Therefore, we have to use a buffered chan to pass the transport parameters to that go routine.
|
||||
paramsChan := make(chan TransportParameters, 1)
|
||||
return &extensionHandlerServer{
|
||||
ourParams: params,
|
||||
|
@ -53,6 +56,7 @@ func (h *extensionHandlerServer) Send(hType mint.HandshakeType, el *mint.Extensi
|
|||
for i, v := range supportedVersions {
|
||||
versions[i] = uint32(v)
|
||||
}
|
||||
utils.Debugf("Sending Transport Parameters: %s", h.ourParams)
|
||||
data, err := syntax.Marshal(encryptedExtensionsTransportParameters{
|
||||
NegotiatedVersion: uint32(h.version),
|
||||
SupportedVersions: versions,
|
||||
|
@ -100,10 +104,11 @@ func (h *extensionHandlerServer) Receive(hType mint.HandshakeType, el *mint.Exte
|
|||
return errors.New("client sent a stateless reset token")
|
||||
}
|
||||
}
|
||||
params, err := readTransportParamters(chtp.Parameters)
|
||||
params, err := readTransportParameters(chtp.Parameters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
utils.Debugf("Received Transport Parameters: %s", params)
|
||||
h.paramsChan <- *params
|
||||
return nil
|
||||
}
|
||||
|
|
55
vendor/github.com/lucas-clemente/quic-go/internal/handshake/transport_parameters.go
generated
vendored
55
vendor/github.com/lucas-clemente/quic-go/internal/handshake/transport_parameters.go
generated
vendored
|
@ -20,9 +20,11 @@ type TransportParameters struct {
|
|||
StreamFlowControlWindow protocol.ByteCount
|
||||
ConnectionFlowControlWindow protocol.ByteCount
|
||||
|
||||
MaxBidiStreamID protocol.StreamID // only used for IETF QUIC
|
||||
MaxUniStreamID protocol.StreamID // only used for IETF QUIC
|
||||
MaxStreams uint32 // only used for gQUIC
|
||||
MaxPacketSize protocol.ByteCount
|
||||
|
||||
MaxUniStreams uint16 // only used for IETF QUIC
|
||||
MaxBidiStreams uint16 // only used for IETF QUIC
|
||||
MaxStreams uint32 // only used for gQUIC
|
||||
|
||||
OmitConnectionID bool
|
||||
IdleTimeout time.Duration
|
||||
|
@ -93,7 +95,7 @@ func (p *TransportParameters) getHelloMap() map[Tag][]byte {
|
|||
}
|
||||
|
||||
// readTransportParameters reads the transport parameters sent in the QUIC TLS extension
|
||||
func readTransportParamters(paramsList []transportParameter) (*TransportParameters, error) {
|
||||
func readTransportParameters(paramsList []transportParameter) (*TransportParameters, error) {
|
||||
params := &TransportParameters{}
|
||||
|
||||
var foundInitialMaxStreamData bool
|
||||
|
@ -114,18 +116,16 @@ func readTransportParamters(paramsList []transportParameter) (*TransportParamete
|
|||
return nil, fmt.Errorf("wrong length for initial_max_data: %d (expected 4)", len(p.Value))
|
||||
}
|
||||
params.ConnectionFlowControlWindow = protocol.ByteCount(binary.BigEndian.Uint32(p.Value))
|
||||
case initialMaxStreamIDBiDiParameterID:
|
||||
if len(p.Value) != 4 {
|
||||
return nil, fmt.Errorf("wrong length for initial_max_stream_id_bidi: %d (expected 4)", len(p.Value))
|
||||
case initialMaxStreamsBiDiParameterID:
|
||||
if len(p.Value) != 2 {
|
||||
return nil, fmt.Errorf("wrong length for initial_max_stream_id_bidi: %d (expected 2)", len(p.Value))
|
||||
}
|
||||
// TODO(#1154): validate the stream ID
|
||||
params.MaxBidiStreamID = protocol.StreamID(binary.BigEndian.Uint32(p.Value))
|
||||
case initialMaxStreamIDUniParameterID:
|
||||
if len(p.Value) != 4 {
|
||||
return nil, fmt.Errorf("wrong length for initial_max_stream_id_uni: %d (expected 4)", len(p.Value))
|
||||
params.MaxBidiStreams = binary.BigEndian.Uint16(p.Value)
|
||||
case initialMaxStreamsUniParameterID:
|
||||
if len(p.Value) != 2 {
|
||||
return nil, fmt.Errorf("wrong length for initial_max_stream_id_uni: %d (expected 2)", len(p.Value))
|
||||
}
|
||||
// TODO(#1154): validate the stream ID
|
||||
params.MaxUniStreamID = protocol.StreamID(binary.BigEndian.Uint32(p.Value))
|
||||
params.MaxUniStreams = binary.BigEndian.Uint16(p.Value)
|
||||
case idleTimeoutParameterID:
|
||||
foundIdleTimeout = true
|
||||
if len(p.Value) != 2 {
|
||||
|
@ -137,6 +137,15 @@ func readTransportParamters(paramsList []transportParameter) (*TransportParamete
|
|||
return nil, fmt.Errorf("wrong length for omit_connection_id: %d (expected empty)", len(p.Value))
|
||||
}
|
||||
params.OmitConnectionID = true
|
||||
case maxPacketSizeParameterID:
|
||||
if len(p.Value) != 2 {
|
||||
return nil, fmt.Errorf("wrong length for max_packet_size: %d (expected 2)", len(p.Value))
|
||||
}
|
||||
maxPacketSize := protocol.ByteCount(binary.BigEndian.Uint16(p.Value))
|
||||
if maxPacketSize < 1200 {
|
||||
return nil, fmt.Errorf("invalid value for max_packet_size: %d (minimum 1200)", maxPacketSize)
|
||||
}
|
||||
params.MaxPacketSize = maxPacketSize
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,10 +162,10 @@ func (p *TransportParameters) getTransportParameters() []transportParameter {
|
|||
binary.BigEndian.PutUint32(initialMaxStreamData, uint32(p.StreamFlowControlWindow))
|
||||
initialMaxData := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(initialMaxData, uint32(p.ConnectionFlowControlWindow))
|
||||
initialMaxBidiStreamID := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(initialMaxBidiStreamID, uint32(p.MaxBidiStreamID))
|
||||
initialMaxUniStreamID := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(initialMaxUniStreamID, uint32(p.MaxUniStreamID))
|
||||
initialMaxBidiStreamID := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(initialMaxBidiStreamID, p.MaxBidiStreams)
|
||||
initialMaxUniStreamID := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(initialMaxUniStreamID, p.MaxUniStreams)
|
||||
idleTimeout := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(idleTimeout, uint16(p.IdleTimeout/time.Second))
|
||||
maxPacketSize := make([]byte, 2)
|
||||
|
@ -164,8 +173,8 @@ func (p *TransportParameters) getTransportParameters() []transportParameter {
|
|||
params := []transportParameter{
|
||||
{initialMaxStreamDataParameterID, initialMaxStreamData},
|
||||
{initialMaxDataParameterID, initialMaxData},
|
||||
{initialMaxStreamIDBiDiParameterID, initialMaxBidiStreamID},
|
||||
{initialMaxStreamIDUniParameterID, initialMaxUniStreamID},
|
||||
{initialMaxStreamsBiDiParameterID, initialMaxBidiStreamID},
|
||||
{initialMaxStreamsUniParameterID, initialMaxUniStreamID},
|
||||
{idleTimeoutParameterID, idleTimeout},
|
||||
{maxPacketSizeParameterID, maxPacketSize},
|
||||
}
|
||||
|
@ -174,3 +183,9 @@ func (p *TransportParameters) getTransportParameters() []transportParameter {
|
|||
}
|
||||
return params
|
||||
}
|
||||
|
||||
// String returns a string representation, intended for logging.
|
||||
// It should only used for IETF QUIC.
|
||||
func (p *TransportParameters) String() string {
|
||||
return fmt.Sprintf("&handshake.TransportParameters{StreamFlowControlWindow: %#x, ConnectionFlowControlWindow: %#x, MaxBidiStreams: %d, MaxUniStreams: %d, OmitConnectionID: %t, IdleTimeout: %s}", p.StreamFlowControlWindow, p.ConnectionFlowControlWindow, p.MaxBidiStreams, p.MaxUniStreams, p.OmitConnectionID, p.IdleTimeout)
|
||||
}
|
||||
|
|
|
@ -61,18 +61,6 @@ func (mr *MockSentPacketHandlerMockRecorder) GetAlarmTimeout() *gomock.Call {
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlarmTimeout", reflect.TypeOf((*MockSentPacketHandler)(nil).GetAlarmTimeout))
|
||||
}
|
||||
|
||||
// GetLeastUnacked mocks base method
|
||||
func (m *MockSentPacketHandler) GetLeastUnacked() protocol.PacketNumber {
|
||||
ret := m.ctrl.Call(m, "GetLeastUnacked")
|
||||
ret0, _ := ret[0].(protocol.PacketNumber)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetLeastUnacked indicates an expected call of GetLeastUnacked
|
||||
func (mr *MockSentPacketHandlerMockRecorder) GetLeastUnacked() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLeastUnacked", reflect.TypeOf((*MockSentPacketHandler)(nil).GetLeastUnacked))
|
||||
}
|
||||
|
||||
// GetLowestPacketNotConfirmedAcked mocks base method
|
||||
func (m *MockSentPacketHandler) GetLowestPacketNotConfirmedAcked() protocol.PacketNumber {
|
||||
ret := m.ctrl.Call(m, "GetLowestPacketNotConfirmedAcked")
|
||||
|
@ -85,6 +73,18 @@ func (mr *MockSentPacketHandlerMockRecorder) GetLowestPacketNotConfirmedAcked()
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLowestPacketNotConfirmedAcked", reflect.TypeOf((*MockSentPacketHandler)(nil).GetLowestPacketNotConfirmedAcked))
|
||||
}
|
||||
|
||||
// GetPacketNumberLen mocks base method
|
||||
func (m *MockSentPacketHandler) GetPacketNumberLen(arg0 protocol.PacketNumber) protocol.PacketNumberLen {
|
||||
ret := m.ctrl.Call(m, "GetPacketNumberLen", arg0)
|
||||
ret0, _ := ret[0].(protocol.PacketNumberLen)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetPacketNumberLen indicates an expected call of GetPacketNumberLen
|
||||
func (mr *MockSentPacketHandlerMockRecorder) GetPacketNumberLen(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPacketNumberLen", reflect.TypeOf((*MockSentPacketHandler)(nil).GetPacketNumberLen), arg0)
|
||||
}
|
||||
|
||||
// GetStopWaitingFrame mocks base method
|
||||
func (m *MockSentPacketHandler) GetStopWaitingFrame(arg0 bool) *wire.StopWaitingFrame {
|
||||
ret := m.ctrl.Call(m, "GetStopWaitingFrame", arg0)
|
||||
|
@ -98,8 +98,10 @@ func (mr *MockSentPacketHandlerMockRecorder) GetStopWaitingFrame(arg0 interface{
|
|||
}
|
||||
|
||||
// OnAlarm mocks base method
|
||||
func (m *MockSentPacketHandler) OnAlarm() {
|
||||
m.ctrl.Call(m, "OnAlarm")
|
||||
func (m *MockSentPacketHandler) OnAlarm() error {
|
||||
ret := m.ctrl.Call(m, "OnAlarm")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// OnAlarm indicates an expected call of OnAlarm
|
||||
|
@ -119,23 +121,21 @@ func (mr *MockSentPacketHandlerMockRecorder) ReceivedAck(arg0, arg1, arg2, arg3
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedAck", reflect.TypeOf((*MockSentPacketHandler)(nil).ReceivedAck), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SendingAllowed mocks base method
|
||||
func (m *MockSentPacketHandler) SendingAllowed() bool {
|
||||
ret := m.ctrl.Call(m, "SendingAllowed")
|
||||
ret0, _ := ret[0].(bool)
|
||||
// SendMode mocks base method
|
||||
func (m *MockSentPacketHandler) SendMode() ackhandler.SendMode {
|
||||
ret := m.ctrl.Call(m, "SendMode")
|
||||
ret0, _ := ret[0].(ackhandler.SendMode)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SendingAllowed indicates an expected call of SendingAllowed
|
||||
func (mr *MockSentPacketHandlerMockRecorder) SendingAllowed() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendingAllowed", reflect.TypeOf((*MockSentPacketHandler)(nil).SendingAllowed))
|
||||
// SendMode indicates an expected call of SendMode
|
||||
func (mr *MockSentPacketHandlerMockRecorder) SendMode() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMode", reflect.TypeOf((*MockSentPacketHandler)(nil).SendMode))
|
||||
}
|
||||
|
||||
// SentPacket mocks base method
|
||||
func (m *MockSentPacketHandler) SentPacket(arg0 *ackhandler.Packet) error {
|
||||
ret := m.ctrl.Call(m, "SentPacket", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
func (m *MockSentPacketHandler) SentPacket(arg0 *ackhandler.Packet) {
|
||||
m.ctrl.Call(m, "SentPacket", arg0)
|
||||
}
|
||||
|
||||
// SentPacket indicates an expected call of SentPacket
|
||||
|
@ -143,6 +143,16 @@ func (mr *MockSentPacketHandlerMockRecorder) SentPacket(arg0 interface{}) *gomoc
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockSentPacketHandler)(nil).SentPacket), arg0)
|
||||
}
|
||||
|
||||
// SentPacketsAsRetransmission mocks base method
|
||||
func (m *MockSentPacketHandler) SentPacketsAsRetransmission(arg0 []*ackhandler.Packet, arg1 protocol.PacketNumber) {
|
||||
m.ctrl.Call(m, "SentPacketsAsRetransmission", arg0, arg1)
|
||||
}
|
||||
|
||||
// SentPacketsAsRetransmission indicates an expected call of SentPacketsAsRetransmission
|
||||
func (mr *MockSentPacketHandlerMockRecorder) SentPacketsAsRetransmission(arg0, arg1 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacketsAsRetransmission", reflect.TypeOf((*MockSentPacketHandler)(nil).SentPacketsAsRetransmission), arg0, arg1)
|
||||
}
|
||||
|
||||
// SetHandshakeComplete mocks base method
|
||||
func (m *MockSentPacketHandler) SetHandshakeComplete() {
|
||||
m.ctrl.Call(m, "SetHandshakeComplete")
|
||||
|
|
16
vendor/github.com/lucas-clemente/quic-go/internal/protocol/protocol.go
generated
vendored
16
vendor/github.com/lucas-clemente/quic-go/internal/protocol/protocol.go
generated
vendored
|
@ -27,14 +27,14 @@ const (
|
|||
type PacketType uint8
|
||||
|
||||
const (
|
||||
// PacketTypeInitial is the packet type of a Initial packet
|
||||
PacketTypeInitial PacketType = 2
|
||||
// PacketTypeInitial is the packet type of an Initial packet
|
||||
PacketTypeInitial PacketType = 0x7f
|
||||
// PacketTypeRetry is the packet type of a Retry packet
|
||||
PacketTypeRetry PacketType = 3
|
||||
// PacketTypeHandshake is the packet type of a Cleartext packet
|
||||
PacketTypeHandshake PacketType = 4
|
||||
PacketTypeRetry PacketType = 0x7e
|
||||
// PacketTypeHandshake is the packet type of a Handshake packet
|
||||
PacketTypeHandshake PacketType = 0x7d
|
||||
// PacketType0RTT is the packet type of a 0-RTT packet
|
||||
PacketType0RTT PacketType = 5
|
||||
PacketType0RTT PacketType = 0x7c
|
||||
)
|
||||
|
||||
func (t PacketType) String() string {
|
||||
|
@ -77,11 +77,11 @@ const DefaultTCPMSS ByteCount = 1460
|
|||
// MinClientHelloSize is the minimum size the server expects an inchoate CHLO to have (in gQUIC)
|
||||
const MinClientHelloSize = 1024
|
||||
|
||||
// MinInitialPacketSize is the minimum size an Initial packet (in IETF QUIC) is requried to have.
|
||||
// MinInitialPacketSize is the minimum size an Initial packet (in IETF QUIC) is required to have.
|
||||
const MinInitialPacketSize = 1200
|
||||
|
||||
// MaxClientHellos is the maximum number of times we'll send a client hello
|
||||
// The value 3 accounts for:
|
||||
// * one failure due to an incorrect or missing source-address token
|
||||
// * one failure due the server's certificate chain being unavailible and the server being unwilling to send it without a valid source-address token
|
||||
// * one failure due the server's certificate chain being unavailable and the server being unwilling to send it without a valid source-address token
|
||||
const MaxClientHellos = 3
|
||||
|
|
37
vendor/github.com/lucas-clemente/quic-go/internal/protocol/server_parameters.go
generated
vendored
37
vendor/github.com/lucas-clemente/quic-go/internal/protocol/server_parameters.go
generated
vendored
|
@ -2,9 +2,11 @@ package protocol
|
|||
|
||||
import "time"
|
||||
|
||||
// MaxPacketSize is the maximum packet size that we use for sending packets.
|
||||
// It includes the QUIC packet header, but excludes the UDP and IP header.
|
||||
const MaxPacketSize ByteCount = 1200
|
||||
// MaxPacketSizeIPv4 is the maximum packet size that we use for sending IPv4 packets.
|
||||
const MaxPacketSizeIPv4 = 1252
|
||||
|
||||
// MaxPacketSizeIPv6 is the maximum packet size that we use for sending IPv6 packets.
|
||||
const MaxPacketSizeIPv6 = 1232
|
||||
|
||||
// NonForwardSecurePacketSizeReduction is the number of bytes a non forward-secure packet has to be smaller than a forward-secure packet
|
||||
// This makes sure that those packets can always be retransmitted without splitting the contained StreamFrames
|
||||
|
@ -24,10 +26,6 @@ const MaxUndecryptablePackets = 10
|
|||
// This timeout allows the Go scheduler to switch to the Go rountine that reads the crypto stream and to escalate the crypto
|
||||
const PublicResetTimeout = 500 * time.Millisecond
|
||||
|
||||
// AckSendDelay is the maximum delay that can be applied to an ACK for a retransmittable packet
|
||||
// This is the value Chromium is using
|
||||
const AckSendDelay = 25 * time.Millisecond
|
||||
|
||||
// ReceiveStreamFlowControlWindow is the stream-level flow control window for receiving data
|
||||
// This is the value that Google servers are using
|
||||
const ReceiveStreamFlowControlWindow = (1 << 10) * 32 // 32 kB
|
||||
|
@ -59,8 +57,11 @@ const ConnectionFlowControlMultiplier = 1.5
|
|||
// WindowUpdateThreshold is the fraction of the receive window that has to be consumed before an higher offset is advertised to the client
|
||||
const WindowUpdateThreshold = 0.25
|
||||
|
||||
// MaxIncomingStreams is the maximum number of streams that a peer may open
|
||||
const MaxIncomingStreams = 100
|
||||
// DefaultMaxIncomingStreams is the maximum number of streams that a peer may open
|
||||
const DefaultMaxIncomingStreams = 100
|
||||
|
||||
// DefaultMaxIncomingUniStreams is the maximum number of unidirectional streams that a peer may open
|
||||
const DefaultMaxIncomingUniStreams = 100
|
||||
|
||||
// MaxStreamsMultiplier is the slack the client is allowed for the maximum number of streams per connection, needed e.g. when packets are out of order or dropped. The minimum of this procentual increase and the absolute increment specified by MaxStreamsMinimumIncrement is used.
|
||||
const MaxStreamsMultiplier = 1.1
|
||||
|
@ -68,10 +69,6 @@ const MaxStreamsMultiplier = 1.1
|
|||
// MaxStreamsMinimumIncrement is the slack the client is allowed for the maximum number of streams per connection, needed e.g. when packets are out of order or dropped. The minimum of this absolute increment and the procentual increase specified by MaxStreamsMultiplier is used.
|
||||
const MaxStreamsMinimumIncrement = 10
|
||||
|
||||
// MaxNewStreamIDDelta is the maximum difference between and a newly opened Stream and the highest StreamID that a client has ever opened
|
||||
// note that the number of streams is half this value, since the client can only open streams with open StreamID
|
||||
const MaxNewStreamIDDelta = 4 * MaxIncomingStreams
|
||||
|
||||
// MaxSessionUnprocessedPackets is the max number of packets stored in each session that are not yet processed.
|
||||
const MaxSessionUnprocessedPackets = DefaultMaxCongestionWindow
|
||||
|
||||
|
@ -84,8 +81,15 @@ const MaxTrackedSkippedPackets = 10
|
|||
// CookieExpiryTime is the valid time of a cookie
|
||||
const CookieExpiryTime = 24 * time.Hour
|
||||
|
||||
// MaxTrackedSentPackets is maximum number of sent packets saved for either later retransmission or entropy calculation
|
||||
const MaxTrackedSentPackets = 2 * DefaultMaxCongestionWindow
|
||||
// MaxOutstandingSentPackets is maximum number of packets saved for retransmission.
|
||||
// When reached, it imposes a soft limit on sending new packets:
|
||||
// Sending ACKs and retransmission is still allowed, but now new regular packets can be sent.
|
||||
const MaxOutstandingSentPackets = 2 * DefaultMaxCongestionWindow
|
||||
|
||||
// MaxTrackedSentPackets is maximum number of sent packets saved for retransmission.
|
||||
// When reached, no more packets will be sent.
|
||||
// This value *must* be larger than MaxOutstandingSentPackets.
|
||||
const MaxTrackedSentPackets = MaxOutstandingSentPackets * 5 / 4
|
||||
|
||||
// MaxTrackedReceivedAckRanges is the maximum number of ACK ranges tracked
|
||||
const MaxTrackedReceivedAckRanges = DefaultMaxCongestionWindow
|
||||
|
@ -93,9 +97,6 @@ const MaxTrackedReceivedAckRanges = DefaultMaxCongestionWindow
|
|||
// MaxNonRetransmittableAcks is the maximum number of packets containing an ACK, but no retransmittable frames, that we send in a row
|
||||
const MaxNonRetransmittableAcks = 19
|
||||
|
||||
// RetransmittablePacketsBeforeAck is the number of retransmittable that an ACK is sent for
|
||||
const RetransmittablePacketsBeforeAck = 10
|
||||
|
||||
// MaxStreamFrameSorterGaps is the maximum number of gaps between received StreamFrames
|
||||
// prevents DoS attacks against the streamFrameSorter
|
||||
const MaxStreamFrameSorterGaps = 1000
|
||||
|
|
17
vendor/github.com/lucas-clemente/quic-go/internal/protocol/version.go
generated
vendored
17
vendor/github.com/lucas-clemente/quic-go/internal/protocol/version.go
generated
vendored
|
@ -4,10 +4,11 @@ import (
|
|||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
// VersionNumber is a version number as int
|
||||
type VersionNumber int32
|
||||
type VersionNumber uint32
|
||||
|
||||
// gQUIC version range as defined in the wiki: https://github.com/quicwg/base-drafts/wiki/QUIC-Versions
|
||||
const (
|
||||
|
@ -20,7 +21,7 @@ const (
|
|||
Version39 VersionNumber = gquicVersion0 + 3*0x100 + 0x9 + iota
|
||||
VersionTLS VersionNumber = 101
|
||||
VersionWhatever VersionNumber = 0 // for when the version doesn't matter
|
||||
VersionUnknown VersionNumber = -1
|
||||
VersionUnknown VersionNumber = math.MaxUint32
|
||||
)
|
||||
|
||||
// SupportedVersions lists the versions that the server supports
|
||||
|
@ -29,6 +30,11 @@ var SupportedVersions = []VersionNumber{
|
|||
Version39,
|
||||
}
|
||||
|
||||
// IsValidVersion says if the version is known to quic-go
|
||||
func IsValidVersion(v VersionNumber) bool {
|
||||
return v == VersionTLS || IsSupportedVersion(SupportedVersions, v)
|
||||
}
|
||||
|
||||
// UsesTLS says if this QUIC version uses TLS 1.3 for the handshake
|
||||
func (vn VersionNumber) UsesTLS() bool {
|
||||
return vn == VersionTLS
|
||||
|
@ -46,7 +52,7 @@ func (vn VersionNumber) String() string {
|
|||
if vn.isGQUIC() {
|
||||
return fmt.Sprintf("gQUIC %d", vn.toGQUICVersion())
|
||||
}
|
||||
return fmt.Sprintf("%d", vn)
|
||||
return fmt.Sprintf("%#x", uint32(vn))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,6 +77,11 @@ func (vn VersionNumber) UsesIETFFrameFormat() bool {
|
|||
return vn != Version39
|
||||
}
|
||||
|
||||
// UsesStopWaitingFrames tells if this version uses STOP_WAITING frames
|
||||
func (vn VersionNumber) UsesStopWaitingFrames() bool {
|
||||
return vn == Version39
|
||||
}
|
||||
|
||||
// StreamContributesToConnectionFlowControl says if a stream contributes to connection-level flow control
|
||||
func (vn VersionNumber) StreamContributesToConnectionFlowControl(id StreamID) bool {
|
||||
if id == vn.CryptoStreamID() {
|
||||
|
|
2
vendor/github.com/lucas-clemente/quic-go/internal/utils/timer.go
generated
vendored
2
vendor/github.com/lucas-clemente/quic-go/internal/utils/timer.go
generated
vendored
|
@ -31,7 +31,7 @@ func (t *Timer) Reset(deadline time.Time) {
|
|||
if !t.t.Stop() && !t.read {
|
||||
<-t.t.C
|
||||
}
|
||||
t.t.Reset(deadline.Sub(time.Now()))
|
||||
t.t.Reset(time.Until(deadline))
|
||||
|
||||
t.read = false
|
||||
t.deadline = deadline
|
||||
|
|
6
vendor/github.com/lucas-clemente/quic-go/internal/wire/ack_frame.go
generated
vendored
6
vendor/github.com/lucas-clemente/quic-go/internal/wire/ack_frame.go
generated
vendored
|
@ -60,7 +60,7 @@ func ParseAckFrame(r *bytes.Reader, version protocol.VersionNumber) (*AckFrame,
|
|||
if ackBlock > frame.LargestAcked {
|
||||
return nil, errors.New("invalid first ACK range")
|
||||
}
|
||||
smallest := frame.LargestAcked - protocol.PacketNumber(ackBlock)
|
||||
smallest := frame.LargestAcked - ackBlock
|
||||
|
||||
// read all the other ACK ranges
|
||||
if numBlocks > 0 {
|
||||
|
@ -86,7 +86,7 @@ func ParseAckFrame(r *bytes.Reader, version protocol.VersionNumber) (*AckFrame,
|
|||
if ackBlock > largest {
|
||||
return nil, errInvalidAckRanges
|
||||
}
|
||||
smallest = largest - protocol.PacketNumber(ackBlock)
|
||||
smallest = largest - ackBlock
|
||||
frame.AckRanges = append(frame.AckRanges, AckRange{First: smallest, Last: largest})
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ func (f *AckFrame) Length(version protocol.VersionNumber) protocol.ByteCount {
|
|||
return f.lengthLegacy(version)
|
||||
}
|
||||
|
||||
length := 1 + utils.VarIntLen(uint64(f.LargestAcked)) + utils.VarIntLen(uint64(encodeAckDelay(f.DelayTime)))
|
||||
length := 1 + utils.VarIntLen(uint64(f.LargestAcked)) + utils.VarIntLen(encodeAckDelay(f.DelayTime))
|
||||
|
||||
var lowestInFirstRange protocol.PacketNumber
|
||||
if f.HasMissingRanges() {
|
||||
|
|
5
vendor/github.com/lucas-clemente/quic-go/internal/wire/ack_range.go
generated
vendored
5
vendor/github.com/lucas-clemente/quic-go/internal/wire/ack_range.go
generated
vendored
|
@ -7,3 +7,8 @@ type AckRange struct {
|
|||
First protocol.PacketNumber
|
||||
Last protocol.PacketNumber
|
||||
}
|
||||
|
||||
// Len returns the number of packets contained in this ACK range
|
||||
func (r AckRange) Len() protocol.PacketNumber {
|
||||
return r.Last - r.First + 1
|
||||
}
|
||||
|
|
4
vendor/github.com/lucas-clemente/quic-go/internal/wire/connection_close_frame.go
generated
vendored
4
vendor/github.com/lucas-clemente/quic-go/internal/wire/connection_close_frame.go
generated
vendored
|
@ -48,7 +48,7 @@ func ParseConnectionCloseFrame(r *bytes.Reader, version protocol.VersionNumber)
|
|||
reasonPhraseLen = uint64(length)
|
||||
}
|
||||
|
||||
// shortcut to prevent the unneccessary allocation of dataLen bytes
|
||||
// shortcut to prevent the unnecessary allocation of dataLen bytes
|
||||
// if the dataLen is larger than the remaining length of the packet
|
||||
// reading the whole reason phrase would result in EOF when attempting to READ
|
||||
if int(reasonPhraseLen) > r.Len() {
|
||||
|
@ -62,7 +62,7 @@ func ParseConnectionCloseFrame(r *bytes.Reader, version protocol.VersionNumber)
|
|||
}
|
||||
|
||||
return &ConnectionCloseFrame{
|
||||
ErrorCode: qerr.ErrorCode(errorCode),
|
||||
ErrorCode: errorCode,
|
||||
ReasonPhrase: string(reasonPhrase),
|
||||
}, nil
|
||||
}
|
||||
|
|
2
vendor/github.com/lucas-clemente/quic-go/internal/wire/goaway_frame.go
generated
vendored
2
vendor/github.com/lucas-clemente/quic-go/internal/wire/goaway_frame.go
generated
vendored
|
@ -41,7 +41,7 @@ func ParseGoawayFrame(r *bytes.Reader, _ protocol.VersionNumber) (*GoawayFrame,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if reasonPhraseLen > uint16(protocol.MaxPacketSize) {
|
||||
if reasonPhraseLen > uint16(protocol.MaxReceivePacketSize) {
|
||||
return nil, qerr.Error(qerr.InvalidGoawayData, "reason phrase too long")
|
||||
}
|
||||
|
||||
|
|
14
vendor/github.com/lucas-clemente/quic-go/internal/wire/header.go
generated
vendored
14
vendor/github.com/lucas-clemente/quic-go/internal/wire/header.go
generated
vendored
|
@ -50,6 +50,7 @@ func ParseHeaderSentByServer(b *bytes.Reader, version protocol.VersionNumber) (*
|
|||
// the client knows the version that this packet was sent with
|
||||
isPublicHeader = !version.UsesTLS()
|
||||
}
|
||||
|
||||
return parsePacketHeader(b, protocol.PerspectiveServer, isPublicHeader)
|
||||
}
|
||||
|
||||
|
@ -61,12 +62,13 @@ func ParseHeaderSentByClient(b *bytes.Reader) (*Header, error) {
|
|||
}
|
||||
_ = b.UnreadByte() // unread the type byte
|
||||
|
||||
// If this is a gQUIC header 0x80 and 0x40 will be set to 0.
|
||||
// If this is an IETF QUIC header there are two options:
|
||||
// * either 0x80 will be 1 (for the Long Header)
|
||||
// * or 0x40 (the Connection ID Flag) will be 0 (for the Short Header), since we don't the client to omit it
|
||||
isPublicHeader := typeByte&0xc0 == 0
|
||||
|
||||
// In an IETF QUIC packet header
|
||||
// * either 0x80 is set (for the Long Header)
|
||||
// * or 0x8 is unset (for the Short Header)
|
||||
// In a gQUIC Public Header
|
||||
// * 0x80 is always unset and
|
||||
// * and 0x8 is always set (this is the Connection ID flag, which the client always sets)
|
||||
isPublicHeader := typeByte&0x88 == 0x8
|
||||
return parsePacketHeader(b, protocol.PerspectiveClient, isPublicHeader)
|
||||
}
|
||||
|
||||
|
|
51
vendor/github.com/lucas-clemente/quic-go/internal/wire/ietf_header.go
generated
vendored
51
vendor/github.com/lucas-clemente/quic-go/internal/wire/ietf_header.go
generated
vendored
|
@ -2,6 +2,7 @@ package wire
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
|
@ -31,15 +32,9 @@ func parseLongHeader(b *bytes.Reader, sentBy protocol.Perspective, typeByte byte
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pn, err := utils.BigEndian.ReadUint32(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h := &Header{
|
||||
ConnectionID: protocol.ConnectionID(connID),
|
||||
PacketNumber: protocol.PacketNumber(pn),
|
||||
PacketNumberLen: protocol.PacketNumberLen4,
|
||||
Version: protocol.VersionNumber(v),
|
||||
ConnectionID: protocol.ConnectionID(connID),
|
||||
Version: protocol.VersionNumber(v),
|
||||
}
|
||||
if v == 0 { // version negotiation packet
|
||||
if sentBy == protocol.PerspectiveClient {
|
||||
|
@ -60,6 +55,12 @@ func parseLongHeader(b *bytes.Reader, sentBy protocol.Perspective, typeByte byte
|
|||
return h, nil
|
||||
}
|
||||
h.IsLongHeader = true
|
||||
pn, err := utils.BigEndian.ReadUint32(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h.PacketNumber = protocol.PacketNumber(pn)
|
||||
h.PacketNumberLen = protocol.PacketNumberLen4
|
||||
h.Type = protocol.PacketType(typeByte & 0x7f)
|
||||
if sentBy == protocol.PerspectiveClient && (h.Type != protocol.PacketTypeInitial && h.Type != protocol.PacketTypeHandshake && h.Type != protocol.PacketType0RTT) {
|
||||
return nil, qerr.Error(qerr.InvalidPacketHeader, fmt.Sprintf("Received packet with invalid packet type: %d", h.Type))
|
||||
|
@ -71,26 +72,40 @@ func parseLongHeader(b *bytes.Reader, sentBy protocol.Perspective, typeByte byte
|
|||
}
|
||||
|
||||
func parseShortHeader(b *bytes.Reader, typeByte byte) (*Header, error) {
|
||||
hasConnID := typeByte&0x40 > 0
|
||||
omitConnID := typeByte&0x40 > 0
|
||||
var connID uint64
|
||||
if hasConnID {
|
||||
if !omitConnID {
|
||||
var err error
|
||||
connID, err = utils.BigEndian.ReadUint64(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
pnLen := 1 << ((typeByte & 0x3) - 1)
|
||||
// bit 4 must be set, bit 5 must be unset
|
||||
if typeByte&0x18 != 0x10 {
|
||||
return nil, errors.New("invalid bit 4 and 5")
|
||||
}
|
||||
var pnLen protocol.PacketNumberLen
|
||||
switch typeByte & 0x7 {
|
||||
case 0x0:
|
||||
pnLen = protocol.PacketNumberLen1
|
||||
case 0x1:
|
||||
pnLen = protocol.PacketNumberLen2
|
||||
case 0x2:
|
||||
pnLen = protocol.PacketNumberLen4
|
||||
default:
|
||||
return nil, errors.New("invalid short header type")
|
||||
}
|
||||
pn, err := utils.BigEndian.ReadUintN(b, uint8(pnLen))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Header{
|
||||
KeyPhase: int(typeByte&0x20) >> 5,
|
||||
OmitConnectionID: !hasConnID,
|
||||
OmitConnectionID: omitConnID,
|
||||
ConnectionID: protocol.ConnectionID(connID),
|
||||
PacketNumber: protocol.PacketNumber(pn),
|
||||
PacketNumberLen: protocol.PacketNumberLen(pnLen),
|
||||
PacketNumberLen: pnLen,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -112,17 +127,17 @@ func (h *Header) writeLongHeader(b *bytes.Buffer) error {
|
|||
}
|
||||
|
||||
func (h *Header) writeShortHeader(b *bytes.Buffer) error {
|
||||
typeByte := byte(h.KeyPhase << 5)
|
||||
if !h.OmitConnectionID {
|
||||
typeByte := byte(0x10)
|
||||
typeByte ^= byte(h.KeyPhase << 5)
|
||||
if h.OmitConnectionID {
|
||||
typeByte ^= 0x40
|
||||
}
|
||||
switch h.PacketNumberLen {
|
||||
case protocol.PacketNumberLen1:
|
||||
typeByte ^= 0x1
|
||||
case protocol.PacketNumberLen2:
|
||||
typeByte ^= 0x2
|
||||
typeByte ^= 0x1
|
||||
case protocol.PacketNumberLen4:
|
||||
typeByte ^= 0x3
|
||||
typeByte ^= 0x2
|
||||
default:
|
||||
return fmt.Errorf("invalid packet number length: %d", h.PacketNumberLen)
|
||||
}
|
||||
|
|
9
vendor/github.com/lucas-clemente/quic-go/internal/wire/public_header.go
generated
vendored
9
vendor/github.com/lucas-clemente/quic-go/internal/wire/public_header.go
generated
vendored
|
@ -134,10 +134,9 @@ func parsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective) (*Hea
|
|||
}
|
||||
}
|
||||
|
||||
// Contrary to what the gQUIC wire spec says, the 0x4 bit only indicates the presence of the diversification nonce for packets sent by the server.
|
||||
// It doesn't have any meaning when sent by the client.
|
||||
if packetSentBy == protocol.PerspectiveServer && publicFlagByte&0x04 > 0 {
|
||||
// TODO: remove the if once the Google servers send the correct value
|
||||
// assume that a packet doesn't contain a diversification nonce if the version flag or the reset flag is set, no matter what the public flag says
|
||||
// see https://github.com/lucas-clemente/quic-go/issues/232
|
||||
if !header.VersionFlag && !header.ResetFlag {
|
||||
header.DiversificationNonce = make([]byte, 32)
|
||||
if _, err := io.ReadFull(b, header.DiversificationNonce); err != nil {
|
||||
|
@ -148,7 +147,7 @@ func parsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective) (*Hea
|
|||
|
||||
// Version (optional)
|
||||
if !header.ResetFlag && header.VersionFlag {
|
||||
if packetSentBy == protocol.PerspectiveServer { // parse the version negotiaton packet
|
||||
if packetSentBy == protocol.PerspectiveServer { // parse the version negotiation packet
|
||||
if b.Len() == 0 {
|
||||
return nil, qerr.Error(qerr.InvalidVersionNegotiationPacket, "empty version list")
|
||||
}
|
||||
|
@ -236,7 +235,7 @@ func (h *Header) logPublicHeader() {
|
|||
}
|
||||
ver := "(unset)"
|
||||
if h.Version != 0 {
|
||||
ver = fmt.Sprintf("%s", h.Version)
|
||||
ver = h.Version.String()
|
||||
}
|
||||
utils.Debugf(" Public Header{ConnectionID: %s, PacketNumber: %#x, PacketNumberLen: %d, Version: %s, DiversificationNonce: %#v}", connID, h.PacketNumber, h.PacketNumberLen, ver, h.DiversificationNonce)
|
||||
}
|
||||
|
|
2
vendor/github.com/lucas-clemente/quic-go/internal/wire/stream_frame.go
generated
vendored
2
vendor/github.com/lucas-clemente/quic-go/internal/wire/stream_frame.go
generated
vendored
|
@ -56,7 +56,7 @@ func ParseStreamFrame(r *bytes.Reader, version protocol.VersionNumber) (*StreamF
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// shortcut to prevent the unneccessary allocation of dataLen bytes
|
||||
// shortcut to prevent the unnecessary allocation of dataLen bytes
|
||||
// if the dataLen is larger than the remaining length of the packet
|
||||
// reading the packet contents would result in EOF when attempting to READ
|
||||
if dataLen > uint64(r.Len()) {
|
||||
|
|
2
vendor/github.com/lucas-clemente/quic-go/internal/wire/stream_frame_legacy.go
generated
vendored
2
vendor/github.com/lucas-clemente/quic-go/internal/wire/stream_frame_legacy.go
generated
vendored
|
@ -52,7 +52,7 @@ func parseLegacyStreamFrame(r *bytes.Reader, _ protocol.VersionNumber) (*StreamF
|
|||
}
|
||||
}
|
||||
|
||||
// shortcut to prevent the unneccessary allocation of dataLen bytes
|
||||
// shortcut to prevent the unnecessary allocation of dataLen bytes
|
||||
// if the dataLen is larger than the remaining length of the packet
|
||||
// reading the packet contents would result in EOF when attempting to READ
|
||||
if int(dataLen) > r.Len() {
|
||||
|
|
39
vendor/github.com/lucas-clemente/quic-go/internal/wire/version_negotiation.go
generated
vendored
39
vendor/github.com/lucas-clemente/quic-go/internal/wire/version_negotiation.go
generated
vendored
|
@ -10,50 +10,37 @@ import (
|
|||
|
||||
// ComposeGQUICVersionNegotiation composes a Version Negotiation Packet for gQUIC
|
||||
func ComposeGQUICVersionNegotiation(connID protocol.ConnectionID, versions []protocol.VersionNumber) []byte {
|
||||
fullReply := &bytes.Buffer{}
|
||||
buf := &bytes.Buffer{}
|
||||
ph := Header{
|
||||
ConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
VersionFlag: true,
|
||||
IsVersionNegotiation: true,
|
||||
}
|
||||
if err := ph.writePublicHeader(fullReply, protocol.PerspectiveServer, protocol.VersionWhatever); err != nil {
|
||||
if err := ph.writePublicHeader(buf, protocol.PerspectiveServer, protocol.VersionWhatever); err != nil {
|
||||
utils.Errorf("error composing version negotiation packet: %s", err.Error())
|
||||
return nil
|
||||
}
|
||||
writeVersions(fullReply, versions)
|
||||
return fullReply.Bytes()
|
||||
for _, v := range versions {
|
||||
utils.BigEndian.WriteUint32(buf, uint32(v))
|
||||
}
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// ComposeVersionNegotiation composes a Version Negotiation according to the IETF draft
|
||||
func ComposeVersionNegotiation(
|
||||
connID protocol.ConnectionID,
|
||||
pn protocol.PacketNumber,
|
||||
versions []protocol.VersionNumber,
|
||||
) []byte {
|
||||
fullReply := &bytes.Buffer{}
|
||||
greasedVersions := protocol.GetGreasedVersions(versions)
|
||||
buf := bytes.NewBuffer(make([]byte, 0, 1+8+4+len(greasedVersions)*4))
|
||||
r := make([]byte, 1)
|
||||
_, _ = rand.Read(r) // ignore the error here. It is not critical to have perfect random here.
|
||||
h := Header{
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketType(r[0] | 0x80),
|
||||
ConnectionID: connID,
|
||||
PacketNumber: pn,
|
||||
Version: 0,
|
||||
IsVersionNegotiation: true,
|
||||
}
|
||||
if err := h.writeHeader(fullReply); err != nil {
|
||||
utils.Errorf("error composing version negotiation packet: %s", err.Error())
|
||||
return nil
|
||||
}
|
||||
writeVersions(fullReply, versions)
|
||||
return fullReply.Bytes()
|
||||
}
|
||||
|
||||
// writeVersions writes the versions for a Version Negotiation Packet.
|
||||
// It inserts one reserved version number at a random position.
|
||||
func writeVersions(buf *bytes.Buffer, supported []protocol.VersionNumber) {
|
||||
for _, v := range protocol.GetGreasedVersions(supported) {
|
||||
buf.WriteByte(r[0] | 0x80)
|
||||
utils.BigEndian.WriteUint64(buf, uint64(connID))
|
||||
utils.BigEndian.WriteUint32(buf, 0) // version 0
|
||||
for _, v := range greasedVersions {
|
||||
utils.BigEndian.WriteUint32(buf, uint32(v))
|
||||
}
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
|
4
vendor/github.com/lucas-clemente/quic-go/mint_utils.go
generated
vendored
4
vendor/github.com/lucas-clemente/quic-go/mint_utils.go
generated
vendored
|
@ -139,8 +139,8 @@ func unpackInitialPacket(aead crypto.AEAD, hdr *wire.Header, data []byte, versio
|
|||
// packUnencryptedPacket provides a low-overhead way to pack a packet.
|
||||
// It is supposed to be used in the early stages of the handshake, before a session (which owns a packetPacker) is available.
|
||||
func packUnencryptedPacket(aead crypto.AEAD, hdr *wire.Header, f wire.Frame, pers protocol.Perspective) ([]byte, error) {
|
||||
raw := getPacketBuffer()
|
||||
buffer := bytes.NewBuffer(raw)
|
||||
raw := *getPacketBuffer()
|
||||
buffer := bytes.NewBuffer(raw[:0])
|
||||
if err := hdr.Write(buffer, pers, hdr.Version); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
172
vendor/github.com/lucas-clemente/quic-go/packet_packer.go
generated
vendored
172
vendor/github.com/lucas-clemente/quic-go/packet_packer.go
generated
vendored
|
@ -4,11 +4,13 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"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/utils"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
)
|
||||
|
||||
|
@ -19,6 +21,16 @@ type packedPacket struct {
|
|||
encryptionLevel protocol.EncryptionLevel
|
||||
}
|
||||
|
||||
func (p *packedPacket) ToAckHandlerPacket() *ackhandler.Packet {
|
||||
return &ackhandler.Packet{
|
||||
PacketNumber: p.header.PacketNumber,
|
||||
PacketType: p.header.Type,
|
||||
Frames: p.frames,
|
||||
Length: protocol.ByteCount(len(p.raw)),
|
||||
EncryptionLevel: p.encryptionLevel,
|
||||
}
|
||||
}
|
||||
|
||||
type streamFrameSource interface {
|
||||
HasCryptoStreamData() bool
|
||||
PopCryptoStreamFrame(protocol.ByteCount) *wire.StreamFrame
|
||||
|
@ -32,6 +44,7 @@ type packetPacker struct {
|
|||
cryptoSetup handshake.CryptoSetup
|
||||
|
||||
packetNumberGenerator *packetNumberGenerator
|
||||
getPacketNumberLen func(protocol.PacketNumber) protocol.PacketNumberLen
|
||||
streams streamFrameSource
|
||||
|
||||
controlFrameMutex sync.Mutex
|
||||
|
@ -39,26 +52,43 @@ type packetPacker struct {
|
|||
|
||||
stopWaiting *wire.StopWaitingFrame
|
||||
ackFrame *wire.AckFrame
|
||||
leastUnacked protocol.PacketNumber
|
||||
omitConnectionID bool
|
||||
maxPacketSize protocol.ByteCount
|
||||
hasSentPacket bool // has the packetPacker already sent a packet
|
||||
numNonRetransmittableAcks int
|
||||
}
|
||||
|
||||
func newPacketPacker(connectionID protocol.ConnectionID,
|
||||
initialPacketNumber protocol.PacketNumber,
|
||||
getPacketNumberLen func(protocol.PacketNumber) protocol.PacketNumberLen,
|
||||
remoteAddr net.Addr, // only used for determining the max packet size
|
||||
cryptoSetup handshake.CryptoSetup,
|
||||
streamFramer streamFrameSource,
|
||||
perspective protocol.Perspective,
|
||||
version protocol.VersionNumber,
|
||||
) *packetPacker {
|
||||
maxPacketSize := protocol.ByteCount(protocol.MinInitialPacketSize)
|
||||
// If this is not a UDP address, we don't know anything about the MTU.
|
||||
// Use the minimum size of an Initial packet as the max packet size.
|
||||
if udpAddr, ok := remoteAddr.(*net.UDPAddr); ok {
|
||||
// If ip is not an IPv4 address, To4 returns nil.
|
||||
// Note that there might be some corner cases, where this is not correct.
|
||||
// See https://stackoverflow.com/questions/22751035/golang-distinguish-ipv4-ipv6.
|
||||
if udpAddr.IP.To4() == nil {
|
||||
maxPacketSize = protocol.MaxPacketSizeIPv6
|
||||
} else {
|
||||
maxPacketSize = protocol.MaxPacketSizeIPv4
|
||||
}
|
||||
}
|
||||
return &packetPacker{
|
||||
cryptoSetup: cryptoSetup,
|
||||
connectionID: connectionID,
|
||||
perspective: perspective,
|
||||
version: version,
|
||||
streams: streamFramer,
|
||||
getPacketNumberLen: getPacketNumberLen,
|
||||
packetNumberGenerator: newPacketNumberGenerator(initialPacketNumber, protocol.SkipPacketAveragePeriodLength),
|
||||
maxPacketSize: maxPacketSize,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,18 +129,124 @@ func (p *packetPacker) PackAckPacket() (*packedPacket, error) {
|
|||
}, err
|
||||
}
|
||||
|
||||
// PackHandshakeRetransmission retransmits a handshake packet, that was sent with less than forward-secure encryption
|
||||
func (p *packetPacker) PackHandshakeRetransmission(packet *ackhandler.Packet) (*packedPacket, error) {
|
||||
if packet.EncryptionLevel == protocol.EncryptionForwardSecure {
|
||||
return nil, errors.New("PacketPacker BUG: forward-secure encrypted handshake packets don't need special treatment")
|
||||
// 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 *packetPacker) 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()
|
||||
for len(controlFrames) > 0 || len(streamFrames) > 0 {
|
||||
var frames []wire.Frame
|
||||
var payloadLength protocol.ByteCount
|
||||
|
||||
header := p.getHeader(encLevel)
|
||||
headerLength, err := header.GetLength(p.perspective, p.version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLength
|
||||
|
||||
// for gQUIC: add a STOP_WAITING for *every* retransmission
|
||||
if p.version.UsesStopWaitingFrames() {
|
||||
if p.stopWaiting == nil {
|
||||
return nil, errors.New("PacketPacker BUG: Handshake retransmissions must contain a STOP_WAITING frame")
|
||||
}
|
||||
// create a new StopWaitingFrame, since we might need to send more than one packet as a retransmission
|
||||
swf := &wire.StopWaitingFrame{
|
||||
LeastUnacked: p.stopWaiting.LeastUnacked,
|
||||
PacketNumber: header.PacketNumber,
|
||||
PacketNumberLen: header.PacketNumberLen,
|
||||
}
|
||||
payloadLength += swf.Length(p.version)
|
||||
frames = append(frames, swf)
|
||||
}
|
||||
|
||||
for len(controlFrames) > 0 {
|
||||
frame := controlFrames[0]
|
||||
length := frame.Length(p.version)
|
||||
if payloadLength+length > maxSize {
|
||||
break
|
||||
}
|
||||
payloadLength += length
|
||||
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
|
||||
// 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() {
|
||||
maxSize++
|
||||
} else {
|
||||
maxSize += 2
|
||||
}
|
||||
for len(streamFrames) > 0 && payloadLength+protocol.MinStreamFrameSize < maxSize {
|
||||
// TODO: optimize by setting DataLenPresent = false on all but the last STREAM frame
|
||||
frame := streamFrames[0]
|
||||
frameToAdd := frame
|
||||
|
||||
sf, err := frame.MaybeSplitOffFrame(maxSize-payloadLength, p.version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if sf != nil {
|
||||
frameToAdd = sf
|
||||
} else {
|
||||
streamFrames = streamFrames[1:]
|
||||
}
|
||||
payloadLength += 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,
|
||||
})
|
||||
}
|
||||
p.stopWaiting = nil
|
||||
return packets, nil
|
||||
}
|
||||
|
||||
// packHandshakeRetransmission retransmits a handshake packet, that was sent with less than forward-secure encryption
|
||||
func (p *packetPacker) 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.UsesIETFFrameFormat() { // for gQUIC: pack a STOP_WAITING first
|
||||
if p.version.UsesStopWaitingFrames() { // for gQUIC: pack a STOP_WAITING first
|
||||
if p.stopWaiting == nil {
|
||||
return nil, errors.New("PacketPacker BUG: Handshake retransmissions must contain a STOP_WAITING frame")
|
||||
}
|
||||
|
@ -155,7 +291,7 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
|||
p.stopWaiting.PacketNumberLen = header.PacketNumberLen
|
||||
}
|
||||
|
||||
maxSize := protocol.MaxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLength
|
||||
maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLength
|
||||
payloadFrames, err := p.composeNextPacket(maxSize, p.canSendData(encLevel))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -204,7 +340,7 @@ func (p *packetPacker) packCryptoPacket() (*packedPacket, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
maxLen := protocol.MaxPacketSize - protocol.ByteCount(sealer.Overhead()) - protocol.NonForwardSecurePacketSizeReduction - headerLength
|
||||
maxLen := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - protocol.NonForwardSecurePacketSizeReduction - headerLength
|
||||
sf := p.streams.PopCryptoStreamFrame(maxLen)
|
||||
sf.DataLenPresent = false
|
||||
frames := []wire.Frame{sf}
|
||||
|
@ -261,7 +397,7 @@ 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
|
||||
// however, for the last StreamFrame in the packet, we can omit the DataLen, thus yielding a packet of exactly the correct size
|
||||
// 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() {
|
||||
|
@ -296,7 +432,7 @@ func (p *packetPacker) QueueControlFrame(frame wire.Frame) {
|
|||
|
||||
func (p *packetPacker) getHeader(encLevel protocol.EncryptionLevel) *wire.Header {
|
||||
pnum := p.packetNumberGenerator.Peek()
|
||||
packetNumberLen := protocol.GetPacketNumberLengthForHeader(pnum, p.leastUnacked)
|
||||
packetNumberLen := p.getPacketNumberLen(pnum)
|
||||
|
||||
header := &wire.Header{
|
||||
ConnectionID: p.connectionID,
|
||||
|
@ -338,8 +474,8 @@ func (p *packetPacker) writeAndSealPacket(
|
|||
payloadFrames []wire.Frame,
|
||||
sealer handshake.Sealer,
|
||||
) ([]byte, error) {
|
||||
raw := getPacketBuffer()
|
||||
buffer := bytes.NewBuffer(raw)
|
||||
raw := *getPacketBuffer()
|
||||
buffer := bytes.NewBuffer(raw[:0])
|
||||
|
||||
if err := header.Write(buffer, p.perspective, p.version); err != nil {
|
||||
return nil, err
|
||||
|
@ -367,8 +503,8 @@ func (p *packetPacker) writeAndSealPacket(
|
|||
}
|
||||
}
|
||||
|
||||
if size := protocol.ByteCount(buffer.Len() + sealer.Overhead()); size > protocol.MaxPacketSize {
|
||||
return nil, fmt.Errorf("PacketPacker BUG: packet too large (%d bytes, allowed %d bytes)", size, protocol.MaxPacketSize)
|
||||
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()]
|
||||
|
@ -390,10 +526,10 @@ func (p *packetPacker) canSendData(encLevel protocol.EncryptionLevel) bool {
|
|||
return encLevel == protocol.EncryptionForwardSecure
|
||||
}
|
||||
|
||||
func (p *packetPacker) SetLeastUnacked(leastUnacked protocol.PacketNumber) {
|
||||
p.leastUnacked = leastUnacked
|
||||
}
|
||||
|
||||
func (p *packetPacker) SetOmitConnectionID() {
|
||||
p.omitConnectionID = true
|
||||
}
|
||||
|
||||
func (p *packetPacker) SetMaxPacketSize(size protocol.ByteCount) {
|
||||
p.maxPacketSize = utils.MinByteCount(p.maxPacketSize, size)
|
||||
}
|
||||
|
|
5
vendor/github.com/lucas-clemente/quic-go/packet_unpacker.go
generated
vendored
5
vendor/github.com/lucas-clemente/quic-go/packet_unpacker.go
generated
vendored
|
@ -24,8 +24,9 @@ type packetUnpacker struct {
|
|||
}
|
||||
|
||||
func (u *packetUnpacker) Unpack(headerBinary []byte, hdr *wire.Header, data []byte) (*unpackedPacket, error) {
|
||||
buf := getPacketBuffer()
|
||||
defer putPacketBuffer(buf)
|
||||
buf := *getPacketBuffer()
|
||||
buf = buf[:0]
|
||||
defer putPacketBuffer(&buf)
|
||||
decrypted, encryptionLevel, err := u.aead.Open(buf, data, hdr.PacketNumber, headerBinary)
|
||||
if err != nil {
|
||||
// Wrap err in quicError so that public reset is sent by session
|
||||
|
|
1
vendor/github.com/lucas-clemente/quic-go/qerr/quic_error.go
generated
vendored
1
vendor/github.com/lucas-clemente/quic-go/qerr/quic_error.go
generated
vendored
|
@ -31,6 +31,7 @@ func (e *QuicError) Error() string {
|
|||
return fmt.Sprintf("%s: %s", e.ErrorCode.String(), e.ErrorMessage)
|
||||
}
|
||||
|
||||
// Timeout says if this error is a timeout.
|
||||
func (e *QuicError) Timeout() bool {
|
||||
switch e.ErrorCode {
|
||||
case NetworkIdleTimeout,
|
||||
|
|
2
vendor/github.com/lucas-clemente/quic-go/receive_stream.go
generated
vendored
2
vendor/github.com/lucas-clemente/quic-go/receive_stream.go
generated
vendored
|
@ -124,7 +124,7 @@ func (s *receiveStream) Read(p []byte) (int, error) {
|
|||
} else {
|
||||
select {
|
||||
case <-s.readChan:
|
||||
case <-time.After(deadline.Sub(time.Now())):
|
||||
case <-time.After(time.Until(deadline)):
|
||||
}
|
||||
}
|
||||
s.mutex.Lock()
|
||||
|
|
2
vendor/github.com/lucas-clemente/quic-go/send_stream.go
generated
vendored
2
vendor/github.com/lucas-clemente/quic-go/send_stream.go
generated
vendored
|
@ -116,7 +116,7 @@ func (s *sendStream) Write(p []byte) (int, error) {
|
|||
} else {
|
||||
select {
|
||||
case <-s.writeChan:
|
||||
case <-time.After(deadline.Sub(time.Now())):
|
||||
case <-time.After(time.Until(deadline)):
|
||||
}
|
||||
}
|
||||
s.mutex.Lock()
|
||||
|
|
31
vendor/github.com/lucas-clemente/quic-go/server.go
generated
vendored
31
vendor/github.com/lucas-clemente/quic-go/server.go
generated
vendored
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
@ -85,9 +86,12 @@ func Listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (Listener,
|
|||
}
|
||||
config = populateServerConfig(config)
|
||||
|
||||
// check if any of the supported versions supports TLS
|
||||
var supportsTLS bool
|
||||
for _, v := range config.Versions {
|
||||
if !protocol.IsValidVersion(v) {
|
||||
return nil, fmt.Errorf("%s is not a valid QUIC version", v)
|
||||
}
|
||||
// check if any of the supported versions supports TLS
|
||||
if v.UsesTLS() {
|
||||
supportsTLS = true
|
||||
break
|
||||
|
@ -136,10 +140,11 @@ func (s *server) setupTLS() error {
|
|||
case tlsSession := <-sessionChan:
|
||||
connID := tlsSession.connID
|
||||
sess := tlsSession.sess
|
||||
if _, ok := s.sessions[connID]; ok { // drop this session if it already exists
|
||||
return
|
||||
}
|
||||
s.sessionsMutex.Lock()
|
||||
if _, ok := s.sessions[connID]; ok { // drop this session if it already exists
|
||||
s.sessionsMutex.Unlock()
|
||||
continue
|
||||
}
|
||||
s.sessions[connID] = sess
|
||||
s.sessionsMutex.Unlock()
|
||||
s.runHandshakeAndSession(sess, connID)
|
||||
|
@ -198,6 +203,18 @@ func populateServerConfig(config *Config) *Config {
|
|||
if maxReceiveConnectionFlowControlWindow == 0 {
|
||||
maxReceiveConnectionFlowControlWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindowServer
|
||||
}
|
||||
maxIncomingStreams := config.MaxIncomingStreams
|
||||
if maxIncomingStreams == 0 {
|
||||
maxIncomingStreams = protocol.DefaultMaxIncomingStreams
|
||||
} else if maxIncomingStreams < 0 {
|
||||
maxIncomingStreams = 0
|
||||
}
|
||||
maxIncomingUniStreams := config.MaxIncomingUniStreams
|
||||
if maxIncomingUniStreams == 0 {
|
||||
maxIncomingUniStreams = protocol.DefaultMaxIncomingUniStreams
|
||||
} else if maxIncomingUniStreams < 0 {
|
||||
maxIncomingUniStreams = 0
|
||||
}
|
||||
|
||||
return &Config{
|
||||
Versions: versions,
|
||||
|
@ -207,13 +224,15 @@ func populateServerConfig(config *Config) *Config {
|
|||
KeepAlive: config.KeepAlive,
|
||||
MaxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow,
|
||||
MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow,
|
||||
MaxIncomingStreams: maxIncomingStreams,
|
||||
MaxIncomingUniStreams: maxIncomingUniStreams,
|
||||
}
|
||||
}
|
||||
|
||||
// serve listens on an existing PacketConn
|
||||
func (s *server) serve() {
|
||||
for {
|
||||
data := getPacketBuffer()
|
||||
data := *getPacketBuffer()
|
||||
data = data[:protocol.MaxReceivePacketSize]
|
||||
// The packet size should not exceed protocol.MaxReceivePacketSize bytes
|
||||
// If it does, we only read a truncated packet, which will then end up undecryptable
|
||||
|
@ -309,7 +328,7 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
|||
var pr *wire.PublicReset
|
||||
pr, err = wire.ParsePublicReset(r)
|
||||
if err != nil {
|
||||
utils.Infof("Received a Public Reset for connection %x. An error occurred parsing the packet.")
|
||||
utils.Infof("Received a Public Reset for connection %x. An error occurred parsing the packet.", hdr.ConnectionID)
|
||||
} else {
|
||||
utils.Infof("Received a Public Reset for connection %x, rejected packet number: 0x%x.", hdr.ConnectionID, pr.RejectedPacketNumber)
|
||||
}
|
||||
|
|
12
vendor/github.com/lucas-clemente/quic-go/server_tls.go
generated
vendored
12
vendor/github.com/lucas-clemente/quic-go/server_tls.go
generated
vendored
|
@ -36,7 +36,6 @@ type serverTLS struct {
|
|||
config *Config
|
||||
supportedVersions []protocol.VersionNumber
|
||||
mintConf *mint.Config
|
||||
cookieProtector mint.CookieProtector
|
||||
params *handshake.TransportParameters
|
||||
newMintConn func(*handshake.CryptoStreamConn, protocol.VersionNumber) (handshake.MintTLS, <-chan handshake.TransportParameters, error)
|
||||
|
||||
|
@ -72,9 +71,8 @@ func newServerTLS(
|
|||
StreamFlowControlWindow: protocol.ReceiveStreamFlowControlWindow,
|
||||
ConnectionFlowControlWindow: protocol.ReceiveConnectionFlowControlWindow,
|
||||
IdleTimeout: config.IdleTimeout,
|
||||
// TODO(#523): make these values configurable
|
||||
MaxBidiStreamID: protocol.MaxBidiStreamID(protocol.MaxIncomingStreams, protocol.PerspectiveServer),
|
||||
MaxUniStreamID: protocol.MaxUniStreamID(protocol.MaxIncomingStreams, protocol.PerspectiveServer),
|
||||
MaxBidiStreams: uint16(config.MaxIncomingStreams),
|
||||
MaxUniStreams: uint16(config.MaxIncomingUniStreams),
|
||||
},
|
||||
}
|
||||
s.newMintConn = s.newMintConnImpl
|
||||
|
@ -85,7 +83,7 @@ func (s *serverTLS) HandleInitial(remoteAddr net.Addr, hdr *wire.Header, data []
|
|||
utils.Debugf("Received a Packet. Handling it statelessly.")
|
||||
sess, err := s.handleInitialImpl(remoteAddr, hdr, data)
|
||||
if err != nil {
|
||||
utils.Errorf("Error occured handling initial packet: %s", err)
|
||||
utils.Errorf("Error occurred handling initial packet: %s", err)
|
||||
return
|
||||
}
|
||||
if sess == nil { // a stateless reset was done
|
||||
|
@ -132,7 +130,7 @@ func (s *serverTLS) handleInitialImpl(remoteAddr net.Addr, hdr *wire.Header, dat
|
|||
// check version, if not matching send VNP
|
||||
if !protocol.IsSupportedVersion(s.supportedVersions, hdr.Version) {
|
||||
utils.Debugf("Client offered version %s, sending VersionNegotiationPacket", hdr.Version)
|
||||
_, err := s.conn.WriteTo(wire.ComposeVersionNegotiation(hdr.ConnectionID, hdr.PacketNumber, s.supportedVersions), remoteAddr)
|
||||
_, err := s.conn.WriteTo(wire.ComposeVersionNegotiation(hdr.ConnectionID, s.supportedVersions), remoteAddr)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -149,7 +147,7 @@ func (s *serverTLS) handleInitialImpl(remoteAddr net.Addr, hdr *wire.Header, dat
|
|||
sess, err := s.handleUnpackedInitial(remoteAddr, hdr, frame, aead)
|
||||
if err != nil {
|
||||
if ccerr := s.sendConnectionClose(remoteAddr, hdr, aead, err); ccerr != nil {
|
||||
utils.Debugf("Error sending CONNECTION_CLOSE: ", ccerr)
|
||||
utils.Debugf("Error sending CONNECTION_CLOSE: %s", ccerr)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
|
239
vendor/github.com/lucas-clemente/quic-go/session.go
generated
vendored
239
vendor/github.com/lucas-clemente/quic-go/session.go
generated
vendored
|
@ -33,8 +33,11 @@ type streamManager interface {
|
|||
GetOrOpenSendStream(protocol.StreamID) (sendStreamI, error)
|
||||
GetOrOpenReceiveStream(protocol.StreamID) (receiveStreamI, error)
|
||||
OpenStream() (Stream, error)
|
||||
OpenUniStream() (SendStream, error)
|
||||
OpenStreamSync() (Stream, error)
|
||||
OpenUniStreamSync() (SendStream, error)
|
||||
AcceptStream() (Stream, error)
|
||||
AcceptUniStream() (ReceiveStream, error)
|
||||
DeleteStream(protocol.StreamID) error
|
||||
UpdateLimits(*handshake.TransportParameters)
|
||||
HandleMaxStreamIDFrame(*wire.MaxStreamIDFrame) error
|
||||
|
@ -108,7 +111,9 @@ type session struct {
|
|||
handshakeChan chan error
|
||||
handshakeComplete bool
|
||||
|
||||
lastRcvdPacketNumber protocol.PacketNumber
|
||||
receivedFirstPacket bool // since packet numbers start at 0, we can't use largestRcvdPacketNumber != 0 for this
|
||||
receivedFirstForwardSecurePacket bool
|
||||
lastRcvdPacketNumber protocol.PacketNumber
|
||||
// Used to calculate the next packet number from the truncated wire
|
||||
// representation, and sent back in public reset packets
|
||||
largestRcvdPacketNumber protocol.PacketNumber
|
||||
|
@ -153,7 +158,7 @@ func newSession(
|
|||
transportParams := &handshake.TransportParameters{
|
||||
StreamFlowControlWindow: protocol.ReceiveStreamFlowControlWindow,
|
||||
ConnectionFlowControlWindow: protocol.ReceiveConnectionFlowControlWindow,
|
||||
MaxStreams: protocol.MaxIncomingStreams,
|
||||
MaxStreams: uint32(s.config.MaxIncomingStreams),
|
||||
IdleTimeout: s.config.IdleTimeout,
|
||||
}
|
||||
cs, err := newCryptoSetup(
|
||||
|
@ -184,7 +189,7 @@ var newClientSession = func(
|
|||
tlsConf *tls.Config,
|
||||
config *Config,
|
||||
initialVersion protocol.VersionNumber,
|
||||
negotiatedVersions []protocol.VersionNumber, // needed for validation of the GQUIC version negotiaton
|
||||
negotiatedVersions []protocol.VersionNumber, // needed for validation of the GQUIC version negotiation
|
||||
) (packetHandler, error) {
|
||||
paramsChan := make(chan handshake.TransportParameters)
|
||||
handshakeEvent := make(chan struct{}, 1)
|
||||
|
@ -201,7 +206,7 @@ var newClientSession = func(
|
|||
transportParams := &handshake.TransportParameters{
|
||||
StreamFlowControlWindow: protocol.ReceiveStreamFlowControlWindow,
|
||||
ConnectionFlowControlWindow: protocol.ReceiveConnectionFlowControlWindow,
|
||||
MaxStreams: protocol.MaxIncomingStreams,
|
||||
MaxStreams: uint32(s.config.MaxIncomingStreams),
|
||||
IdleTimeout: s.config.IdleTimeout,
|
||||
OmitConnectionID: s.config.RequestConnectionIDOmission,
|
||||
}
|
||||
|
@ -323,16 +328,18 @@ func (s *session) postSetup(initialPacketNumber protocol.PacketNumber) error {
|
|||
s.sessionCreationTime = now
|
||||
|
||||
s.sentPacketHandler = ackhandler.NewSentPacketHandler(s.rttStats)
|
||||
s.receivedPacketHandler = ackhandler.NewReceivedPacketHandler(s.version)
|
||||
s.receivedPacketHandler = ackhandler.NewReceivedPacketHandler(s.rttStats, s.version)
|
||||
|
||||
if s.version.UsesTLS() {
|
||||
s.streamsMap = newStreamsMap(s, s.newFlowController, s.perspective, s.version)
|
||||
s.streamsMap = newStreamsMap(s, s.newFlowController, s.config.MaxIncomingStreams, s.config.MaxIncomingUniStreams, s.perspective, s.version)
|
||||
} else {
|
||||
s.streamsMap = newStreamsMapLegacy(s.newStream, s.perspective)
|
||||
s.streamsMap = newStreamsMapLegacy(s.newStream, s.config.MaxIncomingStreams, s.perspective)
|
||||
}
|
||||
s.streamFramer = newStreamFramer(s.cryptoStream, s.streamsMap, s.version)
|
||||
s.packer = newPacketPacker(s.connectionID,
|
||||
initialPacketNumber,
|
||||
s.sentPacketHandler.GetPacketNumberLen,
|
||||
s.RemoteAddr(),
|
||||
s.cryptoSetup,
|
||||
s.streamFramer,
|
||||
s.perspective,
|
||||
|
@ -390,14 +397,13 @@ runLoop:
|
|||
}
|
||||
// This is a bit unclean, but works properly, since the packet always
|
||||
// begins with the public header and we never copy it.
|
||||
putPacketBuffer(p.header.Raw)
|
||||
putPacketBuffer(&p.header.Raw)
|
||||
case p := <-s.paramsChan:
|
||||
s.processTransportParameters(&p)
|
||||
case _, ok := <-handshakeEvent:
|
||||
if !ok { // the aeadChanged chan was closed. This means that the handshake is completed.
|
||||
s.handshakeComplete = true
|
||||
handshakeEvent = nil // prevent this case from ever being selected again
|
||||
s.sentPacketHandler.SetHandshakeComplete()
|
||||
if !s.version.UsesTLS() && s.perspective == protocol.PerspectiveClient {
|
||||
// In gQUIC, there's no equivalent to the Finished message in TLS
|
||||
// The server knows that the handshake is complete when it receives the first forward-secure packet sent by the client.
|
||||
|
@ -412,9 +418,11 @@ runLoop:
|
|||
|
||||
now := time.Now()
|
||||
if timeout := s.sentPacketHandler.GetAlarmTimeout(); !timeout.IsZero() && timeout.Before(now) {
|
||||
// This could cause packets to be retransmitted, so check it before trying
|
||||
// to send packets.
|
||||
s.sentPacketHandler.OnAlarm()
|
||||
// This could cause packets to be retransmitted.
|
||||
// Check it before trying to send packets.
|
||||
if err := s.sentPacketHandler.OnAlarm(); err != nil {
|
||||
s.closeLocal(err)
|
||||
}
|
||||
}
|
||||
|
||||
var pacingDeadline time.Time
|
||||
|
@ -506,6 +514,7 @@ func (s *session) handlePacketImpl(p *receivedPacket) error {
|
|||
p.rcvTime = time.Now()
|
||||
}
|
||||
|
||||
s.receivedFirstPacket = true
|
||||
s.lastNetworkActivityTime = p.rcvTime
|
||||
s.keepAlivePingSent = false
|
||||
hdr := p.header
|
||||
|
@ -532,13 +541,26 @@ func (s *session) handlePacketImpl(p *receivedPacket) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// In TLS 1.3, the client considers the handshake complete as soon as
|
||||
// it received the server's Finished message and sent its Finished.
|
||||
// We have to wait for the first forward-secure packet from the server before
|
||||
// deleting all handshake packets from the history.
|
||||
if !s.receivedFirstForwardSecurePacket && packet.encryptionLevel == protocol.EncryptionForwardSecure {
|
||||
s.receivedFirstForwardSecurePacket = true
|
||||
s.sentPacketHandler.SetHandshakeComplete()
|
||||
}
|
||||
|
||||
s.lastRcvdPacketNumber = hdr.PacketNumber
|
||||
// Only do this after decrypting, so we are sure the packet is not attacker-controlled
|
||||
s.largestRcvdPacketNumber = utils.MaxPacketNumber(s.largestRcvdPacketNumber, hdr.PacketNumber)
|
||||
|
||||
isRetransmittable := ackhandler.HasRetransmittableFrames(packet.frames)
|
||||
if err = s.receivedPacketHandler.ReceivedPacket(hdr.PacketNumber, p.rcvTime, isRetransmittable); err != nil {
|
||||
return err
|
||||
// If this is a Retry packet, there's no need to send an ACK.
|
||||
// The session will be closed and recreated as soon as the crypto setup processed the HRR.
|
||||
if hdr.Type != protocol.PacketTypeRetry {
|
||||
isRetransmittable := ackhandler.HasRetransmittableFrames(packet.frames)
|
||||
if err := s.receivedPacketHandler.ReceivedPacket(hdr.PacketNumber, p.rcvTime, isRetransmittable); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return s.handleFrames(packet.frames, packet.encryptionLevel)
|
||||
|
@ -577,12 +599,7 @@ func (s *session) handleFrames(fs []wire.Frame, encLevel protocol.EncryptionLeve
|
|||
}
|
||||
|
||||
if err != nil {
|
||||
switch err {
|
||||
case ackhandler.ErrDuplicateOrOutOfOrderAck:
|
||||
// Can happen e.g. when packets thought missing arrive late
|
||||
default:
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -744,6 +761,9 @@ func (s *session) processTransportParameters(params *handshake.TransportParamete
|
|||
if params.OmitConnectionID {
|
||||
s.packer.SetOmitConnectionID()
|
||||
}
|
||||
if params.MaxPacketSize != 0 {
|
||||
s.packer.SetMaxPacketSize(params.MaxPacketSize)
|
||||
}
|
||||
s.connFlowController.UpdateSendWindow(params.ConnectionFlowControlWindow)
|
||||
// the crypto stream is the only open stream at this moment
|
||||
// so we don't need to update stream flow control windows
|
||||
|
@ -751,23 +771,56 @@ func (s *session) processTransportParameters(params *handshake.TransportParamete
|
|||
|
||||
func (s *session) sendPackets() error {
|
||||
s.pacingDeadline = time.Time{}
|
||||
if !s.sentPacketHandler.SendingAllowed() { // if congestion limited, at least try sending an ACK frame
|
||||
return s.maybeSendAckOnlyPacket()
|
||||
|
||||
sendMode := s.sentPacketHandler.SendMode()
|
||||
if sendMode == ackhandler.SendNone { // shortcut: return immediately if there's nothing to send
|
||||
return nil
|
||||
}
|
||||
|
||||
numPackets := s.sentPacketHandler.ShouldSendNumPackets()
|
||||
for i := 0; i < numPackets; i++ {
|
||||
sentPacket, err := s.sendPacket()
|
||||
if err != nil {
|
||||
return err
|
||||
var numPacketsSent int
|
||||
sendLoop:
|
||||
for {
|
||||
switch sendMode {
|
||||
case ackhandler.SendNone:
|
||||
break sendLoop
|
||||
case ackhandler.SendAck:
|
||||
// We can at most send a single ACK only packet.
|
||||
// There will only be a new ACK after receiving new packets.
|
||||
// SendAck is only returned when we're congestion limited, so we don't need to set the pacingt timer.
|
||||
return s.maybeSendAckOnlyPacket()
|
||||
case ackhandler.SendRetransmission:
|
||||
sentPacket, err := s.maybeSendRetransmission()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sentPacket {
|
||||
numPacketsSent++
|
||||
// This can happen if a retransmission queued, but it wasn't necessary to send it.
|
||||
// e.g. when an Initial is queued, but we already received a packet from the server.
|
||||
}
|
||||
case ackhandler.SendAny:
|
||||
sentPacket, err := s.sendPacket()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !sentPacket {
|
||||
break sendLoop
|
||||
}
|
||||
numPacketsSent++
|
||||
default:
|
||||
return fmt.Errorf("BUG: invalid send mode %d", sendMode)
|
||||
}
|
||||
// If no packet was sent, or we're congestion limit, we're done here.
|
||||
if !sentPacket || !s.sentPacketHandler.SendingAllowed() {
|
||||
return nil
|
||||
if numPacketsSent >= numPackets {
|
||||
break
|
||||
}
|
||||
sendMode = s.sentPacketHandler.SendMode()
|
||||
}
|
||||
// Only start the pacing timer if we sent as many packets as we were allowed.
|
||||
// There will probably be more to send when calling sendPacket again.
|
||||
s.pacingDeadline = s.sentPacketHandler.TimeUntilSend()
|
||||
if numPacketsSent == numPackets {
|
||||
s.pacingDeadline = s.sentPacketHandler.TimeUntilSend()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -778,7 +831,7 @@ func (s *session) maybeSendAckOnlyPacket() error {
|
|||
}
|
||||
s.packer.QueueControlFrame(ack)
|
||||
|
||||
if !s.version.UsesIETFFrameFormat() { // for gQUIC, maybe add a STOP_WAITING
|
||||
if s.version.UsesStopWaitingFrames() { // for gQUIC, maybe add a STOP_WAITING
|
||||
if swf := s.sentPacketHandler.GetStopWaitingFrame(false); swf != nil {
|
||||
s.packer.QueueControlFrame(swf)
|
||||
}
|
||||
|
@ -787,12 +840,57 @@ func (s *session) maybeSendAckOnlyPacket() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.sentPacketHandler.SentPacket(packet.ToAckHandlerPacket())
|
||||
return s.sendPackedPacket(packet)
|
||||
}
|
||||
|
||||
func (s *session) sendPacket() (bool, error) {
|
||||
s.packer.SetLeastUnacked(s.sentPacketHandler.GetLeastUnacked())
|
||||
// maybeSendRetransmission sends retransmissions for at most one packet.
|
||||
// It takes care that Initials aren't retransmitted, if a packet from the server was already received.
|
||||
func (s *session) maybeSendRetransmission() (bool, error) {
|
||||
var retransmitPacket *ackhandler.Packet
|
||||
for {
|
||||
retransmitPacket = s.sentPacketHandler.DequeuePacketForRetransmission()
|
||||
if retransmitPacket == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Don't retransmit Initial packets if we already received a response.
|
||||
// An Initial might have been retransmitted multiple times before we receive a response.
|
||||
// As soon as we receive one response, we don't need to send any more Initials.
|
||||
if s.receivedFirstPacket && retransmitPacket.PacketType == protocol.PacketTypeInitial {
|
||||
utils.Debugf("Skipping retransmission of packet %d. Already received a response to an Initial.", retransmitPacket.PacketNumber)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if retransmitPacket.EncryptionLevel != protocol.EncryptionForwardSecure {
|
||||
utils.Debugf("\tDequeueing handshake retransmission for packet 0x%x", retransmitPacket.PacketNumber)
|
||||
} else {
|
||||
utils.Debugf("\tDequeueing retransmission for packet 0x%x", retransmitPacket.PacketNumber)
|
||||
}
|
||||
|
||||
if s.version.UsesStopWaitingFrames() {
|
||||
s.packer.QueueControlFrame(s.sentPacketHandler.GetStopWaitingFrame(true))
|
||||
}
|
||||
packets, err := s.packer.PackRetransmission(retransmitPacket)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
ackhandlerPackets := make([]*ackhandler.Packet, len(packets))
|
||||
for i, packet := range packets {
|
||||
ackhandlerPackets[i] = packet.ToAckHandlerPacket()
|
||||
}
|
||||
s.sentPacketHandler.SentPacketsAsRetransmission(ackhandlerPackets, retransmitPacket.PacketNumber)
|
||||
for _, packet := range packets {
|
||||
if err := s.sendPackedPacket(packet); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *session) sendPacket() (bool, error) {
|
||||
if offset := s.connFlowController.GetWindowUpdate(); offset != 0 {
|
||||
s.packer.QueueControlFrame(&wire.MaxDataFrame{ByteOffset: offset})
|
||||
}
|
||||
|
@ -801,58 +899,20 @@ func (s *session) sendPacket() (bool, error) {
|
|||
}
|
||||
s.windowUpdateQueue.QueueAll()
|
||||
|
||||
ack := s.receivedPacketHandler.GetAckFrame()
|
||||
if ack != nil {
|
||||
if ack := s.receivedPacketHandler.GetAckFrame(); ack != nil {
|
||||
s.packer.QueueControlFrame(ack)
|
||||
}
|
||||
|
||||
// check for retransmissions first
|
||||
for {
|
||||
retransmitPacket := s.sentPacketHandler.DequeuePacketForRetransmission()
|
||||
if retransmitPacket == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// retransmit handshake packets
|
||||
if retransmitPacket.EncryptionLevel != protocol.EncryptionForwardSecure {
|
||||
utils.Debugf("\tDequeueing handshake retransmission for packet 0x%x", retransmitPacket.PacketNumber)
|
||||
if !s.version.UsesIETFFrameFormat() {
|
||||
s.packer.QueueControlFrame(s.sentPacketHandler.GetStopWaitingFrame(true))
|
||||
}
|
||||
packet, err := s.packer.PackHandshakeRetransmission(retransmitPacket)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := s.sendPackedPacket(packet); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// queue all retransmittable frames sent in forward-secure packets
|
||||
utils.Debugf("\tDequeueing retransmission for packet 0x%x", retransmitPacket.PacketNumber)
|
||||
// resend the frames that were in the packet
|
||||
for _, frame := range retransmitPacket.GetFramesForRetransmission() {
|
||||
// TODO: only retransmit WINDOW_UPDATEs if they actually enlarge the window
|
||||
switch f := frame.(type) {
|
||||
case *wire.StreamFrame:
|
||||
s.streamFramer.AddFrameForRetransmission(f)
|
||||
default:
|
||||
s.packer.QueueControlFrame(frame)
|
||||
if s.version.UsesStopWaitingFrames() {
|
||||
if swf := s.sentPacketHandler.GetStopWaitingFrame(false); swf != nil {
|
||||
s.packer.QueueControlFrame(swf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hasRetransmission := s.streamFramer.HasFramesForRetransmission()
|
||||
if !s.version.UsesIETFFrameFormat() && (ack != nil || hasRetransmission) {
|
||||
if swf := s.sentPacketHandler.GetStopWaitingFrame(hasRetransmission); swf != nil {
|
||||
s.packer.QueueControlFrame(swf)
|
||||
}
|
||||
}
|
||||
packet, err := s.packer.PackPacket()
|
||||
if err != nil || packet == nil {
|
||||
return false, err
|
||||
}
|
||||
s.sentPacketHandler.SentPacket(packet.ToAckHandlerPacket())
|
||||
if err := s.sendPackedPacket(packet); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -860,22 +920,12 @@ func (s *session) sendPacket() (bool, error) {
|
|||
}
|
||||
|
||||
func (s *session) sendPackedPacket(packet *packedPacket) error {
|
||||
defer putPacketBuffer(packet.raw)
|
||||
err := s.sentPacketHandler.SentPacket(&ackhandler.Packet{
|
||||
PacketNumber: packet.header.PacketNumber,
|
||||
Frames: packet.frames,
|
||||
Length: protocol.ByteCount(len(packet.raw)),
|
||||
EncryptionLevel: packet.encryptionLevel,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer putPacketBuffer(&packet.raw)
|
||||
s.logPacket(packet)
|
||||
return s.conn.Write(packet.raw)
|
||||
}
|
||||
|
||||
func (s *session) sendConnectionClose(quicErr *qerr.QuicError) error {
|
||||
s.packer.SetLeastUnacked(s.sentPacketHandler.GetLeastUnacked())
|
||||
packet, err := s.packer.PackConnectionClose(&wire.ConnectionCloseFrame{
|
||||
ErrorCode: quicErr.ErrorCode,
|
||||
ReasonPhrase: quicErr.ErrorMessage,
|
||||
|
@ -919,6 +969,10 @@ func (s *session) AcceptStream() (Stream, error) {
|
|||
return s.streamsMap.AcceptStream()
|
||||
}
|
||||
|
||||
func (s *session) AcceptUniStream() (ReceiveStream, error) {
|
||||
return s.streamsMap.AcceptUniStream()
|
||||
}
|
||||
|
||||
// OpenStream opens a stream
|
||||
func (s *session) OpenStream() (Stream, error) {
|
||||
return s.streamsMap.OpenStream()
|
||||
|
@ -928,6 +982,14 @@ func (s *session) OpenStreamSync() (Stream, error) {
|
|||
return s.streamsMap.OpenStreamSync()
|
||||
}
|
||||
|
||||
func (s *session) OpenUniStream() (SendStream, error) {
|
||||
return s.streamsMap.OpenUniStream()
|
||||
}
|
||||
|
||||
func (s *session) OpenUniStreamSync() (SendStream, error) {
|
||||
return s.streamsMap.OpenUniStreamSync()
|
||||
}
|
||||
|
||||
func (s *session) newStream(id protocol.StreamID) streamI {
|
||||
flowController := s.newFlowController(id)
|
||||
return newStream(id, s, flowController, s.version)
|
||||
|
@ -1026,7 +1088,6 @@ func (s *session) LocalAddr() net.Addr {
|
|||
return s.conn.LocalAddr()
|
||||
}
|
||||
|
||||
// RemoteAddr returns the net.Addr of the client
|
||||
func (s *session) RemoteAddr() net.Addr {
|
||||
return s.conn.RemoteAddr()
|
||||
}
|
||||
|
|
44
vendor/github.com/lucas-clemente/quic-go/stream_framer.go
generated
vendored
44
vendor/github.com/lucas-clemente/quic-go/stream_framer.go
generated
vendored
|
@ -12,8 +12,6 @@ type streamFramer struct {
|
|||
cryptoStream cryptoStreamI
|
||||
version protocol.VersionNumber
|
||||
|
||||
retransmissionQueue []*wire.StreamFrame
|
||||
|
||||
streamQueueMutex sync.Mutex
|
||||
activeStreams map[protocol.StreamID]struct{}
|
||||
streamQueue []protocol.StreamID
|
||||
|
@ -33,10 +31,6 @@ func newStreamFramer(
|
|||
}
|
||||
}
|
||||
|
||||
func (f *streamFramer) AddFrameForRetransmission(frame *wire.StreamFrame) {
|
||||
f.retransmissionQueue = append(f.retransmissionQueue, frame)
|
||||
}
|
||||
|
||||
func (f *streamFramer) AddActiveStream(id protocol.StreamID) {
|
||||
if id == f.version.CryptoStreamID() { // the crypto stream is handled separately
|
||||
f.streamQueueMutex.Lock()
|
||||
|
@ -52,15 +46,6 @@ func (f *streamFramer) AddActiveStream(id protocol.StreamID) {
|
|||
f.streamQueueMutex.Unlock()
|
||||
}
|
||||
|
||||
func (f *streamFramer) PopStreamFrames(maxLen protocol.ByteCount) []*wire.StreamFrame {
|
||||
fs, currentLen := f.maybePopFramesForRetransmission(maxLen)
|
||||
return append(fs, f.maybePopNormalFrames(maxLen-currentLen)...)
|
||||
}
|
||||
|
||||
func (f *streamFramer) HasFramesForRetransmission() bool {
|
||||
return len(f.retransmissionQueue) > 0
|
||||
}
|
||||
|
||||
func (f *streamFramer) HasCryptoStreamData() bool {
|
||||
f.streamQueueMutex.Lock()
|
||||
hasCryptoStreamData := f.hasCryptoStreamData
|
||||
|
@ -76,34 +61,7 @@ func (f *streamFramer) PopCryptoStreamFrame(maxLen protocol.ByteCount) *wire.Str
|
|||
return frame
|
||||
}
|
||||
|
||||
func (f *streamFramer) maybePopFramesForRetransmission(maxTotalLen protocol.ByteCount) (res []*wire.StreamFrame, currentLen protocol.ByteCount) {
|
||||
for len(f.retransmissionQueue) > 0 {
|
||||
frame := f.retransmissionQueue[0]
|
||||
frame.DataLenPresent = true
|
||||
|
||||
maxLen := maxTotalLen - currentLen
|
||||
if frame.Length(f.version) > maxLen && maxLen < protocol.MinStreamFrameSize {
|
||||
break
|
||||
}
|
||||
|
||||
splitFrame, err := frame.MaybeSplitOffFrame(maxLen, f.version)
|
||||
if err != nil { // maxLen is too small. Can't split frame
|
||||
break
|
||||
}
|
||||
if splitFrame != nil { // frame was split
|
||||
res = append(res, splitFrame)
|
||||
currentLen += splitFrame.Length(f.version)
|
||||
break
|
||||
}
|
||||
|
||||
f.retransmissionQueue = f.retransmissionQueue[1:]
|
||||
res = append(res, frame)
|
||||
currentLen += frame.Length(f.version)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *streamFramer) maybePopNormalFrames(maxTotalLen protocol.ByteCount) []*wire.StreamFrame {
|
||||
func (f *streamFramer) PopStreamFrames(maxTotalLen protocol.ByteCount) []*wire.StreamFrame {
|
||||
var currentLen protocol.ByteCount
|
||||
var frames []*wire.StreamFrame
|
||||
f.streamQueueMutex.Lock()
|
||||
|
|
24
vendor/github.com/lucas-clemente/quic-go/streams_map.go
generated
vendored
24
vendor/github.com/lucas-clemente/quic-go/streams_map.go
generated
vendored
|
@ -35,6 +35,8 @@ var _ streamManager = &streamsMap{}
|
|||
func newStreamsMap(
|
||||
sender streamSender,
|
||||
newFlowController func(protocol.StreamID) flowcontrol.StreamFlowController,
|
||||
maxIncomingStreams int,
|
||||
maxIncomingUniStreams int,
|
||||
perspective protocol.Perspective,
|
||||
version protocol.VersionNumber,
|
||||
) streamManager {
|
||||
|
@ -46,7 +48,7 @@ func newStreamsMap(
|
|||
var firstOutgoingBidiStream, firstOutgoingUniStream, firstIncomingBidiStream, firstIncomingUniStream protocol.StreamID
|
||||
if perspective == protocol.PerspectiveServer {
|
||||
firstOutgoingBidiStream = 1
|
||||
firstIncomingBidiStream = 4 // the crypto stream is handled separatedly
|
||||
firstIncomingBidiStream = 4 // the crypto stream is handled separately
|
||||
firstOutgoingUniStream = 3
|
||||
firstIncomingUniStream = 2
|
||||
} else {
|
||||
|
@ -69,11 +71,10 @@ func newStreamsMap(
|
|||
newBidiStream,
|
||||
sender.queueControlFrame,
|
||||
)
|
||||
// TODO(#523): make these values configurable
|
||||
m.incomingBidiStreams = newIncomingBidiStreamsMap(
|
||||
firstIncomingBidiStream,
|
||||
protocol.MaxBidiStreamID(protocol.MaxIncomingStreams, perspective),
|
||||
protocol.MaxIncomingStreams,
|
||||
protocol.MaxBidiStreamID(maxIncomingStreams, perspective),
|
||||
maxIncomingStreams,
|
||||
sender.queueControlFrame,
|
||||
newBidiStream,
|
||||
)
|
||||
|
@ -82,11 +83,10 @@ func newStreamsMap(
|
|||
newUniSendStream,
|
||||
sender.queueControlFrame,
|
||||
)
|
||||
// TODO(#523): make these values configurable
|
||||
m.incomingUniStreams = newIncomingUniStreamsMap(
|
||||
firstIncomingUniStream,
|
||||
protocol.MaxUniStreamID(protocol.MaxIncomingStreams, perspective),
|
||||
protocol.MaxIncomingStreams,
|
||||
protocol.MaxUniStreamID(maxIncomingUniStreams, perspective),
|
||||
maxIncomingUniStreams,
|
||||
sender.queueControlFrame,
|
||||
newUniReceiveStream,
|
||||
)
|
||||
|
@ -206,8 +206,14 @@ func (m *streamsMap) HandleMaxStreamIDFrame(f *wire.MaxStreamIDFrame) error {
|
|||
}
|
||||
|
||||
func (m *streamsMap) UpdateLimits(p *handshake.TransportParameters) {
|
||||
m.outgoingBidiStreams.SetMaxStream(p.MaxBidiStreamID)
|
||||
m.outgoingUniStreams.SetMaxStream(p.MaxUniStreamID)
|
||||
// Max{Uni,Bidi}StreamID returns the highest stream ID that the peer is allowed to open.
|
||||
// Invert the perspective to determine the value that we are allowed to open.
|
||||
peerPers := protocol.PerspectiveServer
|
||||
if m.perspective == protocol.PerspectiveServer {
|
||||
peerPers = protocol.PerspectiveClient
|
||||
}
|
||||
m.outgoingBidiStreams.SetMaxStream(protocol.MaxBidiStreamID(int(p.MaxBidiStreams), peerPers))
|
||||
m.outgoingUniStreams.SetMaxStream(protocol.MaxUniStreamID(int(p.MaxUniStreams), peerPers))
|
||||
}
|
||||
|
||||
func (m *streamsMap) CloseWithError(err error) {
|
||||
|
|
7
vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_bidi.go
generated
vendored
7
vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_bidi.go
generated
vendored
|
@ -69,20 +69,25 @@ func (m *incomingBidiStreamsMap) AcceptStream() (streamI, error) {
|
|||
}
|
||||
|
||||
func (m *incomingBidiStreamsMap) GetOrOpenStream(id protocol.StreamID) (streamI, error) {
|
||||
m.mutex.RLock()
|
||||
if id > m.maxStream {
|
||||
m.mutex.RUnlock()
|
||||
return nil, fmt.Errorf("peer tried to open stream %d (current limit: %d)", id, m.maxStream)
|
||||
}
|
||||
// if the id is smaller than the highest we accepted
|
||||
// * this stream exists in the map, and we can return it, or
|
||||
// * this stream was already closed, then we can return the nil
|
||||
if id <= m.highestStream {
|
||||
m.mutex.RLock()
|
||||
s := m.streams[id]
|
||||
m.mutex.RUnlock()
|
||||
return s, nil
|
||||
}
|
||||
m.mutex.RUnlock()
|
||||
|
||||
m.mutex.Lock()
|
||||
// no need to check the two error conditions from above again
|
||||
// * maxStream can only increase, so if the id was valid before, it definitely is valid now
|
||||
// * highestStream is only modified by this function
|
||||
var start protocol.StreamID
|
||||
if m.highestStream == 0 {
|
||||
start = m.nextStream
|
||||
|
|
7
vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_generic.go
generated
vendored
7
vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_generic.go
generated
vendored
|
@ -67,20 +67,25 @@ func (m *incomingItemsMap) AcceptStream() (item, error) {
|
|||
}
|
||||
|
||||
func (m *incomingItemsMap) GetOrOpenStream(id protocol.StreamID) (item, error) {
|
||||
m.mutex.RLock()
|
||||
if id > m.maxStream {
|
||||
m.mutex.RUnlock()
|
||||
return nil, fmt.Errorf("peer tried to open stream %d (current limit: %d)", id, m.maxStream)
|
||||
}
|
||||
// if the id is smaller than the highest we accepted
|
||||
// * this stream exists in the map, and we can return it, or
|
||||
// * this stream was already closed, then we can return the nil
|
||||
if id <= m.highestStream {
|
||||
m.mutex.RLock()
|
||||
s := m.streams[id]
|
||||
m.mutex.RUnlock()
|
||||
return s, nil
|
||||
}
|
||||
m.mutex.RUnlock()
|
||||
|
||||
m.mutex.Lock()
|
||||
// no need to check the two error conditions from above again
|
||||
// * maxStream can only increase, so if the id was valid before, it definitely is valid now
|
||||
// * highestStream is only modified by this function
|
||||
var start protocol.StreamID
|
||||
if m.highestStream == 0 {
|
||||
start = m.nextStream
|
||||
|
|
7
vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_uni.go
generated
vendored
7
vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_uni.go
generated
vendored
|
@ -69,20 +69,25 @@ func (m *incomingUniStreamsMap) AcceptStream() (receiveStreamI, error) {
|
|||
}
|
||||
|
||||
func (m *incomingUniStreamsMap) GetOrOpenStream(id protocol.StreamID) (receiveStreamI, error) {
|
||||
m.mutex.RLock()
|
||||
if id > m.maxStream {
|
||||
m.mutex.RUnlock()
|
||||
return nil, fmt.Errorf("peer tried to open stream %d (current limit: %d)", id, m.maxStream)
|
||||
}
|
||||
// if the id is smaller than the highest we accepted
|
||||
// * this stream exists in the map, and we can return it, or
|
||||
// * this stream was already closed, then we can return the nil
|
||||
if id <= m.highestStream {
|
||||
m.mutex.RLock()
|
||||
s := m.streams[id]
|
||||
m.mutex.RUnlock()
|
||||
return s, nil
|
||||
}
|
||||
m.mutex.RUnlock()
|
||||
|
||||
m.mutex.Lock()
|
||||
// no need to check the two error conditions from above again
|
||||
// * maxStream can only increase, so if the id was valid before, it definitely is valid now
|
||||
// * highestStream is only modified by this function
|
||||
var start protocol.StreamID
|
||||
if m.highestStream == 0 {
|
||||
start = m.nextStream
|
||||
|
|
22
vendor/github.com/lucas-clemente/quic-go/streams_map_legacy.go
generated
vendored
22
vendor/github.com/lucas-clemente/quic-go/streams_map_legacy.go
generated
vendored
|
@ -39,11 +39,10 @@ var _ streamManager = &streamsMapLegacy{}
|
|||
|
||||
var errMapAccess = errors.New("streamsMap: Error accessing the streams map")
|
||||
|
||||
func newStreamsMapLegacy(newStream func(protocol.StreamID) streamI, pers protocol.Perspective) streamManager {
|
||||
func newStreamsMapLegacy(newStream func(protocol.StreamID) streamI, maxStreams int, pers protocol.Perspective) streamManager {
|
||||
// add some tolerance to the maximum incoming streams value
|
||||
maxStreams := uint32(protocol.MaxIncomingStreams)
|
||||
maxIncomingStreams := utils.MaxUint32(
|
||||
maxStreams+protocol.MaxStreamsMinimumIncrement,
|
||||
uint32(maxStreams)+protocol.MaxStreamsMinimumIncrement,
|
||||
uint32(float64(maxStreams)*float64(protocol.MaxStreamsMultiplier)),
|
||||
)
|
||||
sm := streamsMapLegacy{
|
||||
|
@ -131,7 +130,10 @@ func (m *streamsMapLegacy) openRemoteStream(id protocol.StreamID) (streamI, erro
|
|||
if m.numIncomingStreams >= m.maxIncomingStreams {
|
||||
return nil, qerr.TooManyOpenStreams
|
||||
}
|
||||
if id+protocol.MaxNewStreamIDDelta < m.highestStreamOpenedByPeer {
|
||||
// maxNewStreamIDDelta is the maximum difference between and a newly opened Stream and the highest StreamID that a client has ever opened
|
||||
// note that the number of streams is half this value, since the client can only open streams with open StreamID
|
||||
maxStreamIDDelta := protocol.StreamID(4 * m.maxIncomingStreams)
|
||||
if id+maxStreamIDDelta < m.highestStreamOpenedByPeer {
|
||||
return nil, qerr.Error(qerr.InvalidStreamID, fmt.Sprintf("attempted to open stream %d, which is a lot smaller than the highest opened stream, %d", id, m.highestStreamOpenedByPeer))
|
||||
}
|
||||
|
||||
|
@ -185,6 +187,14 @@ func (m *streamsMapLegacy) OpenStreamSync() (Stream, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *streamsMapLegacy) OpenUniStream() (SendStream, error) {
|
||||
return nil, errors.New("gQUIC doesn't support unidirectional streams")
|
||||
}
|
||||
|
||||
func (m *streamsMapLegacy) OpenUniStreamSync() (SendStream, error) {
|
||||
return nil, errors.New("gQUIC doesn't support unidirectional streams")
|
||||
}
|
||||
|
||||
// AcceptStream returns the next stream opened by the peer
|
||||
// it blocks until a new stream is opened
|
||||
func (m *streamsMapLegacy) AcceptStream() (Stream, error) {
|
||||
|
@ -206,6 +216,10 @@ func (m *streamsMapLegacy) AcceptStream() (Stream, error) {
|
|||
return str, nil
|
||||
}
|
||||
|
||||
func (m *streamsMapLegacy) AcceptUniStream() (ReceiveStream, error) {
|
||||
return nil, errors.New("gQUIC doesn't support unidirectional streams")
|
||||
}
|
||||
|
||||
func (m *streamsMapLegacy) DeleteStream(id protocol.StreamID) error {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
|
3
vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_bidi.go
generated
vendored
3
vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_bidi.go
generated
vendored
|
@ -85,10 +85,11 @@ func (m *outgoingBidiStreamsMap) openStreamImpl() (streamI, error) {
|
|||
}
|
||||
|
||||
func (m *outgoingBidiStreamsMap) GetStream(id protocol.StreamID) (streamI, error) {
|
||||
m.mutex.RLock()
|
||||
if id >= m.nextStream {
|
||||
m.mutex.RUnlock()
|
||||
return nil, qerr.Error(qerr.InvalidStreamID, fmt.Sprintf("peer attempted to open stream %d", id))
|
||||
}
|
||||
m.mutex.RLock()
|
||||
s := m.streams[id]
|
||||
m.mutex.RUnlock()
|
||||
return s, nil
|
||||
|
|
3
vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_generic.go
generated
vendored
3
vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_generic.go
generated
vendored
|
@ -86,10 +86,11 @@ func (m *outgoingItemsMap) openStreamImpl() (item, error) {
|
|||
}
|
||||
|
||||
func (m *outgoingItemsMap) GetStream(id protocol.StreamID) (item, error) {
|
||||
m.mutex.RLock()
|
||||
if id >= m.nextStream {
|
||||
m.mutex.RUnlock()
|
||||
return nil, qerr.Error(qerr.InvalidStreamID, fmt.Sprintf("peer attempted to open stream %d", id))
|
||||
}
|
||||
m.mutex.RLock()
|
||||
s := m.streams[id]
|
||||
m.mutex.RUnlock()
|
||||
return s, nil
|
||||
|
|
3
vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_uni.go
generated
vendored
3
vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_uni.go
generated
vendored
|
@ -85,10 +85,11 @@ func (m *outgoingUniStreamsMap) openStreamImpl() (sendStreamI, error) {
|
|||
}
|
||||
|
||||
func (m *outgoingUniStreamsMap) GetStream(id protocol.StreamID) (sendStreamI, error) {
|
||||
m.mutex.RLock()
|
||||
if id >= m.nextStream {
|
||||
m.mutex.RUnlock()
|
||||
return nil, qerr.Error(qerr.InvalidStreamID, fmt.Sprintf("peer attempted to open stream %d", id))
|
||||
}
|
||||
m.mutex.RLock()
|
||||
s := m.streams[id]
|
||||
m.mutex.RUnlock()
|
||||
return s, nil
|
||||
|
|
|
@ -50,7 +50,7 @@ import (
|
|||
// WAIT_FINISHED RekeyIn; [Send(EOED);] RekeyOut; [SendCert; SendCV;] SendFin; RekeyOut;
|
||||
// CONNECTED StoreTicket || (RekeyIn; [RekeyOut])
|
||||
|
||||
type ClientStateStart struct {
|
||||
type clientStateStart struct {
|
||||
Config *Config
|
||||
Opts ConnectionOptions
|
||||
Params ConnectionParameters
|
||||
|
@ -61,13 +61,13 @@ type ClientStateStart struct {
|
|||
hsCtx HandshakeContext
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ClientStateStart{}
|
||||
var _ HandshakeState = &clientStateStart{}
|
||||
|
||||
func (state ClientStateStart) State() State {
|
||||
func (state clientStateStart) State() State {
|
||||
return StateClientStart
|
||||
}
|
||||
|
||||
func (state ClientStateStart) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state clientStateStart) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
// key_shares
|
||||
offeredDH := map[NamedGroup][]byte{}
|
||||
ks := KeyShareExtension{
|
||||
|
@ -268,7 +268,7 @@ func (state ClientStateStart) Next(hr handshakeMessageReader) (HandshakeState, [
|
|||
|
||||
logf(logTypeHandshake, "[ClientStateStart] -> [ClientStateWaitSH]")
|
||||
state.hsCtx.SetVersion(tls12Version) // Everything after this should be 1.2.
|
||||
nextState := ClientStateWaitSH{
|
||||
nextState := clientStateWaitSH{
|
||||
Config: state.Config,
|
||||
Opts: state.Opts,
|
||||
Params: state.Params,
|
||||
|
@ -298,7 +298,7 @@ func (state ClientStateStart) Next(hr handshakeMessageReader) (HandshakeState, [
|
|||
return nextState, toSend, AlertNoAlert
|
||||
}
|
||||
|
||||
type ClientStateWaitSH struct {
|
||||
type clientStateWaitSH struct {
|
||||
Config *Config
|
||||
Opts ConnectionOptions
|
||||
Params ConnectionParameters
|
||||
|
@ -315,13 +315,13 @@ type ClientStateWaitSH struct {
|
|||
clientHello *HandshakeMessage
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ClientStateWaitSH{}
|
||||
var _ HandshakeState = &clientStateWaitSH{}
|
||||
|
||||
func (state ClientStateWaitSH) State() State {
|
||||
func (state clientStateWaitSH) State() State {
|
||||
return StateClientWaitSH
|
||||
}
|
||||
|
||||
func (state ClientStateWaitSH) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state clientStateWaitSH) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
hm, alert := hr.ReadMessage()
|
||||
if alert != AlertNoAlert {
|
||||
return nil, nil, alert
|
||||
|
@ -413,7 +413,7 @@ func (state ClientStateWaitSH) Next(hr handshakeMessageReader) (HandshakeState,
|
|||
}
|
||||
|
||||
logf(logTypeHandshake, "[ClientStateWaitSH] -> [ClientStateStart]")
|
||||
return ClientStateStart{
|
||||
return clientStateStart{
|
||||
Config: state.Config,
|
||||
Opts: state.Opts,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -517,7 +517,7 @@ func (state ClientStateWaitSH) Next(hr handshakeMessageReader) (HandshakeState,
|
|||
serverHandshakeKeys := makeTrafficKeys(params, serverHandshakeTrafficSecret)
|
||||
|
||||
logf(logTypeHandshake, "[ClientStateWaitSH] -> [ClientStateWaitEE]")
|
||||
nextState := ClientStateWaitEE{
|
||||
nextState := clientStateWaitEE{
|
||||
Config: state.Config,
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -533,7 +533,7 @@ func (state ClientStateWaitSH) Next(hr handshakeMessageReader) (HandshakeState,
|
|||
return nextState, toSend, AlertNoAlert
|
||||
}
|
||||
|
||||
type ClientStateWaitEE struct {
|
||||
type clientStateWaitEE struct {
|
||||
Config *Config
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
|
@ -544,13 +544,13 @@ type ClientStateWaitEE struct {
|
|||
serverHandshakeTrafficSecret []byte
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ClientStateWaitEE{}
|
||||
var _ HandshakeState = &clientStateWaitEE{}
|
||||
|
||||
func (state ClientStateWaitEE) State() State {
|
||||
func (state clientStateWaitEE) State() State {
|
||||
return StateClientWaitEE
|
||||
}
|
||||
|
||||
func (state ClientStateWaitEE) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state clientStateWaitEE) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
hm, alert := hr.ReadMessage()
|
||||
if alert != AlertNoAlert {
|
||||
return nil, nil, alert
|
||||
|
@ -598,7 +598,7 @@ func (state ClientStateWaitEE) Next(hr handshakeMessageReader) (HandshakeState,
|
|||
|
||||
if state.Params.UsingPSK {
|
||||
logf(logTypeHandshake, "[ClientStateWaitEE] -> [ClientStateWaitFinished]")
|
||||
nextState := ClientStateWaitFinished{
|
||||
nextState := clientStateWaitFinished{
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
cryptoParams: state.cryptoParams,
|
||||
|
@ -612,7 +612,7 @@ func (state ClientStateWaitEE) Next(hr handshakeMessageReader) (HandshakeState,
|
|||
}
|
||||
|
||||
logf(logTypeHandshake, "[ClientStateWaitEE] -> [ClientStateWaitCertCR]")
|
||||
nextState := ClientStateWaitCertCR{
|
||||
nextState := clientStateWaitCertCR{
|
||||
Config: state.Config,
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -625,7 +625,7 @@ func (state ClientStateWaitEE) Next(hr handshakeMessageReader) (HandshakeState,
|
|||
return nextState, nil, AlertNoAlert
|
||||
}
|
||||
|
||||
type ClientStateWaitCertCR struct {
|
||||
type clientStateWaitCertCR struct {
|
||||
Config *Config
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
|
@ -636,13 +636,13 @@ type ClientStateWaitCertCR struct {
|
|||
serverHandshakeTrafficSecret []byte
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ClientStateWaitCertCR{}
|
||||
var _ HandshakeState = &clientStateWaitCertCR{}
|
||||
|
||||
func (state ClientStateWaitCertCR) State() State {
|
||||
func (state clientStateWaitCertCR) State() State {
|
||||
return StateClientWaitCertCR
|
||||
}
|
||||
|
||||
func (state ClientStateWaitCertCR) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state clientStateWaitCertCR) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
hm, alert := hr.ReadMessage()
|
||||
if alert != AlertNoAlert {
|
||||
return nil, nil, alert
|
||||
|
@ -663,7 +663,7 @@ func (state ClientStateWaitCertCR) Next(hr handshakeMessageReader) (HandshakeSta
|
|||
switch body := bodyGeneric.(type) {
|
||||
case *CertificateBody:
|
||||
logf(logTypeHandshake, "[ClientStateWaitCertCR] -> [ClientStateWaitCV]")
|
||||
nextState := ClientStateWaitCV{
|
||||
nextState := clientStateWaitCV{
|
||||
Config: state.Config,
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -686,7 +686,7 @@ func (state ClientStateWaitCertCR) Next(hr handshakeMessageReader) (HandshakeSta
|
|||
state.Params.UsingClientAuth = true
|
||||
|
||||
logf(logTypeHandshake, "[ClientStateWaitCertCR] -> [ClientStateWaitCert]")
|
||||
nextState := ClientStateWaitCert{
|
||||
nextState := clientStateWaitCert{
|
||||
Config: state.Config,
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -703,7 +703,7 @@ func (state ClientStateWaitCertCR) Next(hr handshakeMessageReader) (HandshakeSta
|
|||
return nil, nil, AlertUnexpectedMessage
|
||||
}
|
||||
|
||||
type ClientStateWaitCert struct {
|
||||
type clientStateWaitCert struct {
|
||||
Config *Config
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
|
@ -717,13 +717,13 @@ type ClientStateWaitCert struct {
|
|||
serverHandshakeTrafficSecret []byte
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ClientStateWaitCert{}
|
||||
var _ HandshakeState = &clientStateWaitCert{}
|
||||
|
||||
func (state ClientStateWaitCert) State() State {
|
||||
func (state clientStateWaitCert) State() State {
|
||||
return StateClientWaitCert
|
||||
}
|
||||
|
||||
func (state ClientStateWaitCert) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state clientStateWaitCert) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
hm, alert := hr.ReadMessage()
|
||||
if alert != AlertNoAlert {
|
||||
return nil, nil, alert
|
||||
|
@ -742,7 +742,7 @@ func (state ClientStateWaitCert) Next(hr handshakeMessageReader) (HandshakeState
|
|||
state.handshakeHash.Write(hm.Marshal())
|
||||
|
||||
logf(logTypeHandshake, "[ClientStateWaitCert] -> [ClientStateWaitCV]")
|
||||
nextState := ClientStateWaitCV{
|
||||
nextState := clientStateWaitCV{
|
||||
Config: state.Config,
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -757,7 +757,7 @@ func (state ClientStateWaitCert) Next(hr handshakeMessageReader) (HandshakeState
|
|||
return nextState, nil, AlertNoAlert
|
||||
}
|
||||
|
||||
type ClientStateWaitCV struct {
|
||||
type clientStateWaitCV struct {
|
||||
Config *Config
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
|
@ -772,13 +772,13 @@ type ClientStateWaitCV struct {
|
|||
serverHandshakeTrafficSecret []byte
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ClientStateWaitCV{}
|
||||
var _ HandshakeState = &clientStateWaitCV{}
|
||||
|
||||
func (state ClientStateWaitCV) State() State {
|
||||
func (state clientStateWaitCV) State() State {
|
||||
return StateClientWaitCV
|
||||
}
|
||||
|
||||
func (state ClientStateWaitCV) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state clientStateWaitCV) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
hm, alert := hr.ReadMessage()
|
||||
if alert != AlertNoAlert {
|
||||
return nil, nil, alert
|
||||
|
@ -843,7 +843,7 @@ func (state ClientStateWaitCV) Next(hr handshakeMessageReader) (HandshakeState,
|
|||
state.handshakeHash.Write(hm.Marshal())
|
||||
|
||||
logf(logTypeHandshake, "[ClientStateWaitCV] -> [ClientStateWaitFinished]")
|
||||
nextState := ClientStateWaitFinished{
|
||||
nextState := clientStateWaitFinished{
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
cryptoParams: state.cryptoParams,
|
||||
|
@ -859,7 +859,7 @@ func (state ClientStateWaitCV) Next(hr handshakeMessageReader) (HandshakeState,
|
|||
return nextState, nil, AlertNoAlert
|
||||
}
|
||||
|
||||
type ClientStateWaitFinished struct {
|
||||
type clientStateWaitFinished struct {
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
cryptoParams CipherSuiteParams
|
||||
|
@ -875,13 +875,13 @@ type ClientStateWaitFinished struct {
|
|||
serverHandshakeTrafficSecret []byte
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ClientStateWaitFinished{}
|
||||
var _ HandshakeState = &clientStateWaitFinished{}
|
||||
|
||||
func (state ClientStateWaitFinished) State() State {
|
||||
func (state clientStateWaitFinished) State() State {
|
||||
return StateClientWaitFinished
|
||||
}
|
||||
|
||||
func (state ClientStateWaitFinished) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state clientStateWaitFinished) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
hm, alert := hr.ReadMessage()
|
||||
if alert != AlertNoAlert {
|
||||
return nil, nil, alert
|
||||
|
@ -1046,7 +1046,7 @@ func (state ClientStateWaitFinished) Next(hr handshakeMessageReader) (HandshakeS
|
|||
}...)
|
||||
|
||||
logf(logTypeHandshake, "[ClientStateWaitFinished] -> [StateConnected]")
|
||||
nextState := StateConnected{
|
||||
nextState := stateConnected{
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
isClient: true,
|
||||
|
|
|
@ -201,6 +201,8 @@ func (s State) String() string {
|
|||
return "Client WAIT_CV"
|
||||
case StateClientWaitFinished:
|
||||
return "Client WAIT_FINISHED"
|
||||
case StateClientWaitCertCR:
|
||||
return "Client WAIT_CERT_CR"
|
||||
case StateClientConnected:
|
||||
return "Client CONNECTED"
|
||||
case StateServerStart:
|
||||
|
|
18
vendor/github.com/lucas-clemente/quic-go/vendor/github.com/bifurcation/mint/conn.go
generated
vendored
18
vendor/github.com/lucas-clemente/quic-go/vendor/github.com/bifurcation/mint/conn.go
generated
vendored
|
@ -265,7 +265,7 @@ type Conn struct {
|
|||
|
||||
EarlyData []byte
|
||||
|
||||
state StateConnected
|
||||
state stateConnected
|
||||
hState HandshakeState
|
||||
handshakeMutex sync.Mutex
|
||||
handshakeAlert Alert
|
||||
|
@ -345,7 +345,7 @@ func (c *Conn) consumeRecord() error {
|
|||
}
|
||||
|
||||
var connected bool
|
||||
c.state, connected = state.(StateConnected)
|
||||
c.state, connected = state.(stateConnected)
|
||||
if !connected {
|
||||
logf(logTypeHandshake, "Disconnected after state transition: %v", alert)
|
||||
c.sendAlert(alert)
|
||||
|
@ -385,7 +385,7 @@ func (c *Conn) consumeRecord() error {
|
|||
// Read application data up to the size of buffer. Handshake and alert records
|
||||
// are consumed by the Conn object directly.
|
||||
func (c *Conn) Read(buffer []byte) (int, error) {
|
||||
if _, connected := c.hState.(StateConnected); !connected && c.config.NonBlocking {
|
||||
if _, connected := c.hState.(stateConnected); !connected {
|
||||
return 0, errors.New("Read called before the handshake completed")
|
||||
}
|
||||
logf(logTypeHandshake, "conn.Read with buffer = %d", len(buffer))
|
||||
|
@ -661,7 +661,7 @@ func (c *Conn) HandshakeSetup() Alert {
|
|||
}
|
||||
|
||||
if c.isClient {
|
||||
state, actions, alert = ClientStateStart{Config: c.config, Opts: opts, hsCtx: c.hsCtx}.Next(nil)
|
||||
state, actions, alert = clientStateStart{Config: c.config, Opts: opts, hsCtx: c.hsCtx}.Next(nil)
|
||||
if alert != AlertNoAlert {
|
||||
logf(logTypeHandshake, "Error initializing client state: %v", alert)
|
||||
return alert
|
||||
|
@ -688,7 +688,7 @@ func (c *Conn) HandshakeSetup() Alert {
|
|||
return AlertInternalError
|
||||
}
|
||||
}
|
||||
state = ServerStateStart{Config: c.config, conn: c, hsCtx: c.hsCtx}
|
||||
state = serverStateStart{Config: c.config, conn: c, hsCtx: c.hsCtx}
|
||||
}
|
||||
|
||||
c.hState = state
|
||||
|
@ -751,7 +751,7 @@ func (c *Conn) Handshake() Alert {
|
|||
|
||||
logf(logTypeHandshake, "(Re-)entering handshake, state=%v", c.hState)
|
||||
state := c.hState
|
||||
_, connected := state.(StateConnected)
|
||||
_, connected := state.(stateConnected)
|
||||
|
||||
hmr := &handshakeMessageReaderImpl{hsCtx: &c.hsCtx}
|
||||
for !connected {
|
||||
|
@ -784,9 +784,9 @@ func (c *Conn) Handshake() Alert {
|
|||
|
||||
c.hState = state
|
||||
logf(logTypeHandshake, "state is now %s", c.GetHsState())
|
||||
_, connected = state.(StateConnected)
|
||||
_, connected = state.(stateConnected)
|
||||
if connected {
|
||||
c.state = state.(StateConnected)
|
||||
c.state = state.(stateConnected)
|
||||
c.handshakeComplete = true
|
||||
}
|
||||
|
||||
|
@ -852,7 +852,7 @@ func (c *Conn) GetHsState() State {
|
|||
}
|
||||
|
||||
func (c *Conn) ComputeExporter(label string, context []byte, keyLength int) ([]byte, error) {
|
||||
_, connected := c.hState.(StateConnected)
|
||||
_, connected := c.hState.(stateConnected)
|
||||
if !connected {
|
||||
return nil, fmt.Errorf("Cannot compute exporter when state is not connected")
|
||||
}
|
||||
|
|
49
vendor/github.com/lucas-clemente/quic-go/vendor/github.com/bifurcation/mint/crypto.go
generated
vendored
49
vendor/github.com/lucas-clemente/quic-go/vendor/github.com/bifurcation/mint/crypto.go
generated
vendored
|
@ -11,9 +11,11 @@ import (
|
|||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/curve25519"
|
||||
|
||||
|
@ -616,3 +618,50 @@ func makeTrafficKeys(params CipherSuiteParams, secret []byte) keySet {
|
|||
iv: HkdfExpandLabel(params.Hash, secret, "iv", []byte{}, params.IvLen),
|
||||
}
|
||||
}
|
||||
|
||||
func MakeNewSelfSignedCert(name string, alg SignatureScheme) (crypto.Signer, *x509.Certificate, error) {
|
||||
priv, err := newSigningKey(alg)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cert, err := newSelfSigned(name, alg, priv)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return priv, cert, nil
|
||||
}
|
||||
|
||||
func newSelfSigned(name string, alg SignatureScheme, priv crypto.Signer) (*x509.Certificate, error) {
|
||||
sigAlg, ok := x509AlgMap[alg]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("tls.selfsigned: Unknown signature algorithm [%04x]", alg)
|
||||
}
|
||||
if len(name) == 0 {
|
||||
return nil, fmt.Errorf("tls.selfsigned: No name provided")
|
||||
}
|
||||
|
||||
serial, err := rand.Int(rand.Reader, big.NewInt(0xA0A0A0A0))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
template := &x509.Certificate{
|
||||
SerialNumber: serial,
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().AddDate(0, 0, 1),
|
||||
SignatureAlgorithm: sigAlg,
|
||||
Subject: pkix.Name{CommonName: name},
|
||||
DNSNames: []string{name},
|
||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyAgreement | x509.KeyUsageKeyEncipherment,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
}
|
||||
der, err := x509.CreateCertificate(prng, template, template, priv.Public(), priv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// It is safe to ignore the error here because we're parsing known-good data
|
||||
cert, _ := x509.ParseCertificate(der)
|
||||
return cert, nil
|
||||
}
|
||||
|
|
|
@ -71,19 +71,19 @@ type cookie struct {
|
|||
ApplicationCookie []byte `tls:"head=2"`
|
||||
}
|
||||
|
||||
type ServerStateStart struct {
|
||||
type serverStateStart struct {
|
||||
Config *Config
|
||||
conn *Conn
|
||||
hsCtx HandshakeContext
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ServerStateStart{}
|
||||
var _ HandshakeState = &serverStateStart{}
|
||||
|
||||
func (state ServerStateStart) State() State {
|
||||
func (state serverStateStart) State() State {
|
||||
return StateServerStart
|
||||
}
|
||||
|
||||
func (state ServerStateStart) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state serverStateStart) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
hm, alert := hr.ReadMessage()
|
||||
if alert != AlertNoAlert {
|
||||
return nil, nil, alert
|
||||
|
@ -381,7 +381,7 @@ func (state ServerStateStart) Next(hr handshakeMessageReader) (HandshakeState, [
|
|||
|
||||
logf(logTypeHandshake, "[ServerStateStart] -> [ServerStateNegotiated]")
|
||||
state.hsCtx.SetVersion(tls12Version) // Everything after this should be 1.2.
|
||||
return ServerStateNegotiated{
|
||||
return serverStateNegotiated{
|
||||
Config: state.Config,
|
||||
Params: connParams,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -401,7 +401,7 @@ func (state ServerStateStart) Next(hr handshakeMessageReader) (HandshakeState, [
|
|||
}, nil, AlertNoAlert
|
||||
}
|
||||
|
||||
func (state *ServerStateStart) generateHRR(cs CipherSuite, legacySessionId []byte,
|
||||
func (state *serverStateStart) generateHRR(cs CipherSuite, legacySessionId []byte,
|
||||
cookieExt *CookieExtension) (*HandshakeMessage, error) {
|
||||
var helloRetryRequest *HandshakeMessage
|
||||
hrr := &ServerHelloBody{
|
||||
|
@ -442,7 +442,7 @@ func (state *ServerStateStart) generateHRR(cs CipherSuite, legacySessionId []byt
|
|||
return helloRetryRequest, nil
|
||||
}
|
||||
|
||||
type ServerStateNegotiated struct {
|
||||
type serverStateNegotiated struct {
|
||||
Config *Config
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
|
@ -460,13 +460,13 @@ type ServerStateNegotiated struct {
|
|||
clientHello *HandshakeMessage
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ServerStateNegotiated{}
|
||||
var _ HandshakeState = &serverStateNegotiated{}
|
||||
|
||||
func (state ServerStateNegotiated) State() State {
|
||||
func (state serverStateNegotiated) State() State {
|
||||
return StateServerNegotiated
|
||||
}
|
||||
|
||||
func (state ServerStateNegotiated) Next(_ handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state serverStateNegotiated) Next(_ handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
// Create the ServerHello
|
||||
sh := &ServerHelloBody{
|
||||
Version: tls12Version,
|
||||
|
@ -717,7 +717,7 @@ func (state ServerStateNegotiated) Next(_ handshakeMessageReader) (HandshakeStat
|
|||
clientEarlyTrafficKeys := makeTrafficKeys(params, state.clientEarlyTrafficSecret)
|
||||
|
||||
logf(logTypeHandshake, "[ServerStateNegotiated] -> [ServerStateWaitEOED]")
|
||||
nextState := ServerStateWaitEOED{
|
||||
nextState := serverStateWaitEOED{
|
||||
Config: state.Config,
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -741,7 +741,7 @@ func (state ServerStateNegotiated) Next(_ handshakeMessageReader) (HandshakeStat
|
|||
RekeyIn{epoch: EpochHandshakeData, KeySet: clientHandshakeKeys},
|
||||
ReadPastEarlyData{},
|
||||
}...)
|
||||
waitFlight2 := ServerStateWaitFlight2{
|
||||
waitFlight2 := serverStateWaitFlight2{
|
||||
Config: state.Config,
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -756,7 +756,7 @@ func (state ServerStateNegotiated) Next(_ handshakeMessageReader) (HandshakeStat
|
|||
return waitFlight2, toSend, AlertNoAlert
|
||||
}
|
||||
|
||||
type ServerStateWaitEOED struct {
|
||||
type serverStateWaitEOED struct {
|
||||
Config *Config
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
|
@ -769,13 +769,13 @@ type ServerStateWaitEOED struct {
|
|||
exporterSecret []byte
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ServerStateWaitEOED{}
|
||||
var _ HandshakeState = &serverStateWaitEOED{}
|
||||
|
||||
func (state ServerStateWaitEOED) State() State {
|
||||
func (state serverStateWaitEOED) State() State {
|
||||
return StateServerWaitEOED
|
||||
}
|
||||
|
||||
func (state ServerStateWaitEOED) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state serverStateWaitEOED) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
hm, alert := hr.ReadMessage()
|
||||
if alert != AlertNoAlert {
|
||||
return nil, nil, alert
|
||||
|
@ -798,7 +798,7 @@ func (state ServerStateWaitEOED) Next(hr handshakeMessageReader) (HandshakeState
|
|||
toSend := []HandshakeAction{
|
||||
RekeyIn{epoch: EpochHandshakeData, KeySet: clientHandshakeKeys},
|
||||
}
|
||||
waitFlight2 := ServerStateWaitFlight2{
|
||||
waitFlight2 := serverStateWaitFlight2{
|
||||
Config: state.Config,
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -813,7 +813,7 @@ func (state ServerStateWaitEOED) Next(hr handshakeMessageReader) (HandshakeState
|
|||
return waitFlight2, toSend, AlertNoAlert
|
||||
}
|
||||
|
||||
type ServerStateWaitFlight2 struct {
|
||||
type serverStateWaitFlight2 struct {
|
||||
Config *Config
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
|
@ -826,16 +826,16 @@ type ServerStateWaitFlight2 struct {
|
|||
exporterSecret []byte
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ServerStateWaitFlight2{}
|
||||
var _ HandshakeState = &serverStateWaitFlight2{}
|
||||
|
||||
func (state ServerStateWaitFlight2) State() State {
|
||||
func (state serverStateWaitFlight2) State() State {
|
||||
return StateServerWaitFlight2
|
||||
}
|
||||
|
||||
func (state ServerStateWaitFlight2) Next(_ handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state serverStateWaitFlight2) Next(_ handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
if state.Params.UsingClientAuth {
|
||||
logf(logTypeHandshake, "[ServerStateWaitFlight2] -> [ServerStateWaitCert]")
|
||||
nextState := ServerStateWaitCert{
|
||||
nextState := serverStateWaitCert{
|
||||
Config: state.Config,
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -851,7 +851,7 @@ func (state ServerStateWaitFlight2) Next(_ handshakeMessageReader) (HandshakeSta
|
|||
}
|
||||
|
||||
logf(logTypeHandshake, "[ServerStateWaitFlight2] -> [ServerStateWaitFinished]")
|
||||
nextState := ServerStateWaitFinished{
|
||||
nextState := serverStateWaitFinished{
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
cryptoParams: state.cryptoParams,
|
||||
|
@ -865,7 +865,7 @@ func (state ServerStateWaitFlight2) Next(_ handshakeMessageReader) (HandshakeSta
|
|||
return nextState, nil, AlertNoAlert
|
||||
}
|
||||
|
||||
type ServerStateWaitCert struct {
|
||||
type serverStateWaitCert struct {
|
||||
Config *Config
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
|
@ -878,13 +878,13 @@ type ServerStateWaitCert struct {
|
|||
exporterSecret []byte
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ServerStateWaitCert{}
|
||||
var _ HandshakeState = &serverStateWaitCert{}
|
||||
|
||||
func (state ServerStateWaitCert) State() State {
|
||||
func (state serverStateWaitCert) State() State {
|
||||
return StateServerWaitCert
|
||||
}
|
||||
|
||||
func (state ServerStateWaitCert) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state serverStateWaitCert) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
hm, alert := hr.ReadMessage()
|
||||
if alert != AlertNoAlert {
|
||||
return nil, nil, alert
|
||||
|
@ -906,7 +906,7 @@ func (state ServerStateWaitCert) Next(hr handshakeMessageReader) (HandshakeState
|
|||
logf(logTypeHandshake, "[ServerStateWaitCert] WARNING client did not provide a certificate")
|
||||
|
||||
logf(logTypeHandshake, "[ServerStateWaitCert] -> [ServerStateWaitFinished]")
|
||||
nextState := ServerStateWaitFinished{
|
||||
nextState := serverStateWaitFinished{
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
cryptoParams: state.cryptoParams,
|
||||
|
@ -921,7 +921,7 @@ func (state ServerStateWaitCert) Next(hr handshakeMessageReader) (HandshakeState
|
|||
}
|
||||
|
||||
logf(logTypeHandshake, "[ServerStateWaitCert] -> [ServerStateWaitCV]")
|
||||
nextState := ServerStateWaitCV{
|
||||
nextState := serverStateWaitCV{
|
||||
Config: state.Config,
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
|
@ -937,7 +937,7 @@ func (state ServerStateWaitCert) Next(hr handshakeMessageReader) (HandshakeState
|
|||
return nextState, nil, AlertNoAlert
|
||||
}
|
||||
|
||||
type ServerStateWaitCV struct {
|
||||
type serverStateWaitCV struct {
|
||||
Config *Config
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
|
@ -954,13 +954,13 @@ type ServerStateWaitCV struct {
|
|||
clientCertificate *CertificateBody
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ServerStateWaitCV{}
|
||||
var _ HandshakeState = &serverStateWaitCV{}
|
||||
|
||||
func (state ServerStateWaitCV) State() State {
|
||||
func (state serverStateWaitCV) State() State {
|
||||
return StateServerWaitCV
|
||||
}
|
||||
|
||||
func (state ServerStateWaitCV) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state serverStateWaitCV) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
hm, alert := hr.ReadMessage()
|
||||
if alert != AlertNoAlert {
|
||||
return nil, nil, alert
|
||||
|
@ -1005,7 +1005,7 @@ func (state ServerStateWaitCV) Next(hr handshakeMessageReader) (HandshakeState,
|
|||
state.handshakeHash.Write(hm.Marshal())
|
||||
|
||||
logf(logTypeHandshake, "[ServerStateWaitCV] -> [ServerStateWaitFinished]")
|
||||
nextState := ServerStateWaitFinished{
|
||||
nextState := serverStateWaitFinished{
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
cryptoParams: state.cryptoParams,
|
||||
|
@ -1021,7 +1021,7 @@ func (state ServerStateWaitCV) Next(hr handshakeMessageReader) (HandshakeState,
|
|||
return nextState, nil, AlertNoAlert
|
||||
}
|
||||
|
||||
type ServerStateWaitFinished struct {
|
||||
type serverStateWaitFinished struct {
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
cryptoParams CipherSuiteParams
|
||||
|
@ -1037,13 +1037,13 @@ type ServerStateWaitFinished struct {
|
|||
exporterSecret []byte
|
||||
}
|
||||
|
||||
var _ HandshakeState = &ServerStateWaitFinished{}
|
||||
var _ HandshakeState = &serverStateWaitFinished{}
|
||||
|
||||
func (state ServerStateWaitFinished) State() State {
|
||||
func (state serverStateWaitFinished) State() State {
|
||||
return StateServerWaitFinished
|
||||
}
|
||||
|
||||
func (state ServerStateWaitFinished) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state serverStateWaitFinished) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
hm, alert := hr.ReadMessage()
|
||||
if alert != AlertNoAlert {
|
||||
return nil, nil, alert
|
||||
|
@ -1083,7 +1083,7 @@ func (state ServerStateWaitFinished) Next(hr handshakeMessageReader) (HandshakeS
|
|||
clientTrafficKeys := makeTrafficKeys(state.cryptoParams, state.clientTrafficSecret)
|
||||
|
||||
logf(logTypeHandshake, "[ServerStateWaitFinished] -> [StateConnected]")
|
||||
nextState := StateConnected{
|
||||
nextState := stateConnected{
|
||||
Params: state.Params,
|
||||
hsCtx: state.hsCtx,
|
||||
isClient: false,
|
||||
|
|
|
@ -81,8 +81,8 @@ func (hc *HandshakeContext) SetVersion(version uint16) {
|
|||
}
|
||||
}
|
||||
|
||||
// StateConnected is symmetric between client and server
|
||||
type StateConnected struct {
|
||||
// stateConnected is symmetric between client and server
|
||||
type stateConnected struct {
|
||||
Params ConnectionParameters
|
||||
hsCtx HandshakeContext
|
||||
isClient bool
|
||||
|
@ -95,16 +95,16 @@ type StateConnected struct {
|
|||
verifiedChains [][]*x509.Certificate
|
||||
}
|
||||
|
||||
var _ HandshakeState = &StateConnected{}
|
||||
var _ HandshakeState = &stateConnected{}
|
||||
|
||||
func (state StateConnected) State() State {
|
||||
func (state stateConnected) State() State {
|
||||
if state.isClient {
|
||||
return StateClientConnected
|
||||
}
|
||||
return StateServerConnected
|
||||
}
|
||||
|
||||
func (state *StateConnected) KeyUpdate(request KeyUpdateRequest) ([]HandshakeAction, Alert) {
|
||||
func (state *stateConnected) KeyUpdate(request KeyUpdateRequest) ([]HandshakeAction, Alert) {
|
||||
var trafficKeys keySet
|
||||
if state.isClient {
|
||||
state.clientTrafficSecret = HkdfExpandLabel(state.cryptoParams.Hash, state.clientTrafficSecret,
|
||||
|
@ -130,7 +130,7 @@ func (state *StateConnected) KeyUpdate(request KeyUpdateRequest) ([]HandshakeAct
|
|||
return toSend, AlertNoAlert
|
||||
}
|
||||
|
||||
func (state *StateConnected) NewSessionTicket(length int, lifetime, earlyDataLifetime uint32) ([]HandshakeAction, Alert) {
|
||||
func (state *stateConnected) NewSessionTicket(length int, lifetime, earlyDataLifetime uint32) ([]HandshakeAction, Alert) {
|
||||
tkt, err := NewSessionTicket(length, lifetime)
|
||||
if err != nil {
|
||||
logf(logTypeHandshake, "[StateConnected] Error generating NewSessionTicket: %v", err)
|
||||
|
@ -172,11 +172,11 @@ func (state *StateConnected) NewSessionTicket(length int, lifetime, earlyDataLif
|
|||
}
|
||||
|
||||
// Next does nothing for this state.
|
||||
func (state StateConnected) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state stateConnected) Next(hr handshakeMessageReader) (HandshakeState, []HandshakeAction, Alert) {
|
||||
return state, nil, AlertNoAlert
|
||||
}
|
||||
|
||||
func (state StateConnected) ProcessMessage(hm *HandshakeMessage) (HandshakeState, []HandshakeAction, Alert) {
|
||||
func (state stateConnected) ProcessMessage(hm *HandshakeMessage) (HandshakeState, []HandshakeAction, Alert) {
|
||||
if hm == nil {
|
||||
logf(logTypeHandshake, "[StateConnected] Unexpected message")
|
||||
return nil, nil, AlertUnexpectedMessage
|
||||
|
|
2
vendor/manifest
vendored
2
vendor/manifest
vendored
|
@ -145,7 +145,7 @@
|
|||
"importpath": "github.com/lucas-clemente/quic-go",
|
||||
"repository": "https://github.com/lucas-clemente/quic-go",
|
||||
"vcs": "git",
|
||||
"revision": "d71850eb2ff581620f2f5742b558a97de22c13f6",
|
||||
"revision": "9fa739409e6edddbbd47c8031cb7bb3d1a209cc8",
|
||||
"branch": "master",
|
||||
"notests": true
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue