mirror of
https://github.com/fumiama/terasu-cloudflared.git
synced 2026-06-12 06:00:25 +08:00
TUN-7934: Update quic-go to a version that queues datagrams for better throughput and drops large datagram
Remove TestUnregisterUdpSession
This commit is contained in:
18
vendor/github.com/quic-go/quic-go/.golangci.yml
generated
vendored
18
vendor/github.com/quic-go/quic-go/.golangci.yml
generated
vendored
@@ -3,15 +3,15 @@ run:
|
||||
- internal/handshake/cipher_suite.go
|
||||
linters-settings:
|
||||
depguard:
|
||||
type: blacklist
|
||||
packages:
|
||||
- github.com/marten-seemann/qtls
|
||||
- github.com/quic-go/qtls-go1-19
|
||||
- github.com/quic-go/qtls-go1-20
|
||||
packages-with-error-message:
|
||||
- github.com/marten-seemann/qtls: "importing qtls only allowed in internal/qtls"
|
||||
- github.com/quic-go/qtls-go1-19: "importing qtls only allowed in internal/qtls"
|
||||
- github.com/quic-go/qtls-go1-20: "importing qtls only allowed in internal/qtls"
|
||||
rules:
|
||||
qtls:
|
||||
list-mode: lax
|
||||
files:
|
||||
- "!internal/qtls/**"
|
||||
- "$all"
|
||||
deny:
|
||||
- pkg: github.com/quic-go/qtls-go1-20
|
||||
desc: "importing qtls only allowed in internal/qtls"
|
||||
misspell:
|
||||
ignore-words:
|
||||
- ect
|
||||
|
||||
10
vendor/github.com/quic-go/quic-go/README.md
generated
vendored
10
vendor/github.com/quic-go/quic-go/README.md
generated
vendored
@@ -227,12 +227,13 @@ http.Client{
|
||||
## Projects using quic-go
|
||||
|
||||
| Project | Description | Stars |
|
||||
| --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| [AdGuardHome](https://github.com/AdguardTeam/AdGuardHome) | Free and open source, powerful network-wide ads & trackers blocking DNS server. |  |
|
||||
| [algernon](https://github.com/xyproto/algernon) | Small self-contained pure-Go web server with Lua, Markdown, HTTP/2, QUIC, Redis and PostgreSQL support |  |
|
||||
| [caddy](https://github.com/caddyserver/caddy/) | Fast, multi-platform web server with automatic HTTPS |  |
|
||||
| [cloudflared](https://github.com/cloudflare/cloudflared) | A tunneling daemon that proxies traffic from the Cloudflare network to your origins |  |
|
||||
| [go-libp2p](https://github.com/libp2p/go-libp2p) | libp2p implementation in Go, powering [Kubo](https://github.com/ipfs/kubo) (IPFS) and [Lotus](https://github.com/filecoin-project/lotus) (Filecoin), among others |  |
|
||||
| [go-libp2p](https://github.com/libp2p/go-libp2p) | libp2p implementation in Go, powering [Kubo](https://github.com/ipfs/kubo) (IPFS) and [Lotus](https://github.com/filecoin-project/lotus) (Filecoin), among others |  |
|
||||
| [gost](https://github.com/go-gost/gost) | A simple security tunnel written in Go |  |
|
||||
| [Hysteria](https://github.com/apernet/hysteria) | A powerful, lightning fast and censorship resistant proxy |  |
|
||||
| [Mercure](https://github.com/dunglas/mercure) | An open, easy, fast, reliable and battery-efficient solution for real-time communications |  |
|
||||
| [OONI Probe](https://github.com/ooni/probe-cli) | Next generation OONI Probe. Library and CLI tool. |  |
|
||||
@@ -247,11 +248,6 @@ If you'd like to see your project added to this list, please send us a PR.
|
||||
|
||||
quic-go always aims to support the latest two Go releases.
|
||||
|
||||
### Dependency on forked crypto/tls
|
||||
|
||||
Since the standard library didn't provide any QUIC APIs before the Go 1.21 release, we had to fork crypto/tls to add the required APIs ourselves: [qtls for Go 1.20](https://github.com/quic-go/qtls-go1-20).
|
||||
This had led to a lot of pain in the Go ecosystem, and we're happy that we can rely on Go 1.21 going forward.
|
||||
|
||||
## Contributing
|
||||
|
||||
We are always happy to welcome new contributors! We have a number of self-contained issues that are suitable for first-time contributors, they are tagged with [help wanted](https://github.com/quic-go/quic-go/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). If you have any questions, please feel free to reach out by opening an issue or leaving a comment.
|
||||
|
||||
3
vendor/github.com/quic-go/quic-go/conn_id_generator.go
generated
vendored
3
vendor/github.com/quic-go/quic-go/conn_id_generator.go
generated
vendored
@@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/qerr"
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
"github.com/quic-go/quic-go/internal/wire"
|
||||
)
|
||||
|
||||
@@ -60,7 +59,7 @@ func (m *connIDGenerator) SetMaxActiveConnIDs(limit uint64) error {
|
||||
// transport parameter.
|
||||
// We currently don't send the preferred_address transport parameter,
|
||||
// so we can issue (limit - 1) connection IDs.
|
||||
for i := uint64(len(m.activeSrcConnIDs)); i < utils.Min(limit, protocol.MaxIssuedConnectionIDs); i++ {
|
||||
for i := uint64(len(m.activeSrcConnIDs)); i < min(limit, protocol.MaxIssuedConnectionIDs); i++ {
|
||||
if err := m.issueNewConnID(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
2
vendor/github.com/quic-go/quic-go/conn_id_manager.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/conn_id_manager.go
generated
vendored
@@ -145,7 +145,7 @@ func (h *connIDManager) updateConnectionID() {
|
||||
h.queueControlFrame(&wire.RetireConnectionIDFrame{
|
||||
SequenceNumber: h.activeSequenceNumber,
|
||||
})
|
||||
h.highestRetired = utils.Max(h.highestRetired, h.activeSequenceNumber)
|
||||
h.highestRetired = max(h.highestRetired, h.activeSequenceNumber)
|
||||
if h.activeStatelessResetToken != nil {
|
||||
h.removeStatelessResetToken(*h.activeStatelessResetToken)
|
||||
}
|
||||
|
||||
27
vendor/github.com/quic-go/quic-go/connection.go
generated
vendored
27
vendor/github.com/quic-go/quic-go/connection.go
generated
vendored
@@ -629,7 +629,7 @@ runLoop:
|
||||
sendQueueAvailable = s.sendQueue.Available()
|
||||
continue
|
||||
}
|
||||
if err := s.triggerSending(); err != nil {
|
||||
if err := s.triggerSending(now); err != nil {
|
||||
s.closeLocal(err)
|
||||
}
|
||||
if s.sendQueue.WouldBlock() {
|
||||
@@ -681,7 +681,7 @@ func (s *connection) ConnectionState() ConnectionState {
|
||||
|
||||
// Time when the connection should time out
|
||||
func (s *connection) nextIdleTimeoutTime() time.Time {
|
||||
idleTimeout := utils.Max(s.idleTimeout, s.rttStats.PTO(true)*3)
|
||||
idleTimeout := max(s.idleTimeout, s.rttStats.PTO(true)*3)
|
||||
return s.idleTimeoutStartTime().Add(idleTimeout)
|
||||
}
|
||||
|
||||
@@ -691,7 +691,7 @@ func (s *connection) nextKeepAliveTime() time.Time {
|
||||
if s.config.KeepAlivePeriod == 0 || s.keepAlivePingSent || !s.firstAckElicitingPacketAfterIdleSentTime.IsZero() {
|
||||
return time.Time{}
|
||||
}
|
||||
keepAliveInterval := utils.Max(s.keepAliveInterval, s.rttStats.PTO(true)*3/2)
|
||||
keepAliveInterval := max(s.keepAliveInterval, s.rttStats.PTO(true)*3/2)
|
||||
return s.lastPacketReceivedTime.Add(keepAliveInterval)
|
||||
}
|
||||
|
||||
@@ -731,6 +731,10 @@ func (s *connection) handleHandshakeComplete() error {
|
||||
s.connIDManager.SetHandshakeComplete()
|
||||
s.connIDGenerator.SetHandshakeComplete()
|
||||
|
||||
if s.tracer != nil && s.tracer.ChoseALPN != nil {
|
||||
s.tracer.ChoseALPN(s.cryptoStreamHandler.ConnectionState().NegotiatedProtocol)
|
||||
}
|
||||
|
||||
// The server applies transport parameters right away, but the client side has to wait for handshake completion.
|
||||
// During a 0-RTT connection, the client is only allowed to use the new transport parameters for 1-RTT packets.
|
||||
if s.perspective == protocol.PerspectiveClient {
|
||||
@@ -776,7 +780,7 @@ func (s *connection) handleHandshakeConfirmed() error {
|
||||
if maxPacketSize == 0 {
|
||||
maxPacketSize = protocol.MaxByteCount
|
||||
}
|
||||
s.mtuDiscoverer.Start(utils.Min(maxPacketSize, protocol.MaxPacketBufferSize))
|
||||
s.mtuDiscoverer.Start(min(maxPacketSize, protocol.MaxPacketBufferSize))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1751,7 +1755,7 @@ func (s *connection) applyTransportParameters() {
|
||||
params := s.peerParams
|
||||
// Our local idle timeout will always be > 0.
|
||||
s.idleTimeout = utils.MinNonZeroDuration(s.config.MaxIdleTimeout, params.MaxIdleTimeout)
|
||||
s.keepAliveInterval = utils.Min(s.config.KeepAlivePeriod, utils.Min(s.idleTimeout/2, protocol.MaxKeepAliveInterval))
|
||||
s.keepAliveInterval = min(s.config.KeepAlivePeriod, min(s.idleTimeout/2, protocol.MaxKeepAliveInterval))
|
||||
s.streamsMap.UpdateLimits(params)
|
||||
s.frameParser.SetAckDelayExponent(params.AckDelayExponent)
|
||||
s.connFlowController.UpdateSendWindow(params.InitialMaxData)
|
||||
@@ -1767,9 +1771,8 @@ func (s *connection) applyTransportParameters() {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *connection) triggerSending() error {
|
||||
func (s *connection) triggerSending(now time.Time) error {
|
||||
s.pacingDeadline = time.Time{}
|
||||
now := time.Now()
|
||||
|
||||
sendMode := s.sentPacketHandler.SendMode(now)
|
||||
//nolint:exhaustive // No need to handle pacing limited here.
|
||||
@@ -1801,7 +1804,7 @@ func (s *connection) triggerSending() error {
|
||||
s.scheduleSending()
|
||||
return nil
|
||||
}
|
||||
return s.triggerSending()
|
||||
return s.triggerSending(now)
|
||||
case ackhandler.SendPTOHandshake:
|
||||
if err := s.sendProbePacket(protocol.EncryptionHandshake, now); err != nil {
|
||||
return err
|
||||
@@ -1810,7 +1813,7 @@ func (s *connection) triggerSending() error {
|
||||
s.scheduleSending()
|
||||
return nil
|
||||
}
|
||||
return s.triggerSending()
|
||||
return s.triggerSending(now)
|
||||
case ackhandler.SendPTOAppData:
|
||||
if err := s.sendProbePacket(protocol.Encryption1RTT, now); err != nil {
|
||||
return err
|
||||
@@ -1819,7 +1822,7 @@ func (s *connection) triggerSending() error {
|
||||
s.scheduleSending()
|
||||
return nil
|
||||
}
|
||||
return s.triggerSending()
|
||||
return s.triggerSending(now)
|
||||
default:
|
||||
return fmt.Errorf("BUG: invalid send mode %d", sendMode)
|
||||
}
|
||||
@@ -1988,7 +1991,7 @@ func (s *connection) maybeSendAckOnlyPacket(now time.Time) error {
|
||||
if packet == nil {
|
||||
return nil
|
||||
}
|
||||
return s.sendPackedCoalescedPacket(packet, ecn, time.Now())
|
||||
return s.sendPackedCoalescedPacket(packet, ecn, now)
|
||||
}
|
||||
|
||||
ecn := s.sentPacketHandler.ECNMode(true)
|
||||
@@ -2356,7 +2359,7 @@ func (s *connection) SendDatagram(p []byte) error {
|
||||
}
|
||||
f.Data = make([]byte, len(p))
|
||||
copy(f.Data, p)
|
||||
return s.datagramQueue.AddAndWait(f)
|
||||
return s.datagramQueue.Add(f)
|
||||
}
|
||||
|
||||
func (s *connection) ReceiveDatagram(ctx context.Context) ([]byte, error) {
|
||||
|
||||
5
vendor/github.com/quic-go/quic-go/crypto_stream.go
generated
vendored
5
vendor/github.com/quic-go/quic-go/crypto_stream.go
generated
vendored
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/qerr"
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
"github.com/quic-go/quic-go/internal/wire"
|
||||
)
|
||||
|
||||
@@ -56,7 +55,7 @@ func (s *cryptoStreamImpl) HandleCryptoFrame(f *wire.CryptoFrame) error {
|
||||
// could e.g. be a retransmission
|
||||
return nil
|
||||
}
|
||||
s.highestOffset = utils.Max(s.highestOffset, highestOffset)
|
||||
s.highestOffset = max(s.highestOffset, highestOffset)
|
||||
if err := s.queue.Push(f.Data, f.Offset, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -99,7 +98,7 @@ func (s *cryptoStreamImpl) HasData() bool {
|
||||
|
||||
func (s *cryptoStreamImpl) PopCryptoFrame(maxLen protocol.ByteCount) *wire.CryptoFrame {
|
||||
f := &wire.CryptoFrame{Offset: s.writeOffset}
|
||||
n := utils.Min(f.MaxDataLen(maxLen), protocol.ByteCount(len(s.writeBuf)))
|
||||
n := min(f.MaxDataLen(maxLen), protocol.ByteCount(len(s.writeBuf)))
|
||||
f.Data = s.writeBuf[:n]
|
||||
s.writeBuf = s.writeBuf[n:]
|
||||
s.writeOffset += n
|
||||
|
||||
87
vendor/github.com/quic-go/quic-go/datagram_queue.go
generated
vendored
87
vendor/github.com/quic-go/quic-go/datagram_queue.go
generated
vendored
@@ -4,14 +4,20 @@ import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
"github.com/quic-go/quic-go/internal/utils/ringbuffer"
|
||||
"github.com/quic-go/quic-go/internal/wire"
|
||||
)
|
||||
|
||||
const (
|
||||
maxDatagramSendQueueLen = 32
|
||||
maxDatagramRcvQueueLen = 128
|
||||
)
|
||||
|
||||
type datagramQueue struct {
|
||||
sendQueue chan *wire.DatagramFrame
|
||||
nextFrame *wire.DatagramFrame
|
||||
sendMx sync.Mutex
|
||||
sendQueue ringbuffer.RingBuffer[*wire.DatagramFrame]
|
||||
sent chan struct{} // used to notify Add that a datagram was dequeued
|
||||
|
||||
rcvMx sync.Mutex
|
||||
rcvQueue [][]byte
|
||||
@@ -22,60 +28,65 @@ type datagramQueue struct {
|
||||
|
||||
hasData func()
|
||||
|
||||
dequeued chan struct{}
|
||||
|
||||
logger utils.Logger
|
||||
}
|
||||
|
||||
func newDatagramQueue(hasData func(), logger utils.Logger) *datagramQueue {
|
||||
return &datagramQueue{
|
||||
hasData: hasData,
|
||||
sendQueue: make(chan *wire.DatagramFrame, 1),
|
||||
rcvd: make(chan struct{}, 1),
|
||||
dequeued: make(chan struct{}),
|
||||
closed: make(chan struct{}),
|
||||
logger: logger,
|
||||
hasData: hasData,
|
||||
rcvd: make(chan struct{}, 1),
|
||||
sent: make(chan struct{}, 1),
|
||||
closed: make(chan struct{}),
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// AddAndWait queues a new DATAGRAM frame for sending.
|
||||
// It blocks until the frame has been dequeued.
|
||||
func (h *datagramQueue) AddAndWait(f *wire.DatagramFrame) error {
|
||||
select {
|
||||
case h.sendQueue <- f:
|
||||
h.hasData()
|
||||
case <-h.closed:
|
||||
return h.closeErr
|
||||
}
|
||||
// Add queues a new DATAGRAM frame for sending.
|
||||
// Up to 32 DATAGRAM frames will be queued.
|
||||
// Once that limit is reached, Add blocks until the queue size has reduced.
|
||||
func (h *datagramQueue) Add(f *wire.DatagramFrame) error {
|
||||
h.sendMx.Lock()
|
||||
|
||||
select {
|
||||
case <-h.dequeued:
|
||||
return nil
|
||||
case <-h.closed:
|
||||
return h.closeErr
|
||||
for {
|
||||
if h.sendQueue.Len() < maxDatagramSendQueueLen {
|
||||
h.sendQueue.PushBack(f)
|
||||
h.sendMx.Unlock()
|
||||
h.hasData()
|
||||
return nil
|
||||
}
|
||||
select {
|
||||
case <-h.sent: // drain the queue so we don't loop immediately
|
||||
default:
|
||||
}
|
||||
h.sendMx.Unlock()
|
||||
select {
|
||||
case <-h.closed:
|
||||
return h.closeErr
|
||||
case <-h.sent:
|
||||
}
|
||||
h.sendMx.Lock()
|
||||
}
|
||||
}
|
||||
|
||||
// Peek gets the next DATAGRAM frame for sending.
|
||||
// If actually sent out, Pop needs to be called before the next call to Peek.
|
||||
func (h *datagramQueue) Peek() *wire.DatagramFrame {
|
||||
if h.nextFrame != nil {
|
||||
return h.nextFrame
|
||||
}
|
||||
select {
|
||||
case h.nextFrame = <-h.sendQueue:
|
||||
h.dequeued <- struct{}{}
|
||||
default:
|
||||
h.sendMx.Lock()
|
||||
defer h.sendMx.Unlock()
|
||||
if h.sendQueue.Empty() {
|
||||
return nil
|
||||
}
|
||||
return h.nextFrame
|
||||
return h.sendQueue.PeekFront()
|
||||
}
|
||||
|
||||
func (h *datagramQueue) Pop() {
|
||||
if h.nextFrame == nil {
|
||||
panic("datagramQueue BUG: Pop called for nil frame")
|
||||
h.sendMx.Lock()
|
||||
defer h.sendMx.Unlock()
|
||||
_ = h.sendQueue.PopFront()
|
||||
select {
|
||||
case h.sent <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
h.nextFrame = nil
|
||||
}
|
||||
|
||||
// HandleDatagramFrame handles a received DATAGRAM frame.
|
||||
@@ -84,7 +95,7 @@ func (h *datagramQueue) HandleDatagramFrame(f *wire.DatagramFrame) {
|
||||
copy(data, f.Data)
|
||||
var queued bool
|
||||
h.rcvMx.Lock()
|
||||
if len(h.rcvQueue) < protocol.DatagramRcvQueueLen {
|
||||
if len(h.rcvQueue) < maxDatagramRcvQueueLen {
|
||||
h.rcvQueue = append(h.rcvQueue, data)
|
||||
queued = true
|
||||
select {
|
||||
@@ -94,7 +105,7 @@ func (h *datagramQueue) HandleDatagramFrame(f *wire.DatagramFrame) {
|
||||
}
|
||||
h.rcvMx.Unlock()
|
||||
if !queued && h.logger.Debug() {
|
||||
h.logger.Debugf("Discarding DATAGRAM frame (%d bytes payload)", len(f.Data))
|
||||
h.logger.Debugf("Discarding received DATAGRAM frame (%d bytes payload)", len(f.Data))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
37
vendor/github.com/quic-go/quic-go/framer.go
generated
vendored
37
vendor/github.com/quic-go/quic-go/framer.go
generated
vendored
@@ -23,6 +23,8 @@ type framer interface {
|
||||
Handle0RTTRejection() error
|
||||
}
|
||||
|
||||
const maxPathResponses = 256
|
||||
|
||||
type framerI struct {
|
||||
mutex sync.Mutex
|
||||
|
||||
@@ -33,6 +35,7 @@ type framerI struct {
|
||||
|
||||
controlFrameMutex sync.Mutex
|
||||
controlFrames []wire.Frame
|
||||
pathResponses []*wire.PathResponseFrame
|
||||
}
|
||||
|
||||
var _ framer = &framerI{}
|
||||
@@ -52,20 +55,43 @@ func (f *framerI) HasData() bool {
|
||||
return true
|
||||
}
|
||||
f.controlFrameMutex.Lock()
|
||||
hasData = len(f.controlFrames) > 0
|
||||
f.controlFrameMutex.Unlock()
|
||||
return hasData
|
||||
defer f.controlFrameMutex.Unlock()
|
||||
return len(f.controlFrames) > 0 || len(f.pathResponses) > 0
|
||||
}
|
||||
|
||||
func (f *framerI) QueueControlFrame(frame wire.Frame) {
|
||||
f.controlFrameMutex.Lock()
|
||||
defer f.controlFrameMutex.Unlock()
|
||||
|
||||
if pr, ok := frame.(*wire.PathResponseFrame); ok {
|
||||
// Only queue up to maxPathResponses PATH_RESPONSE frames.
|
||||
// This limit should be high enough to never be hit in practice,
|
||||
// unless the peer is doing something malicious.
|
||||
if len(f.pathResponses) >= maxPathResponses {
|
||||
return
|
||||
}
|
||||
f.pathResponses = append(f.pathResponses, pr)
|
||||
return
|
||||
}
|
||||
f.controlFrames = append(f.controlFrames, frame)
|
||||
f.controlFrameMutex.Unlock()
|
||||
}
|
||||
|
||||
func (f *framerI) AppendControlFrames(frames []ackhandler.Frame, maxLen protocol.ByteCount, v protocol.VersionNumber) ([]ackhandler.Frame, protocol.ByteCount) {
|
||||
var length protocol.ByteCount
|
||||
f.controlFrameMutex.Lock()
|
||||
defer f.controlFrameMutex.Unlock()
|
||||
|
||||
var length protocol.ByteCount
|
||||
// add a PATH_RESPONSE first, but only pack a single PATH_RESPONSE per packet
|
||||
if len(f.pathResponses) > 0 {
|
||||
frame := f.pathResponses[0]
|
||||
frameLen := frame.Length(v)
|
||||
if frameLen <= maxLen {
|
||||
frames = append(frames, ackhandler.Frame{Frame: frame})
|
||||
length += frameLen
|
||||
f.pathResponses = f.pathResponses[1:]
|
||||
}
|
||||
}
|
||||
|
||||
for len(f.controlFrames) > 0 {
|
||||
frame := f.controlFrames[len(f.controlFrames)-1]
|
||||
frameLen := frame.Length(v)
|
||||
@@ -76,7 +102,6 @@ func (f *framerI) AppendControlFrames(frames []ackhandler.Frame, maxLen protocol
|
||||
length += frameLen
|
||||
f.controlFrames = f.controlFrames[:len(f.controlFrames)-1]
|
||||
}
|
||||
f.controlFrameMutex.Unlock()
|
||||
return frames, length
|
||||
}
|
||||
|
||||
|
||||
8
vendor/github.com/quic-go/quic-go/interface.go
generated
vendored
8
vendor/github.com/quic-go/quic-go/interface.go
generated
vendored
@@ -187,8 +187,12 @@ type Connection interface {
|
||||
// Warning: This API should not be considered stable and might change soon.
|
||||
ConnectionState() ConnectionState
|
||||
|
||||
// SendDatagram sends a message as a datagram, as specified in RFC 9221.
|
||||
SendDatagram([]byte) error
|
||||
// SendDatagram sends a message using a QUIC datagram, as specified in RFC 9221.
|
||||
// There is no delivery guarantee for DATAGRAM frames, they are not retransmitted if lost.
|
||||
// The payload of the datagram needs to fit into a single QUIC packet.
|
||||
// In addition, a datagram may be dropped before being sent out if the available packet size suddenly decreases.
|
||||
// If the payload is too large to be sent at the current time, a DatagramTooLargeError is returned.
|
||||
SendDatagram(payload []byte) error
|
||||
// ReceiveDatagram gets a message received in a datagram, as specified in RFC 9221.
|
||||
ReceiveDatagram(context.Context) ([]byte, error)
|
||||
}
|
||||
|
||||
2
vendor/github.com/quic-go/quic-go/internal/ackhandler/packet_number_generator.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/internal/ackhandler/packet_number_generator.go
generated
vendored
@@ -80,5 +80,5 @@ func (p *skippingPacketNumberGenerator) Pop() (bool, protocol.PacketNumber) {
|
||||
func (p *skippingPacketNumberGenerator) generateNewSkip() {
|
||||
// make sure that there are never two consecutive packet numbers that are skipped
|
||||
p.nextToSkip = p.next + 3 + protocol.PacketNumber(p.rng.Int31n(int32(2*p.period)))
|
||||
p.period = utils.Min(2*p.period, p.maxPeriod)
|
||||
p.period = min(2*p.period, p.maxPeriod)
|
||||
}
|
||||
|
||||
2
vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_tracker.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_tracker.go
generated
vendored
@@ -179,7 +179,7 @@ func (h *receivedPacketTracker) GetAckFrame(onlyIfQueued bool) *wire.AckFrame {
|
||||
ack = &wire.AckFrame{}
|
||||
}
|
||||
ack.Reset()
|
||||
ack.DelayTime = utils.Max(0, now.Sub(h.largestObservedRcvdTime))
|
||||
ack.DelayTime = max(0, now.Sub(h.largestObservedRcvdTime))
|
||||
ack.ECT0 = h.ect0
|
||||
ack.ECT1 = h.ect1
|
||||
ack.ECNCE = h.ecnce
|
||||
|
||||
14
vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_handler.go
generated
vendored
14
vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_handler.go
generated
vendored
@@ -245,7 +245,7 @@ func (h *sentPacketHandler) SentPacket(
|
||||
|
||||
pnSpace := h.getPacketNumberSpace(encLevel)
|
||||
if h.logger.Debug() && pnSpace.history.HasOutstandingPackets() {
|
||||
for p := utils.Max(0, pnSpace.largestSent+1); p < pn; p++ {
|
||||
for p := max(0, pnSpace.largestSent+1); p < pn; p++ {
|
||||
h.logger.Debugf("Skipping packet number %d", p)
|
||||
}
|
||||
}
|
||||
@@ -336,7 +336,7 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En
|
||||
// don't use the ack delay for Initial and Handshake packets
|
||||
var ackDelay time.Duration
|
||||
if encLevel == protocol.Encryption1RTT {
|
||||
ackDelay = utils.Min(ack.DelayTime, h.rttStats.MaxAckDelay())
|
||||
ackDelay = min(ack.DelayTime, h.rttStats.MaxAckDelay())
|
||||
}
|
||||
h.rttStats.UpdateRTT(rcvTime.Sub(p.SendTime), ackDelay, rcvTime)
|
||||
if h.logger.Debug() {
|
||||
@@ -354,7 +354,7 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En
|
||||
}
|
||||
}
|
||||
|
||||
pnSpace.largestAcked = utils.Max(pnSpace.largestAcked, largestAcked)
|
||||
pnSpace.largestAcked = max(pnSpace.largestAcked, largestAcked)
|
||||
|
||||
if err := h.detectLostPackets(rcvTime, encLevel); err != nil {
|
||||
return false, err
|
||||
@@ -446,7 +446,7 @@ func (h *sentPacketHandler) detectAndRemoveAckedPackets(ack *wire.AckFrame, encL
|
||||
|
||||
for _, p := range h.ackedPackets {
|
||||
if p.LargestAcked != protocol.InvalidPacketNumber && encLevel == protocol.Encryption1RTT {
|
||||
h.lowestNotConfirmedAcked = utils.Max(h.lowestNotConfirmedAcked, p.LargestAcked+1)
|
||||
h.lowestNotConfirmedAcked = max(h.lowestNotConfirmedAcked, p.LargestAcked+1)
|
||||
}
|
||||
|
||||
for _, f := range p.Frames {
|
||||
@@ -607,11 +607,11 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E
|
||||
pnSpace := h.getPacketNumberSpace(encLevel)
|
||||
pnSpace.lossTime = time.Time{}
|
||||
|
||||
maxRTT := float64(utils.Max(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT()))
|
||||
maxRTT := float64(max(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT()))
|
||||
lossDelay := time.Duration(timeThreshold * maxRTT)
|
||||
|
||||
// Minimum time of granularity before packets are deemed lost.
|
||||
lossDelay = utils.Max(lossDelay, protocol.TimerGranularity)
|
||||
lossDelay = max(lossDelay, protocol.TimerGranularity)
|
||||
|
||||
// Packets sent before this time are deemed lost.
|
||||
lostSendTime := now.Add(-lossDelay)
|
||||
@@ -890,7 +890,7 @@ func (h *sentPacketHandler) ResetForRetry(now time.Time) error {
|
||||
// Otherwise, we don't know which Initial the Retry was sent in response to.
|
||||
if h.ptoCount == 0 {
|
||||
// Don't set the RTT to a value lower than 5ms here.
|
||||
h.rttStats.UpdateRTT(utils.Max(minRTTAfterRetry, now.Sub(firstPacketSendTime)), 0, now)
|
||||
h.rttStats.UpdateRTT(max(minRTTAfterRetry, now.Sub(firstPacketSendTime)), 0, now)
|
||||
if h.logger.Debug() {
|
||||
h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation())
|
||||
}
|
||||
|
||||
3
vendor/github.com/quic-go/quic-go/internal/congestion/cubic.go
generated
vendored
3
vendor/github.com/quic-go/quic-go/internal/congestion/cubic.go
generated
vendored
@@ -5,7 +5,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
)
|
||||
|
||||
// This cubic implementation is based on the one found in Chromiums's QUIC
|
||||
@@ -187,7 +186,7 @@ func (c *Cubic) CongestionWindowAfterAck(
|
||||
targetCongestionWindow = c.originPointCongestionWindow - deltaCongestionWindow
|
||||
}
|
||||
// Limit the CWND increase to half the acked bytes.
|
||||
targetCongestionWindow = utils.Min(targetCongestionWindow, currentCongestionWindow+c.ackedBytesCount/2)
|
||||
targetCongestionWindow = min(targetCongestionWindow, currentCongestionWindow+c.ackedBytesCount/2)
|
||||
|
||||
// Increase the window by approximately Alpha * 1 MSS of bytes every
|
||||
// time we ack an estimated tcp window of bytes. For small
|
||||
|
||||
4
vendor/github.com/quic-go/quic-go/internal/congestion/cubic_sender.go
generated
vendored
4
vendor/github.com/quic-go/quic-go/internal/congestion/cubic_sender.go
generated
vendored
@@ -178,7 +178,7 @@ func (c *cubicSender) OnPacketAcked(
|
||||
priorInFlight protocol.ByteCount,
|
||||
eventTime time.Time,
|
||||
) {
|
||||
c.largestAckedPacketNumber = utils.Max(ackedPacketNumber, c.largestAckedPacketNumber)
|
||||
c.largestAckedPacketNumber = max(ackedPacketNumber, c.largestAckedPacketNumber)
|
||||
if c.InRecovery() {
|
||||
return
|
||||
}
|
||||
@@ -246,7 +246,7 @@ func (c *cubicSender) maybeIncreaseCwnd(
|
||||
c.numAckedPackets = 0
|
||||
}
|
||||
} else {
|
||||
c.congestionWindow = utils.Min(c.maxCongestionWindow(), c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime))
|
||||
c.congestionWindow = min(c.maxCongestionWindow(), c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
5
vendor/github.com/quic-go/quic-go/internal/congestion/hybrid_slow_start.go
generated
vendored
5
vendor/github.com/quic-go/quic-go/internal/congestion/hybrid_slow_start.go
generated
vendored
@@ -4,7 +4,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
)
|
||||
|
||||
// Note(pwestin): the magic clamping numbers come from the original code in
|
||||
@@ -75,8 +74,8 @@ func (s *HybridSlowStart) ShouldExitSlowStart(latestRTT time.Duration, minRTT ti
|
||||
// Divide minRTT by 8 to get a rtt increase threshold for exiting.
|
||||
minRTTincreaseThresholdUs := int64(minRTT / time.Microsecond >> hybridStartDelayFactorExp)
|
||||
// Ensure the rtt threshold is never less than 2ms or more than 16ms.
|
||||
minRTTincreaseThresholdUs = utils.Min(minRTTincreaseThresholdUs, hybridStartDelayMaxThresholdUs)
|
||||
minRTTincreaseThreshold := time.Duration(utils.Max(minRTTincreaseThresholdUs, hybridStartDelayMinThresholdUs)) * time.Microsecond
|
||||
minRTTincreaseThresholdUs = min(minRTTincreaseThresholdUs, hybridStartDelayMaxThresholdUs)
|
||||
minRTTincreaseThreshold := time.Duration(max(minRTTincreaseThresholdUs, hybridStartDelayMinThresholdUs)) * time.Microsecond
|
||||
|
||||
if s.currentMinRTT > (minRTT + minRTTincreaseThreshold) {
|
||||
s.hystartFound = true
|
||||
|
||||
7
vendor/github.com/quic-go/quic-go/internal/congestion/pacer.go
generated
vendored
7
vendor/github.com/quic-go/quic-go/internal/congestion/pacer.go
generated
vendored
@@ -4,7 +4,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
)
|
||||
|
||||
const maxBurstSizePackets = 10
|
||||
@@ -52,11 +51,11 @@ func (p *pacer) Budget(now time.Time) protocol.ByteCount {
|
||||
if budget < 0 { // protect against overflows
|
||||
budget = protocol.MaxByteCount
|
||||
}
|
||||
return utils.Min(p.maxBurstSize(), budget)
|
||||
return min(p.maxBurstSize(), budget)
|
||||
}
|
||||
|
||||
func (p *pacer) maxBurstSize() protocol.ByteCount {
|
||||
return utils.Max(
|
||||
return max(
|
||||
protocol.ByteCount(uint64((protocol.MinPacingDelay+protocol.TimerGranularity).Nanoseconds())*p.adjustedBandwidth())/1e9,
|
||||
maxBurstSizePackets*p.maxDatagramSize,
|
||||
)
|
||||
@@ -77,7 +76,7 @@ func (p *pacer) TimeUntilSend() time.Time {
|
||||
if diff%bw > 0 {
|
||||
d++
|
||||
}
|
||||
return p.lastSentTime.Add(utils.Max(protocol.MinPacingDelay, time.Duration(d)*time.Nanosecond))
|
||||
return p.lastSentTime.Add(max(protocol.MinPacingDelay, time.Duration(d)*time.Nanosecond))
|
||||
}
|
||||
|
||||
func (p *pacer) SetMaxDatagramSize(s protocol.ByteCount) {
|
||||
|
||||
2
vendor/github.com/quic-go/quic-go/internal/flowcontrol/base_flow_controller.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/internal/flowcontrol/base_flow_controller.go
generated
vendored
@@ -107,7 +107,7 @@ func (c *baseFlowController) maybeAdjustWindowSize() {
|
||||
now := time.Now()
|
||||
if now.Sub(c.epochStartTime) < time.Duration(4*fraction*float64(rtt)) {
|
||||
// window is consumed too fast, try to increase the window size
|
||||
newSize := utils.Min(2*c.receiveWindowSize, c.maxReceiveWindowSize)
|
||||
newSize := min(2*c.receiveWindowSize, c.maxReceiveWindowSize)
|
||||
if newSize > c.receiveWindowSize && (c.allowWindowIncrease == nil || c.allowWindowIncrease(newSize-c.receiveWindowSize)) {
|
||||
c.receiveWindowSize = newSize
|
||||
}
|
||||
|
||||
2
vendor/github.com/quic-go/quic-go/internal/flowcontrol/connection_flow_controller.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/internal/flowcontrol/connection_flow_controller.go
generated
vendored
@@ -87,7 +87,7 @@ func (c *connectionFlowController) EnsureMinimumWindowSize(inc protocol.ByteCoun
|
||||
c.mutex.Lock()
|
||||
if inc > c.receiveWindowSize {
|
||||
c.logger.Debugf("Increasing receive flow control window for the connection to %d kB, in response to stream flow control window increase", c.receiveWindowSize/(1<<10))
|
||||
newSize := utils.Min(inc, c.maxReceiveWindowSize)
|
||||
newSize := min(inc, c.maxReceiveWindowSize)
|
||||
if delta := newSize - c.receiveWindowSize; delta > 0 && c.allowWindowIncrease(delta) {
|
||||
c.receiveWindowSize = newSize
|
||||
}
|
||||
|
||||
2
vendor/github.com/quic-go/quic-go/internal/flowcontrol/stream_flow_controller.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/internal/flowcontrol/stream_flow_controller.go
generated
vendored
@@ -123,7 +123,7 @@ func (c *streamFlowController) AddBytesSent(n protocol.ByteCount) {
|
||||
}
|
||||
|
||||
func (c *streamFlowController) SendWindowSize() protocol.ByteCount {
|
||||
return utils.Min(c.baseFlowController.sendWindowSize(), c.connection.SendWindowSize())
|
||||
return min(c.baseFlowController.sendWindowSize(), c.connection.SendWindowSize())
|
||||
}
|
||||
|
||||
func (c *streamFlowController) shouldQueueWindowUpdate() bool {
|
||||
|
||||
3
vendor/github.com/quic-go/quic-go/internal/handshake/aead.go
generated
vendored
3
vendor/github.com/quic-go/quic-go/internal/handshake/aead.go
generated
vendored
@@ -5,7 +5,6 @@ import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
)
|
||||
|
||||
func createAEAD(suite *cipherSuite, trafficSecret []byte, v protocol.VersionNumber) cipher.AEAD {
|
||||
@@ -82,7 +81,7 @@ func (o *longHeaderOpener) Open(dst, src []byte, pn protocol.PacketNumber, ad []
|
||||
// It uses the nonce provided here and XOR it with the IV.
|
||||
dec, err := o.aead.Open(dst, o.nonceBuf, src, ad)
|
||||
if err == nil {
|
||||
o.highestRcvdPN = utils.Max(o.highestRcvdPN, pn)
|
||||
o.highestRcvdPN = max(o.highestRcvdPN, pn)
|
||||
} else {
|
||||
err = ErrDecryptionFailed
|
||||
}
|
||||
|
||||
100
vendor/github.com/quic-go/quic-go/internal/handshake/crypto_setup.go
generated
vendored
100
vendor/github.com/quic-go/quic-go/internal/handshake/crypto_setup.go
generated
vendored
@@ -25,11 +25,11 @@ type quicVersionContextKey struct{}
|
||||
|
||||
var QUICVersionContextKey = &quicVersionContextKey{}
|
||||
|
||||
const clientSessionStateRevision = 3
|
||||
const clientSessionStateRevision = 4
|
||||
|
||||
type cryptoSetup struct {
|
||||
tlsConf *tls.Config
|
||||
conn *qtls.QUICConn
|
||||
conn *tls.QUICConn
|
||||
|
||||
events []Event
|
||||
|
||||
@@ -93,12 +93,12 @@ func NewCryptoSetupClient(
|
||||
|
||||
tlsConf = tlsConf.Clone()
|
||||
tlsConf.MinVersion = tls.VersionTLS13
|
||||
quicConf := &qtls.QUICConfig{TLSConfig: tlsConf}
|
||||
quicConf := &tls.QUICConfig{TLSConfig: tlsConf}
|
||||
qtls.SetupConfigForClient(quicConf, cs.marshalDataForSessionState, cs.handleDataFromSessionState)
|
||||
cs.tlsConf = tlsConf
|
||||
cs.allow0RTT = enable0RTT
|
||||
|
||||
cs.conn = qtls.QUICClient(quicConf)
|
||||
cs.conn = tls.QUICClient(quicConf)
|
||||
cs.conn.SetTransportParameters(cs.ourParams.Marshal(protocol.PerspectiveClient))
|
||||
|
||||
return cs
|
||||
@@ -127,12 +127,12 @@ func NewCryptoSetupServer(
|
||||
)
|
||||
cs.allow0RTT = allow0RTT
|
||||
|
||||
quicConf := &qtls.QUICConfig{TLSConfig: tlsConf}
|
||||
quicConf := &tls.QUICConfig{TLSConfig: tlsConf}
|
||||
qtls.SetupConfigForServer(quicConf, cs.allow0RTT, cs.getDataForSessionTicket, cs.handleSessionTicket)
|
||||
addConnToClientHelloInfo(quicConf.TLSConfig, localAddr, remoteAddr)
|
||||
|
||||
cs.tlsConf = quicConf.TLSConfig
|
||||
cs.conn = qtls.QUICServer(quicConf)
|
||||
cs.conn = tls.QUICServer(quicConf)
|
||||
|
||||
return cs
|
||||
}
|
||||
@@ -264,28 +264,28 @@ func (h *cryptoSetup) handleMessage(data []byte, encLevel protocol.EncryptionLev
|
||||
}
|
||||
}
|
||||
|
||||
func (h *cryptoSetup) handleEvent(ev qtls.QUICEvent) (done bool, err error) {
|
||||
func (h *cryptoSetup) handleEvent(ev tls.QUICEvent) (done bool, err error) {
|
||||
switch ev.Kind {
|
||||
case qtls.QUICNoEvent:
|
||||
case tls.QUICNoEvent:
|
||||
return true, nil
|
||||
case qtls.QUICSetReadSecret:
|
||||
case tls.QUICSetReadSecret:
|
||||
h.SetReadKey(ev.Level, ev.Suite, ev.Data)
|
||||
return false, nil
|
||||
case qtls.QUICSetWriteSecret:
|
||||
case tls.QUICSetWriteSecret:
|
||||
h.SetWriteKey(ev.Level, ev.Suite, ev.Data)
|
||||
return false, nil
|
||||
case qtls.QUICTransportParameters:
|
||||
case tls.QUICTransportParameters:
|
||||
return false, h.handleTransportParameters(ev.Data)
|
||||
case qtls.QUICTransportParametersRequired:
|
||||
case tls.QUICTransportParametersRequired:
|
||||
h.conn.SetTransportParameters(h.ourParams.Marshal(h.perspective))
|
||||
return false, nil
|
||||
case qtls.QUICRejectedEarlyData:
|
||||
case tls.QUICRejectedEarlyData:
|
||||
h.rejected0RTT()
|
||||
return false, nil
|
||||
case qtls.QUICWriteData:
|
||||
h.WriteRecord(ev.Level, ev.Data)
|
||||
case tls.QUICWriteData:
|
||||
h.writeRecord(ev.Level, ev.Data)
|
||||
return false, nil
|
||||
case qtls.QUICHandshakeDone:
|
||||
case tls.QUICHandshakeDone:
|
||||
h.handshakeComplete()
|
||||
return false, nil
|
||||
default:
|
||||
@@ -313,19 +313,24 @@ func (h *cryptoSetup) handleTransportParameters(data []byte) error {
|
||||
}
|
||||
|
||||
// must be called after receiving the transport parameters
|
||||
func (h *cryptoSetup) marshalDataForSessionState() []byte {
|
||||
func (h *cryptoSetup) marshalDataForSessionState(earlyData bool) []byte {
|
||||
b := make([]byte, 0, 256)
|
||||
b = quicvarint.Append(b, clientSessionStateRevision)
|
||||
b = quicvarint.Append(b, uint64(h.rttStats.SmoothedRTT().Microseconds()))
|
||||
return h.peerParams.MarshalForSessionTicket(b)
|
||||
if earlyData {
|
||||
// only save the transport parameters for 0-RTT enabled session tickets
|
||||
return h.peerParams.MarshalForSessionTicket(b)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (h *cryptoSetup) handleDataFromSessionState(data []byte) (allowEarlyData bool) {
|
||||
tp, err := h.handleDataFromSessionStateImpl(data)
|
||||
func (h *cryptoSetup) handleDataFromSessionState(data []byte, earlyData bool) (allowEarlyData bool) {
|
||||
rtt, tp, err := decodeDataFromSessionState(data, earlyData)
|
||||
if err != nil {
|
||||
h.logger.Debugf("Restoring of transport parameters from session ticket failed: %s", err.Error())
|
||||
return
|
||||
}
|
||||
h.rttStats.SetInitialRTT(rtt)
|
||||
// The session ticket might have been saved from a connection that allowed 0-RTT,
|
||||
// and therefore contain transport parameters.
|
||||
// Only use them if 0-RTT is actually used on the new connection.
|
||||
@@ -336,25 +341,28 @@ func (h *cryptoSetup) handleDataFromSessionState(data []byte) (allowEarlyData bo
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *cryptoSetup) handleDataFromSessionStateImpl(data []byte) (*wire.TransportParameters, error) {
|
||||
func decodeDataFromSessionState(data []byte, earlyData bool) (time.Duration, *wire.TransportParameters, error) {
|
||||
r := bytes.NewReader(data)
|
||||
ver, err := quicvarint.Read(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return 0, nil, err
|
||||
}
|
||||
if ver != clientSessionStateRevision {
|
||||
return nil, fmt.Errorf("mismatching version. Got %d, expected %d", ver, clientSessionStateRevision)
|
||||
return 0, nil, fmt.Errorf("mismatching version. Got %d, expected %d", ver, clientSessionStateRevision)
|
||||
}
|
||||
rtt, err := quicvarint.Read(r)
|
||||
rttEncoded, err := quicvarint.Read(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return 0, nil, err
|
||||
}
|
||||
rtt := time.Duration(rttEncoded) * time.Microsecond
|
||||
if !earlyData {
|
||||
return rtt, nil, nil
|
||||
}
|
||||
h.rttStats.SetInitialRTT(time.Duration(rtt) * time.Microsecond)
|
||||
var tp wire.TransportParameters
|
||||
if err := tp.UnmarshalFromSessionTicket(r); err != nil {
|
||||
return nil, err
|
||||
return 0, nil, err
|
||||
}
|
||||
return &tp, nil
|
||||
return rtt, &tp, nil
|
||||
}
|
||||
|
||||
func (h *cryptoSetup) getDataForSessionTicket() []byte {
|
||||
@@ -371,7 +379,9 @@ func (h *cryptoSetup) getDataForSessionTicket() []byte {
|
||||
// Due to limitations in crypto/tls, it's only possible to generate a single session ticket per connection.
|
||||
// It is only valid for the server.
|
||||
func (h *cryptoSetup) GetSessionTicket() ([]byte, error) {
|
||||
if err := qtls.SendSessionTicket(h.conn, h.allow0RTT); err != nil {
|
||||
if err := h.conn.SendSessionTicket(tls.QUICSessionTicketOptions{
|
||||
EarlyData: h.allow0RTT,
|
||||
}); err != nil {
|
||||
// Session tickets might be disabled by tls.Config.SessionTicketsDisabled.
|
||||
// We can't check h.tlsConfig here, since the actual config might have been obtained from
|
||||
// the GetConfigForClient callback.
|
||||
@@ -383,11 +393,11 @@ func (h *cryptoSetup) GetSessionTicket() ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
ev := h.conn.NextEvent()
|
||||
if ev.Kind != qtls.QUICWriteData || ev.Level != qtls.QUICEncryptionLevelApplication {
|
||||
if ev.Kind != tls.QUICWriteData || ev.Level != tls.QUICEncryptionLevelApplication {
|
||||
panic("crypto/tls bug: where's my session ticket?")
|
||||
}
|
||||
ticket := ev.Data
|
||||
if ev := h.conn.NextEvent(); ev.Kind != qtls.QUICNoEvent {
|
||||
if ev := h.conn.NextEvent(); ev.Kind != tls.QUICNoEvent {
|
||||
panic("crypto/tls bug: why more than one ticket?")
|
||||
}
|
||||
return ticket, nil
|
||||
@@ -434,12 +444,12 @@ func (h *cryptoSetup) rejected0RTT() {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *cryptoSetup) SetReadKey(el qtls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) {
|
||||
func (h *cryptoSetup) SetReadKey(el tls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) {
|
||||
suite := getCipherSuite(suiteID)
|
||||
h.mutex.Lock()
|
||||
//nolint:exhaustive // The TLS stack doesn't export Initial keys.
|
||||
switch el {
|
||||
case qtls.QUICEncryptionLevelEarly:
|
||||
case tls.QUICEncryptionLevelEarly:
|
||||
if h.perspective == protocol.PerspectiveClient {
|
||||
panic("Received 0-RTT read key for the client")
|
||||
}
|
||||
@@ -451,7 +461,7 @@ func (h *cryptoSetup) SetReadKey(el qtls.QUICEncryptionLevel, suiteID uint16, tr
|
||||
if h.logger.Debug() {
|
||||
h.logger.Debugf("Installed 0-RTT Read keys (using %s)", tls.CipherSuiteName(suite.ID))
|
||||
}
|
||||
case qtls.QUICEncryptionLevelHandshake:
|
||||
case tls.QUICEncryptionLevelHandshake:
|
||||
h.handshakeOpener = newLongHeaderOpener(
|
||||
createAEAD(suite, trafficSecret, h.version),
|
||||
newHeaderProtector(suite, trafficSecret, true, h.version),
|
||||
@@ -459,7 +469,7 @@ func (h *cryptoSetup) SetReadKey(el qtls.QUICEncryptionLevel, suiteID uint16, tr
|
||||
if h.logger.Debug() {
|
||||
h.logger.Debugf("Installed Handshake Read keys (using %s)", tls.CipherSuiteName(suite.ID))
|
||||
}
|
||||
case qtls.QUICEncryptionLevelApplication:
|
||||
case tls.QUICEncryptionLevelApplication:
|
||||
h.aead.SetReadKey(suite, trafficSecret)
|
||||
h.has1RTTOpener = true
|
||||
if h.logger.Debug() {
|
||||
@@ -475,12 +485,12 @@ func (h *cryptoSetup) SetReadKey(el qtls.QUICEncryptionLevel, suiteID uint16, tr
|
||||
}
|
||||
}
|
||||
|
||||
func (h *cryptoSetup) SetWriteKey(el qtls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) {
|
||||
func (h *cryptoSetup) SetWriteKey(el tls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) {
|
||||
suite := getCipherSuite(suiteID)
|
||||
h.mutex.Lock()
|
||||
//nolint:exhaustive // The TLS stack doesn't export Initial keys.
|
||||
switch el {
|
||||
case qtls.QUICEncryptionLevelEarly:
|
||||
case tls.QUICEncryptionLevelEarly:
|
||||
if h.perspective == protocol.PerspectiveServer {
|
||||
panic("Received 0-RTT write key for the server")
|
||||
}
|
||||
@@ -497,7 +507,7 @@ func (h *cryptoSetup) SetWriteKey(el qtls.QUICEncryptionLevel, suiteID uint16, t
|
||||
}
|
||||
// don't set used0RTT here. 0-RTT might still get rejected.
|
||||
return
|
||||
case qtls.QUICEncryptionLevelHandshake:
|
||||
case tls.QUICEncryptionLevelHandshake:
|
||||
h.handshakeSealer = newLongHeaderSealer(
|
||||
createAEAD(suite, trafficSecret, h.version),
|
||||
newHeaderProtector(suite, trafficSecret, true, h.version),
|
||||
@@ -505,7 +515,7 @@ func (h *cryptoSetup) SetWriteKey(el qtls.QUICEncryptionLevel, suiteID uint16, t
|
||||
if h.logger.Debug() {
|
||||
h.logger.Debugf("Installed Handshake Write keys (using %s)", tls.CipherSuiteName(suite.ID))
|
||||
}
|
||||
case qtls.QUICEncryptionLevelApplication:
|
||||
case tls.QUICEncryptionLevelApplication:
|
||||
h.aead.SetWriteKey(suite, trafficSecret)
|
||||
h.has1RTTSealer = true
|
||||
if h.logger.Debug() {
|
||||
@@ -529,15 +539,15 @@ func (h *cryptoSetup) SetWriteKey(el qtls.QUICEncryptionLevel, suiteID uint16, t
|
||||
}
|
||||
}
|
||||
|
||||
// WriteRecord is called when TLS writes data
|
||||
func (h *cryptoSetup) WriteRecord(encLevel qtls.QUICEncryptionLevel, p []byte) {
|
||||
// writeRecord is called when TLS writes data
|
||||
func (h *cryptoSetup) writeRecord(encLevel tls.QUICEncryptionLevel, p []byte) {
|
||||
//nolint:exhaustive // handshake records can only be written for Initial and Handshake.
|
||||
switch encLevel {
|
||||
case qtls.QUICEncryptionLevelInitial:
|
||||
case tls.QUICEncryptionLevelInitial:
|
||||
h.events = append(h.events, Event{Kind: EventWriteInitialData, Data: p})
|
||||
case qtls.QUICEncryptionLevelHandshake:
|
||||
case tls.QUICEncryptionLevelHandshake:
|
||||
h.events = append(h.events, Event{Kind: EventWriteHandshakeData, Data: p})
|
||||
case qtls.QUICEncryptionLevelApplication:
|
||||
case tls.QUICEncryptionLevelApplication:
|
||||
panic("unexpected write")
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected write encryption level: %s", encLevel))
|
||||
@@ -684,7 +694,7 @@ func (h *cryptoSetup) ConnectionState() ConnectionState {
|
||||
|
||||
func wrapError(err error) error {
|
||||
// alert 80 is an internal error
|
||||
if alertErr := qtls.AlertError(0); errors.As(err, &alertErr) && alertErr != 80 {
|
||||
if alertErr := tls.AlertError(0); errors.As(err, &alertErr) && alertErr != 80 {
|
||||
return qerr.NewLocalCryptoError(uint8(alertErr), err)
|
||||
}
|
||||
return &qerr.TransportError{ErrorCode: qerr.InternalError, ErrorMessage: err.Error()}
|
||||
|
||||
2
vendor/github.com/quic-go/quic-go/internal/handshake/updatable_aead.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/internal/handshake/updatable_aead.go
generated
vendored
@@ -172,7 +172,7 @@ func (a *updatableAEAD) Open(dst, src []byte, rcvTime time.Time, pn protocol.Pac
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
a.highestRcvdPN = utils.Max(a.highestRcvdPN, pn)
|
||||
a.highestRcvdPN = max(a.highestRcvdPN, pn)
|
||||
}
|
||||
return dec, err
|
||||
}
|
||||
|
||||
3
vendor/github.com/quic-go/quic-go/internal/protocol/params.go
generated
vendored
3
vendor/github.com/quic-go/quic-go/internal/protocol/params.go
generated
vendored
@@ -129,9 +129,6 @@ const MaxPostHandshakeCryptoFrameSize = 1000
|
||||
// but must ensure that a maximum size ACK frame fits into one packet.
|
||||
const MaxAckFrameSize ByteCount = 1000
|
||||
|
||||
// DatagramRcvQueueLen is the length of the receive queue for DATAGRAM frames (RFC 9221)
|
||||
const DatagramRcvQueueLen = 128
|
||||
|
||||
// MaxNumAckRanges is the maximum number of ACK ranges that we send in an ACK frame.
|
||||
// It also serves as a limit for the packet history.
|
||||
// If at any point we keep track of more ranges, old ranges are discarded.
|
||||
|
||||
5
vendor/github.com/quic-go/quic-go/internal/qerr/error_codes.go
generated
vendored
5
vendor/github.com/quic-go/quic-go/internal/qerr/error_codes.go
generated
vendored
@@ -1,9 +1,8 @@
|
||||
package qerr
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/qtls"
|
||||
)
|
||||
|
||||
// TransportErrorCode is a QUIC transport error.
|
||||
@@ -40,7 +39,7 @@ func (e TransportErrorCode) Message() string {
|
||||
if !e.IsCryptoError() {
|
||||
return ""
|
||||
}
|
||||
return qtls.AlertError(e - 0x100).Error()
|
||||
return tls.AlertError(e - 0x100).Error()
|
||||
}
|
||||
|
||||
func (e TransportErrorCode) String() string {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//go:build go1.21
|
||||
|
||||
package qtls
|
||||
|
||||
import (
|
||||
13
vendor/github.com/quic-go/quic-go/internal/qtls/client_session_cache.go
generated
vendored
13
vendor/github.com/quic-go/quic-go/internal/qtls/client_session_cache.go
generated
vendored
@@ -7,8 +7,8 @@ import (
|
||||
)
|
||||
|
||||
type clientSessionCache struct {
|
||||
getData func() []byte
|
||||
setData func([]byte) (allowEarlyData bool)
|
||||
getData func(earlyData bool) []byte
|
||||
setData func(data []byte, earlyData bool) (allowEarlyData bool)
|
||||
wrapped tls.ClientSessionCache
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ func (c clientSessionCache) Put(key string, cs *tls.ClientSessionState) {
|
||||
c.wrapped.Put(key, cs)
|
||||
return
|
||||
}
|
||||
state.Extra = append(state.Extra, addExtraPrefix(c.getData()))
|
||||
state.Extra = append(state.Extra, addExtraPrefix(c.getData(state.EarlyData)))
|
||||
newCS, err := tls.NewResumptionState(ticket, state)
|
||||
if err != nil {
|
||||
// It's not clear why this would error. Just save the original state.
|
||||
@@ -46,12 +46,13 @@ func (c clientSessionCache) Get(key string) (*tls.ClientSessionState, bool) {
|
||||
c.wrapped.Put(key, nil)
|
||||
return nil, false
|
||||
}
|
||||
var earlyData bool
|
||||
// restore QUIC transport parameters and RTT stored in state.Extra
|
||||
if extra := findExtraData(state.Extra); extra != nil {
|
||||
earlyData = c.setData(extra)
|
||||
earlyData := c.setData(extra, state.EarlyData)
|
||||
if state.EarlyData {
|
||||
state.EarlyData = earlyData
|
||||
}
|
||||
}
|
||||
state.EarlyData = earlyData
|
||||
session, err := tls.NewResumptionState(ticket, state)
|
||||
if err != nil {
|
||||
// It's not clear why this would error.
|
||||
|
||||
147
vendor/github.com/quic-go/quic-go/internal/qtls/go120.go
generated
vendored
147
vendor/github.com/quic-go/quic-go/internal/qtls/go120.go
generated
vendored
@@ -1,147 +0,0 @@
|
||||
//go:build go1.20 && !go1.21
|
||||
|
||||
package qtls
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
|
||||
"github.com/quic-go/qtls-go1-20"
|
||||
)
|
||||
|
||||
type (
|
||||
QUICConn = qtls.QUICConn
|
||||
QUICConfig = qtls.QUICConfig
|
||||
QUICEvent = qtls.QUICEvent
|
||||
QUICEventKind = qtls.QUICEventKind
|
||||
QUICEncryptionLevel = qtls.QUICEncryptionLevel
|
||||
AlertError = qtls.AlertError
|
||||
)
|
||||
|
||||
const (
|
||||
QUICEncryptionLevelInitial = qtls.QUICEncryptionLevelInitial
|
||||
QUICEncryptionLevelEarly = qtls.QUICEncryptionLevelEarly
|
||||
QUICEncryptionLevelHandshake = qtls.QUICEncryptionLevelHandshake
|
||||
QUICEncryptionLevelApplication = qtls.QUICEncryptionLevelApplication
|
||||
)
|
||||
|
||||
const (
|
||||
QUICNoEvent = qtls.QUICNoEvent
|
||||
QUICSetReadSecret = qtls.QUICSetReadSecret
|
||||
QUICSetWriteSecret = qtls.QUICSetWriteSecret
|
||||
QUICWriteData = qtls.QUICWriteData
|
||||
QUICTransportParameters = qtls.QUICTransportParameters
|
||||
QUICTransportParametersRequired = qtls.QUICTransportParametersRequired
|
||||
QUICRejectedEarlyData = qtls.QUICRejectedEarlyData
|
||||
QUICHandshakeDone = qtls.QUICHandshakeDone
|
||||
)
|
||||
|
||||
func SetupConfigForServer(conf *QUICConfig, enable0RTT bool, getDataForSessionTicket func() []byte, handleSessionTicket func([]byte, bool) bool) {
|
||||
qtls.InitSessionTicketKeys(conf.TLSConfig)
|
||||
conf.TLSConfig = conf.TLSConfig.Clone()
|
||||
conf.TLSConfig.MinVersion = tls.VersionTLS13
|
||||
conf.ExtraConfig = &qtls.ExtraConfig{
|
||||
Enable0RTT: enable0RTT,
|
||||
Accept0RTT: func(data []byte) bool {
|
||||
return handleSessionTicket(data, true)
|
||||
},
|
||||
GetAppDataForSessionTicket: getDataForSessionTicket,
|
||||
}
|
||||
}
|
||||
|
||||
func SetupConfigForClient(conf *QUICConfig, getDataForSessionState func() []byte, setDataFromSessionState func([]byte) bool) {
|
||||
conf.ExtraConfig = &qtls.ExtraConfig{
|
||||
GetAppDataForSessionState: getDataForSessionState,
|
||||
SetAppDataFromSessionState: setDataFromSessionState,
|
||||
}
|
||||
}
|
||||
|
||||
func QUICServer(config *QUICConfig) *QUICConn {
|
||||
return qtls.QUICServer(config)
|
||||
}
|
||||
|
||||
func QUICClient(config *QUICConfig) *QUICConn {
|
||||
return qtls.QUICClient(config)
|
||||
}
|
||||
|
||||
func ToTLSEncryptionLevel(e protocol.EncryptionLevel) qtls.QUICEncryptionLevel {
|
||||
switch e {
|
||||
case protocol.EncryptionInitial:
|
||||
return qtls.QUICEncryptionLevelInitial
|
||||
case protocol.EncryptionHandshake:
|
||||
return qtls.QUICEncryptionLevelHandshake
|
||||
case protocol.Encryption1RTT:
|
||||
return qtls.QUICEncryptionLevelApplication
|
||||
case protocol.Encryption0RTT:
|
||||
return qtls.QUICEncryptionLevelEarly
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected encryption level: %s", e))
|
||||
}
|
||||
}
|
||||
|
||||
func FromTLSEncryptionLevel(e qtls.QUICEncryptionLevel) protocol.EncryptionLevel {
|
||||
switch e {
|
||||
case qtls.QUICEncryptionLevelInitial:
|
||||
return protocol.EncryptionInitial
|
||||
case qtls.QUICEncryptionLevelHandshake:
|
||||
return protocol.EncryptionHandshake
|
||||
case qtls.QUICEncryptionLevelApplication:
|
||||
return protocol.Encryption1RTT
|
||||
case qtls.QUICEncryptionLevelEarly:
|
||||
return protocol.Encryption0RTT
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpect encryption level: %s", e))
|
||||
}
|
||||
}
|
||||
|
||||
//go:linkname cipherSuitesTLS13 github.com/quic-go/qtls-go1-20.cipherSuitesTLS13
|
||||
var cipherSuitesTLS13 []unsafe.Pointer
|
||||
|
||||
//go:linkname defaultCipherSuitesTLS13 github.com/quic-go/qtls-go1-20.defaultCipherSuitesTLS13
|
||||
var defaultCipherSuitesTLS13 []uint16
|
||||
|
||||
//go:linkname defaultCipherSuitesTLS13NoAES github.com/quic-go/qtls-go1-20.defaultCipherSuitesTLS13NoAES
|
||||
var defaultCipherSuitesTLS13NoAES []uint16
|
||||
|
||||
var cipherSuitesModified bool
|
||||
|
||||
// SetCipherSuite modifies the cipherSuiteTLS13 slice of cipher suites inside qtls
|
||||
// such that it only contains the cipher suite with the chosen id.
|
||||
// The reset function returned resets them back to the original value.
|
||||
func SetCipherSuite(id uint16) (reset func()) {
|
||||
if cipherSuitesModified {
|
||||
panic("cipher suites modified multiple times without resetting")
|
||||
}
|
||||
cipherSuitesModified = true
|
||||
|
||||
origCipherSuitesTLS13 := append([]unsafe.Pointer{}, cipherSuitesTLS13...)
|
||||
origDefaultCipherSuitesTLS13 := append([]uint16{}, defaultCipherSuitesTLS13...)
|
||||
origDefaultCipherSuitesTLS13NoAES := append([]uint16{}, defaultCipherSuitesTLS13NoAES...)
|
||||
// The order is given by the order of the slice elements in cipherSuitesTLS13 in qtls.
|
||||
switch id {
|
||||
case tls.TLS_AES_128_GCM_SHA256:
|
||||
cipherSuitesTLS13 = cipherSuitesTLS13[:1]
|
||||
case tls.TLS_CHACHA20_POLY1305_SHA256:
|
||||
cipherSuitesTLS13 = cipherSuitesTLS13[1:2]
|
||||
case tls.TLS_AES_256_GCM_SHA384:
|
||||
cipherSuitesTLS13 = cipherSuitesTLS13[2:]
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected cipher suite: %d", id))
|
||||
}
|
||||
defaultCipherSuitesTLS13 = []uint16{id}
|
||||
defaultCipherSuitesTLS13NoAES = []uint16{id}
|
||||
|
||||
return func() {
|
||||
cipherSuitesTLS13 = origCipherSuitesTLS13
|
||||
defaultCipherSuitesTLS13 = origDefaultCipherSuitesTLS13
|
||||
defaultCipherSuitesTLS13NoAES = origDefaultCipherSuitesTLS13NoAES
|
||||
cipherSuitesModified = false
|
||||
}
|
||||
}
|
||||
|
||||
func SendSessionTicket(c *QUICConn, allow0RTT bool) error {
|
||||
return c.SendSessionTicket(allow0RTT)
|
||||
}
|
||||
5
vendor/github.com/quic-go/quic-go/internal/qtls/go_oldversion.go
generated
vendored
5
vendor/github.com/quic-go/quic-go/internal/qtls/go_oldversion.go
generated
vendored
@@ -1,5 +0,0 @@
|
||||
//go:build !go1.20
|
||||
|
||||
package qtls
|
||||
|
||||
var _ int = "The version of quic-go you're using can't be built using outdated Go versions. For more details, please see https://github.com/quic-go/quic-go/wiki/quic-go-and-Go-versions."
|
||||
@@ -1,5 +1,3 @@
|
||||
//go:build go1.21
|
||||
|
||||
package qtls
|
||||
|
||||
import (
|
||||
@@ -10,38 +8,7 @@ import (
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
)
|
||||
|
||||
type (
|
||||
QUICConn = tls.QUICConn
|
||||
QUICConfig = tls.QUICConfig
|
||||
QUICEvent = tls.QUICEvent
|
||||
QUICEventKind = tls.QUICEventKind
|
||||
QUICEncryptionLevel = tls.QUICEncryptionLevel
|
||||
QUICSessionTicketOptions = tls.QUICSessionTicketOptions
|
||||
AlertError = tls.AlertError
|
||||
)
|
||||
|
||||
const (
|
||||
QUICEncryptionLevelInitial = tls.QUICEncryptionLevelInitial
|
||||
QUICEncryptionLevelEarly = tls.QUICEncryptionLevelEarly
|
||||
QUICEncryptionLevelHandshake = tls.QUICEncryptionLevelHandshake
|
||||
QUICEncryptionLevelApplication = tls.QUICEncryptionLevelApplication
|
||||
)
|
||||
|
||||
const (
|
||||
QUICNoEvent = tls.QUICNoEvent
|
||||
QUICSetReadSecret = tls.QUICSetReadSecret
|
||||
QUICSetWriteSecret = tls.QUICSetWriteSecret
|
||||
QUICWriteData = tls.QUICWriteData
|
||||
QUICTransportParameters = tls.QUICTransportParameters
|
||||
QUICTransportParametersRequired = tls.QUICTransportParametersRequired
|
||||
QUICRejectedEarlyData = tls.QUICRejectedEarlyData
|
||||
QUICHandshakeDone = tls.QUICHandshakeDone
|
||||
)
|
||||
|
||||
func QUICServer(config *QUICConfig) *QUICConn { return tls.QUICServer(config) }
|
||||
func QUICClient(config *QUICConfig) *QUICConn { return tls.QUICClient(config) }
|
||||
|
||||
func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, handleSessionTicket func([]byte, bool) bool) {
|
||||
func SetupConfigForServer(qconf *tls.QUICConfig, _ bool, getData func() []byte, handleSessionTicket func([]byte, bool) bool) {
|
||||
conf := qconf.TLSConfig
|
||||
|
||||
// Workaround for https://github.com/golang/go/issues/60506.
|
||||
@@ -93,7 +60,11 @@ func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, hand
|
||||
}
|
||||
}
|
||||
|
||||
func SetupConfigForClient(qconf *QUICConfig, getData func() []byte, setData func([]byte) bool) {
|
||||
func SetupConfigForClient(
|
||||
qconf *tls.QUICConfig,
|
||||
getData func(earlyData bool) []byte,
|
||||
setData func(data []byte, earlyData bool) (allowEarlyData bool),
|
||||
) {
|
||||
conf := qconf.TLSConfig
|
||||
if conf.ClientSessionCache != nil {
|
||||
origCache := conf.ClientSessionCache
|
||||
@@ -151,9 +122,3 @@ func findExtraData(extras [][]byte) []byte {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func SendSessionTicket(c *QUICConn, allow0RTT bool) error {
|
||||
return c.SendSessionTicket(tls.QUICSessionTicketOptions{
|
||||
EarlyData: allow0RTT,
|
||||
})
|
||||
}
|
||||
26
vendor/github.com/quic-go/quic-go/internal/utils/minmax.go
generated
vendored
26
vendor/github.com/quic-go/quic-go/internal/utils/minmax.go
generated
vendored
@@ -3,27 +3,11 @@ package utils
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
// InfDuration is a duration of infinite length
|
||||
const InfDuration = time.Duration(math.MaxInt64)
|
||||
|
||||
func Max[T constraints.Ordered](a, b T) T {
|
||||
if a < b {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func Min[T constraints.Ordered](a, b T) T {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// MinNonZeroDuration return the minimum duration that's not zero.
|
||||
func MinNonZeroDuration(a, b time.Duration) time.Duration {
|
||||
if a == 0 {
|
||||
@@ -32,15 +16,7 @@ func MinNonZeroDuration(a, b time.Duration) time.Duration {
|
||||
if b == 0 {
|
||||
return a
|
||||
}
|
||||
return Min(a, b)
|
||||
}
|
||||
|
||||
// AbsDuration returns the absolute value of a time duration
|
||||
func AbsDuration(d time.Duration) time.Duration {
|
||||
if d >= 0 {
|
||||
return d
|
||||
}
|
||||
return -d
|
||||
return min(a, b)
|
||||
}
|
||||
|
||||
// MinTime returns the earlier time
|
||||
|
||||
12
vendor/github.com/quic-go/quic-go/internal/utils/ringbuffer/ringbuffer.go
generated
vendored
12
vendor/github.com/quic-go/quic-go/internal/utils/ringbuffer/ringbuffer.go
generated
vendored
@@ -8,7 +8,7 @@ type RingBuffer[T any] struct {
|
||||
full bool
|
||||
}
|
||||
|
||||
// Init preallocs a buffer with a certain size.
|
||||
// Init preallocates a buffer with a certain size.
|
||||
func (r *RingBuffer[T]) Init(size int) {
|
||||
r.ring = make([]T, size)
|
||||
}
|
||||
@@ -62,6 +62,16 @@ func (r *RingBuffer[T]) PopFront() T {
|
||||
return t
|
||||
}
|
||||
|
||||
// PeekFront returns the next element.
|
||||
// It must not be called when the buffer is empty, that means that
|
||||
// callers might need to check if there are elements in the buffer first.
|
||||
func (r *RingBuffer[T]) PeekFront() T {
|
||||
if r.Empty() {
|
||||
panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: peek from an empty queue")
|
||||
}
|
||||
return r.ring[r.headPos]
|
||||
}
|
||||
|
||||
// Grow the maximum size of the queue.
|
||||
// This method assume the queue is full.
|
||||
func (r *RingBuffer[T]) grow() {
|
||||
|
||||
8
vendor/github.com/quic-go/quic-go/internal/utils/rtt_stats.go
generated
vendored
8
vendor/github.com/quic-go/quic-go/internal/utils/rtt_stats.go
generated
vendored
@@ -55,7 +55,7 @@ func (r *RTTStats) PTO(includeMaxAckDelay bool) time.Duration {
|
||||
if r.SmoothedRTT() == 0 {
|
||||
return 2 * defaultInitialRTT
|
||||
}
|
||||
pto := r.SmoothedRTT() + Max(4*r.MeanDeviation(), protocol.TimerGranularity)
|
||||
pto := r.SmoothedRTT() + max(4*r.MeanDeviation(), protocol.TimerGranularity)
|
||||
if includeMaxAckDelay {
|
||||
pto += r.MaxAckDelay()
|
||||
}
|
||||
@@ -90,7 +90,7 @@ func (r *RTTStats) UpdateRTT(sendDelta, ackDelay time.Duration, now time.Time) {
|
||||
r.smoothedRTT = sample
|
||||
r.meanDeviation = sample / 2
|
||||
} else {
|
||||
r.meanDeviation = time.Duration(oneMinusBeta*float32(r.meanDeviation/time.Microsecond)+rttBeta*float32(AbsDuration(r.smoothedRTT-sample)/time.Microsecond)) * time.Microsecond
|
||||
r.meanDeviation = time.Duration(oneMinusBeta*float32(r.meanDeviation/time.Microsecond)+rttBeta*float32((r.smoothedRTT-sample).Abs()/time.Microsecond)) * time.Microsecond
|
||||
r.smoothedRTT = time.Duration((float32(r.smoothedRTT/time.Microsecond)*oneMinusAlpha)+(float32(sample/time.Microsecond)*rttAlpha)) * time.Microsecond
|
||||
}
|
||||
}
|
||||
@@ -126,6 +126,6 @@ func (r *RTTStats) OnConnectionMigration() {
|
||||
// is larger. The mean deviation is increased to the most recent deviation if
|
||||
// it's larger.
|
||||
func (r *RTTStats) ExpireSmoothedMetrics() {
|
||||
r.meanDeviation = Max(r.meanDeviation, AbsDuration(r.smoothedRTT-r.latestRTT))
|
||||
r.smoothedRTT = Max(r.smoothedRTT, r.latestRTT)
|
||||
r.meanDeviation = max(r.meanDeviation, (r.smoothedRTT - r.latestRTT).Abs())
|
||||
r.smoothedRTT = max(r.smoothedRTT, r.latestRTT)
|
||||
}
|
||||
|
||||
4
vendor/github.com/quic-go/quic-go/internal/wire/ack_frame.go
generated
vendored
4
vendor/github.com/quic-go/quic-go/internal/wire/ack_frame.go
generated
vendored
@@ -37,7 +37,7 @@ func parseAckFrame(frame *AckFrame, r *bytes.Reader, typ uint64, ackDelayExponen
|
||||
|
||||
delayTime := time.Duration(delay*1<<ackDelayExponent) * time.Microsecond
|
||||
if delayTime < 0 {
|
||||
// If the delay time overflows, set it to the maximum encodable value.
|
||||
// If the delay time overflows, set it to the maximum encode-able value.
|
||||
delayTime = utils.InfDuration
|
||||
}
|
||||
frame.DelayTime = delayTime
|
||||
@@ -57,9 +57,9 @@ func parseAckFrame(frame *AckFrame, r *bytes.Reader, typ uint64, ackDelayExponen
|
||||
return errors.New("invalid first ACK range")
|
||||
}
|
||||
smallest := largestAcked - ackBlock
|
||||
frame.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largestAcked})
|
||||
|
||||
// read all the other ACK ranges
|
||||
frame.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largestAcked})
|
||||
for i := uint64(0); i < numBlocks; i++ {
|
||||
g, err := quicvarint.Read(r)
|
||||
if err != nil {
|
||||
|
||||
2
vendor/github.com/quic-go/quic-go/internal/wire/transport_parameters.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/internal/wire/transport_parameters.go
generated
vendored
@@ -294,7 +294,7 @@ func (p *TransportParameters) readNumericTransportParameter(
|
||||
return fmt.Errorf("initial_max_streams_uni too large: %d (maximum %d)", p.MaxUniStreamNum, protocol.MaxStreamCount)
|
||||
}
|
||||
case maxIdleTimeoutParameterID:
|
||||
p.MaxIdleTimeout = utils.Max(protocol.MinRemoteIdleTimeout, time.Duration(val)*time.Millisecond)
|
||||
p.MaxIdleTimeout = max(protocol.MinRemoteIdleTimeout, time.Duration(val)*time.Millisecond)
|
||||
case maxUDPPayloadSizeParameterID:
|
||||
if val < 1200 {
|
||||
return fmt.Errorf("invalid value for max_packet_size: %d (minimum 1200)", val)
|
||||
|
||||
8
vendor/github.com/quic-go/quic-go/logging/connection_tracer.go
generated
vendored
8
vendor/github.com/quic-go/quic-go/logging/connection_tracer.go
generated
vendored
@@ -34,6 +34,7 @@ type ConnectionTracer struct {
|
||||
LossTimerExpired func(TimerType, EncryptionLevel)
|
||||
LossTimerCanceled func()
|
||||
ECNStateUpdated func(state ECNState, trigger ECNStateTrigger)
|
||||
ChoseALPN func(protocol string)
|
||||
// Close is called when the connection is closed.
|
||||
Close func()
|
||||
Debug func(name, msg string)
|
||||
@@ -237,6 +238,13 @@ func NewMultiplexedConnectionTracer(tracers ...*ConnectionTracer) *ConnectionTra
|
||||
}
|
||||
}
|
||||
},
|
||||
ChoseALPN: func(protocol string) {
|
||||
for _, t := range tracers {
|
||||
if t.ChoseALPN != nil {
|
||||
t.ChoseALPN(protocol)
|
||||
}
|
||||
}
|
||||
},
|
||||
Close: func() {
|
||||
for _, t := range tracers {
|
||||
if t.Close != nil {
|
||||
|
||||
6
vendor/github.com/quic-go/quic-go/oss-fuzz.sh
generated
vendored
6
vendor/github.com/quic-go/quic-go/oss-fuzz.sh
generated
vendored
@@ -3,12 +3,12 @@
|
||||
# Install Go manually, since oss-fuzz ships with an outdated Go version.
|
||||
# See https://github.com/google/oss-fuzz/pull/10643.
|
||||
export CXX="${CXX} -lresolv" # required by Go 1.20
|
||||
wget https://go.dev/dl/go1.20.5.linux-amd64.tar.gz \
|
||||
wget https://go.dev/dl/go1.21.5.linux-amd64.tar.gz \
|
||||
&& mkdir temp-go \
|
||||
&& rm -rf /root/.go/* \
|
||||
&& tar -C temp-go/ -xzf go1.20.5.linux-amd64.tar.gz \
|
||||
&& tar -C temp-go/ -xzf go1.21.5.linux-amd64.tar.gz \
|
||||
&& mv temp-go/go/* /root/.go/ \
|
||||
&& rm -rf temp-go go1.20.5.linux-amd64.tar.gz
|
||||
&& rm -rf temp-go go1.21.5.linux-amd64.tar.gz
|
||||
|
||||
(
|
||||
# fuzz qpack
|
||||
|
||||
16
vendor/github.com/quic-go/quic-go/packet_packer.go
generated
vendored
16
vendor/github.com/quic-go/quic-go/packet_packer.go
generated
vendored
@@ -606,11 +606,17 @@ func (p *packetPacker) composeNextPacket(maxFrameSize protocol.ByteCount, onlyAc
|
||||
if p.datagramQueue != nil {
|
||||
if f := p.datagramQueue.Peek(); f != nil {
|
||||
size := f.Length(v)
|
||||
if size <= maxFrameSize-pl.length {
|
||||
if size <= maxFrameSize-pl.length { // DATAGRAM frame fits
|
||||
pl.frames = append(pl.frames, ackhandler.Frame{Frame: f})
|
||||
pl.length += size
|
||||
p.datagramQueue.Pop()
|
||||
} else if !hasAck {
|
||||
// The DATAGRAM frame doesn't fit, and the packet doesn't contain an ACK.
|
||||
// Discard this frame. There's no point in retrying this in the next packet,
|
||||
// as it's unlikely that the available packet size will increase.
|
||||
p.datagramQueue.Pop()
|
||||
}
|
||||
// If the DATAGRAM frame was too large and the packet contained an ACK, we'll try to send it out later.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,7 +646,13 @@ func (p *packetPacker) composeNextPacket(maxFrameSize protocol.ByteCount, onlyAc
|
||||
pl.length += lengthAdded
|
||||
// add handlers for the control frames that were added
|
||||
for i := startLen; i < len(pl.frames); i++ {
|
||||
pl.frames[i].Handler = p.retransmissionQueue.AppDataAckHandler()
|
||||
switch pl.frames[i].Frame.(type) {
|
||||
case *wire.PathChallengeFrame, *wire.PathResponseFrame:
|
||||
// Path probing is currently not supported, therefore we don't need to set the OnAcked callback yet.
|
||||
// PATH_CHALLENGE and PATH_RESPONSE are never retransmitted.
|
||||
default:
|
||||
pl.frames[i].Handler = p.retransmissionQueue.AppDataAckHandler()
|
||||
}
|
||||
}
|
||||
|
||||
pl.streamFrames, lengthAdded = p.framer.AppendStreamFrames(pl.streamFrames, maxFrameSize-pl.length, v)
|
||||
|
||||
4
vendor/github.com/quic-go/quic-go/send_stream.go
generated
vendored
4
vendor/github.com/quic-go/quic-go/send_stream.go
generated
vendored
@@ -274,7 +274,7 @@ func (s *sendStream) popNewStreamFrame(maxBytes, sendWindow protocol.ByteCount,
|
||||
nextFrame := s.nextFrame
|
||||
s.nextFrame = nil
|
||||
|
||||
maxDataLen := utils.Min(sendWindow, nextFrame.MaxDataLen(maxBytes, v))
|
||||
maxDataLen := min(sendWindow, nextFrame.MaxDataLen(maxBytes, v))
|
||||
if nextFrame.DataLen() > maxDataLen {
|
||||
s.nextFrame = wire.GetStreamFrame()
|
||||
s.nextFrame.StreamID = s.streamID
|
||||
@@ -309,7 +309,7 @@ func (s *sendStream) popNewStreamFrameWithoutBuffer(f *wire.StreamFrame, maxByte
|
||||
if maxDataLen == 0 { // a STREAM frame must have at least one byte of data
|
||||
return s.dataForWriting != nil || s.nextFrame != nil || s.finishedWriting
|
||||
}
|
||||
s.getDataForWriting(f, utils.Min(maxDataLen, sendWindow))
|
||||
s.getDataForWriting(f, min(maxDataLen, sendWindow))
|
||||
|
||||
return s.dataForWriting != nil || s.nextFrame != nil || s.finishedWriting
|
||||
}
|
||||
|
||||
5
vendor/github.com/quic-go/quic-go/token_store.go
generated
vendored
5
vendor/github.com/quic-go/quic-go/token_store.go
generated
vendored
@@ -3,7 +3,6 @@ package quic
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
list "github.com/quic-go/quic-go/internal/utils/linkedlist"
|
||||
)
|
||||
|
||||
@@ -20,14 +19,14 @@ func newSingleOriginTokenStore(size int) *singleOriginTokenStore {
|
||||
func (s *singleOriginTokenStore) Add(token *ClientToken) {
|
||||
s.tokens[s.p] = token
|
||||
s.p = s.index(s.p + 1)
|
||||
s.len = utils.Min(s.len+1, len(s.tokens))
|
||||
s.len = min(s.len+1, len(s.tokens))
|
||||
}
|
||||
|
||||
func (s *singleOriginTokenStore) Pop() *ClientToken {
|
||||
s.p = s.index(s.p - 1)
|
||||
token := s.tokens[s.p]
|
||||
s.tokens[s.p] = nil
|
||||
s.len = utils.Max(s.len-1, 0)
|
||||
s.len = max(s.len-1, 0)
|
||||
return token
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user