mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-03-31 10:47:35 +03:00
upstream: sync to 0.39.1
This commit is contained in:
commit
7c77243b04
147 changed files with 3740 additions and 2211 deletions
21
.clusterfuzzlite/Dockerfile
Normal file
21
.clusterfuzzlite/Dockerfile
Normal file
|
@ -0,0 +1,21 @@
|
|||
FROM gcr.io/oss-fuzz-base/base-builder-go:v1
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
RUN echo "TARGETPLATFORM: ${TARGETPLATFORM}"
|
||||
|
||||
ENV GOVERSION=1.20.7
|
||||
|
||||
RUN platform=$(echo ${TARGETPLATFORM} | tr '/' '-') && \
|
||||
filename="go${GOVERSION}.${platform}.tar.gz" && \
|
||||
wget https://dl.google.com/go/${filename} && \
|
||||
mkdir temp-go && \
|
||||
rm -rf /root/.go/* && \
|
||||
tar -C temp-go/ -xzf ${filename} && \
|
||||
mv temp-go/go/* /root/.go/ && \
|
||||
rm -r ${filename} temp-go
|
||||
|
||||
RUN apt-get update && apt-get install -y make autoconf automake libtool
|
||||
|
||||
COPY . $SRC/quic-go
|
||||
WORKDIR quic-go
|
||||
COPY .clusterfuzzlite/build.sh $SRC/
|
9
.clusterfuzzlite/build.sh
Executable file
9
.clusterfuzzlite/build.sh
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
export CXX="${CXX} -lresolv" # required by Go 1.20
|
||||
|
||||
compile_go_fuzzer github.com/quic-go/quic-go/fuzzing/frames Fuzz frame_fuzzer
|
||||
compile_go_fuzzer github.com/quic-go/quic-go/fuzzing/header Fuzz header_fuzzer
|
||||
compile_go_fuzzer github.com/quic-go/quic-go/fuzzing/transportparameters Fuzz transportparameter_fuzzer
|
||||
compile_go_fuzzer github.com/quic-go/quic-go/fuzzing/tokens Fuzz token_fuzzer
|
||||
compile_go_fuzzer github.com/quic-go/quic-go/fuzzing/handshake Fuzz handshake_fuzzer
|
1
.clusterfuzzlite/project.yaml
Normal file
1
.clusterfuzzlite/project.yaml
Normal file
|
@ -0,0 +1 @@
|
|||
language: go
|
13
.github/FUNDING.yml
vendored
Normal file
13
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: [marten-seemann] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
48
.github/workflows/clusterfuzz-lite-pr.yml
vendored
Normal file
48
.github/workflows/clusterfuzz-lite-pr.yml
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
name: ClusterFuzzLite PR fuzzing
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '**'
|
||||
|
||||
permissions: read-all
|
||||
jobs:
|
||||
PR:
|
||||
runs-on: ${{ fromJSON(vars['CLUSTERFUZZ_LITE_RUNNER_UBUNTU'] || '"ubuntu-latest"') }}
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
sanitizer:
|
||||
- address
|
||||
steps:
|
||||
- name: Build Fuzzers (${{ matrix.sanitizer }})
|
||||
id: build
|
||||
uses: google/clusterfuzzlite/actions/build_fuzzers@v1
|
||||
with:
|
||||
language: go
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
sanitizer: ${{ matrix.sanitizer }}
|
||||
# Optional but recommended: used to only run fuzzers that are affected
|
||||
# by the PR.
|
||||
# See later section on "Git repo for storage".
|
||||
# storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/OWNER/STORAGE-REPO-NAME.git
|
||||
# storage-repo-branch: main # Optional. Defaults to "main"
|
||||
# storage-repo-branch-coverage: gh-pages # Optional. Defaults to "gh-pages".
|
||||
- name: Run Fuzzers (${{ matrix.sanitizer }})
|
||||
id: run
|
||||
uses: google/clusterfuzzlite/actions/run_fuzzers@v1
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
fuzz-seconds: 480
|
||||
mode: 'code-change'
|
||||
sanitizer: ${{ matrix.sanitizer }}
|
||||
output-sarif: true
|
||||
parallel-fuzzing: true
|
||||
# Optional but recommended: used to download the corpus produced by
|
||||
# batch fuzzing.
|
||||
# See later section on "Git repo for storage".
|
||||
# storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/OWNER/STORAGE-REPO-NAME.git
|
||||
# storage-repo-branch: main # Optional. Defaults to "main"
|
||||
# storage-repo-branch-coverage: gh-pages # Optional. Defaults to "gh-pages".
|
|
@ -4,7 +4,7 @@
|
|||
[](https://github.com/refraction-networking/uquic/actions/workflows/ginkgo_test.yml)
|
||||
[](https://godoc.org/github.com/refraction-networking/uquic)
|
||||
---
|
||||
uQUIC is a fork of [quic-go](https://github.com/quic-go/quic-go), which provides Initial Packet fingerprinting resistance and other features. While the handshake is still performed by quic-go, this library provides interface to customize the unencrypted Initial Packet which may reveal fingerprint-able information.
|
||||
uQUIC is a fork of [quic-go](https://github.com/refraction-networking/uquic), which provides Initial Packet fingerprinting resistance and other features. While the handshake is still performed by quic-go, this library provides interface to customize the unencrypted Initial Packet which may reveal fingerprint-able information.
|
||||
|
||||
Golang 1.20+ is required.
|
||||
|
||||
|
@ -32,7 +32,7 @@ If you are interested in our research, please stay tuned for our paper.
|
|||
- [ ] QUIC ACK Frame (on hold)
|
||||
- [x] TLS ClientHello Message (by [uTLS](https://github.com/refraction-networking/utls))
|
||||
- [x] QUIC Transport Parameters (in a uTLS extension)
|
||||
- [ ] Customize Initial ACK behavior ([#1](https://github.com/refraction-networking/uquic/issues/1), [quic-go#4007](https://github.com/quic-go/quic-go/issues/4007))
|
||||
- [ ] Customize Initial ACK behavior ([#1](https://github.com/refraction-networking/uquic/issues/1), [quic-go#4007](https://github.com/refraction-networking/uquic/issues/4007))
|
||||
- [ ] Customize Initial Retry behavior ([#2](https://github.com/refraction-networking/uquic/issues/2))
|
||||
- [ ] Add preset QUIC parrots
|
||||
- [x] Google Chrome parrot (call for parrots w/ `Token/PSK`)
|
||||
|
|
|
@ -35,7 +35,7 @@ type client struct {
|
|||
|
||||
conn quicConn
|
||||
|
||||
tracer logging.ConnectionTracer
|
||||
tracer *logging.ConnectionTracer
|
||||
tracingID uint64
|
||||
logger utils.Logger
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ func dial(
|
|||
if c.config.Tracer != nil {
|
||||
c.tracer = c.config.Tracer(context.WithValue(ctx, ConnectionTracingKey, c.tracingID), protocol.PerspectiveClient, c.destConnID)
|
||||
}
|
||||
if c.tracer != nil {
|
||||
if c.tracer != nil && c.tracer.StartedConnection != nil {
|
||||
c.tracer.StartedConnection(c.sendConn.LocalAddr(), c.sendConn.RemoteAddr(), c.srcConnID, c.destConnID)
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ func (c *client) dial(ctx context.Context) error {
|
|||
select {
|
||||
case <-ctx.Done():
|
||||
c.conn.shutdown()
|
||||
return ctx.Err()
|
||||
return context.Cause(ctx)
|
||||
case err := <-errorChan:
|
||||
return err
|
||||
case recreateErr := <-recreateChan:
|
||||
|
|
|
@ -44,7 +44,7 @@ var _ = Describe("Client", func() {
|
|||
initialPacketNumber protocol.PacketNumber,
|
||||
enable0RTT bool,
|
||||
hasNegotiatedVersion bool,
|
||||
tracer logging.ConnectionTracer,
|
||||
tracer *logging.ConnectionTracer,
|
||||
tracingID uint64,
|
||||
logger utils.Logger,
|
||||
v protocol.VersionNumber,
|
||||
|
@ -55,10 +55,11 @@ var _ = Describe("Client", func() {
|
|||
tlsConf = &tls.Config{NextProtos: []string{"proto1"}}
|
||||
connID = protocol.ParseConnectionID([]byte{0, 0, 0, 0, 0, 0, 0x13, 0x37})
|
||||
originalClientConnConstructor = newClientConnection
|
||||
tracer = mocklogging.NewMockConnectionTracer(mockCtrl)
|
||||
var tr *logging.ConnectionTracer
|
||||
tr, tracer = mocklogging.NewMockConnectionTracer(mockCtrl)
|
||||
config = &Config{
|
||||
Tracer: func(ctx context.Context, perspective logging.Perspective, id ConnectionID) logging.ConnectionTracer {
|
||||
return tracer
|
||||
Tracer: func(ctx context.Context, perspective logging.Perspective, id ConnectionID) *logging.ConnectionTracer {
|
||||
return tr
|
||||
},
|
||||
Versions: []protocol.VersionNumber{protocol.Version1},
|
||||
}
|
||||
|
@ -71,7 +72,7 @@ var _ = Describe("Client", func() {
|
|||
destConnID: connID,
|
||||
version: protocol.Version1,
|
||||
sendConn: packetConn,
|
||||
tracer: tracer,
|
||||
tracer: tr,
|
||||
logger: utils.DefaultLogger,
|
||||
}
|
||||
getMultiplexer() // make the sync.Once execute
|
||||
|
@ -122,7 +123,7 @@ var _ = Describe("Client", func() {
|
|||
_ protocol.PacketNumber,
|
||||
enable0RTT bool,
|
||||
_ bool,
|
||||
_ logging.ConnectionTracer,
|
||||
_ *logging.ConnectionTracer,
|
||||
_ uint64,
|
||||
_ utils.Logger,
|
||||
_ protocol.VersionNumber,
|
||||
|
@ -159,7 +160,7 @@ var _ = Describe("Client", func() {
|
|||
_ protocol.PacketNumber,
|
||||
enable0RTT bool,
|
||||
_ bool,
|
||||
_ logging.ConnectionTracer,
|
||||
_ *logging.ConnectionTracer,
|
||||
_ uint64,
|
||||
_ utils.Logger,
|
||||
_ protocol.VersionNumber,
|
||||
|
@ -196,7 +197,7 @@ var _ = Describe("Client", func() {
|
|||
_ protocol.PacketNumber,
|
||||
_ bool,
|
||||
_ bool,
|
||||
_ logging.ConnectionTracer,
|
||||
_ *logging.ConnectionTracer,
|
||||
_ uint64,
|
||||
_ utils.Logger,
|
||||
_ protocol.VersionNumber,
|
||||
|
@ -281,7 +282,7 @@ var _ = Describe("Client", func() {
|
|||
_ protocol.PacketNumber,
|
||||
_ bool,
|
||||
_ bool,
|
||||
_ logging.ConnectionTracer,
|
||||
_ *logging.ConnectionTracer,
|
||||
_ uint64,
|
||||
_ utils.Logger,
|
||||
versionP protocol.VersionNumber,
|
||||
|
@ -324,7 +325,7 @@ var _ = Describe("Client", func() {
|
|||
pn protocol.PacketNumber,
|
||||
_ bool,
|
||||
hasNegotiatedVersion bool,
|
||||
_ logging.ConnectionTracer,
|
||||
_ *logging.ConnectionTracer,
|
||||
_ uint64,
|
||||
_ utils.Logger,
|
||||
versionP protocol.VersionNumber,
|
||||
|
|
|
@ -1,19 +1,10 @@
|
|||
coverage:
|
||||
round: nearest
|
||||
ignore:
|
||||
- streams_map_incoming_bidi.go
|
||||
- streams_map_incoming_uni.go
|
||||
- streams_map_outgoing_bidi.go
|
||||
- streams_map_outgoing_uni.go
|
||||
- http3/gzip_reader.go
|
||||
- interop/
|
||||
- internal/ackhandler/packet_linkedlist.go
|
||||
- internal/handshake/cipher_suite.go
|
||||
- internal/utils/byteinterval_linkedlist.go
|
||||
- internal/utils/newconnectionid_linkedlist.go
|
||||
- internal/utils/packetinterval_linkedlist.go
|
||||
- internal/utils/linkedlist/linkedlist.go
|
||||
- logging/null_tracer.go
|
||||
- fuzzing/
|
||||
- metrics/
|
||||
status:
|
||||
|
|
52
config.go
52
config.go
|
@ -6,7 +6,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/refraction-networking/uquic/internal/protocol"
|
||||
"github.com/refraction-networking/uquic/internal/utils"
|
||||
"github.com/refraction-networking/uquic/quicvarint"
|
||||
)
|
||||
|
||||
|
@ -17,7 +16,11 @@ func (c *Config) Clone() *Config {
|
|||
}
|
||||
|
||||
func (c *Config) handshakeTimeout() time.Duration {
|
||||
return utils.Max(protocol.DefaultHandshakeTimeout, 2*c.HandshakeIdleTimeout)
|
||||
return 2 * c.HandshakeIdleTimeout
|
||||
}
|
||||
|
||||
func (c *Config) maxRetryTokenAge() time.Duration {
|
||||
return c.handshakeTimeout()
|
||||
}
|
||||
|
||||
func validateConfig(config *Config) error {
|
||||
|
@ -50,12 +53,6 @@ func validateConfig(config *Config) error {
|
|||
// it may be called with nil
|
||||
func populateServerConfig(config *Config) *Config {
|
||||
config = populateConfig(config)
|
||||
if config.MaxTokenAge == 0 {
|
||||
config.MaxTokenAge = protocol.TokenValidity
|
||||
}
|
||||
if config.MaxRetryTokenAge == 0 {
|
||||
config.MaxRetryTokenAge = protocol.RetryTokenValidity
|
||||
}
|
||||
if config.RequireAddressValidation == nil {
|
||||
config.RequireAddressValidation = func(net.Addr) bool { return false }
|
||||
}
|
||||
|
@ -110,27 +107,24 @@ func populateConfig(config *Config) *Config {
|
|||
}
|
||||
|
||||
return &Config{
|
||||
GetConfigForClient: config.GetConfigForClient,
|
||||
Versions: versions,
|
||||
HandshakeIdleTimeout: handshakeIdleTimeout,
|
||||
MaxIdleTimeout: idleTimeout,
|
||||
MaxTokenAge: config.MaxTokenAge,
|
||||
MaxRetryTokenAge: config.MaxRetryTokenAge,
|
||||
RequireAddressValidation: config.RequireAddressValidation,
|
||||
KeepAlivePeriod: config.KeepAlivePeriod,
|
||||
InitialStreamReceiveWindow: initialStreamReceiveWindow,
|
||||
MaxStreamReceiveWindow: maxStreamReceiveWindow,
|
||||
InitialConnectionReceiveWindow: initialConnectionReceiveWindow,
|
||||
MaxConnectionReceiveWindow: maxConnectionReceiveWindow,
|
||||
AllowConnectionWindowIncrease: config.AllowConnectionWindowIncrease,
|
||||
MaxIncomingStreams: maxIncomingStreams,
|
||||
MaxIncomingUniStreams: maxIncomingUniStreams,
|
||||
TokenStore: config.TokenStore,
|
||||
EnableDatagrams: config.EnableDatagrams,
|
||||
DisablePathMTUDiscovery: config.DisablePathMTUDiscovery,
|
||||
DisableVersionNegotiationPackets: config.DisableVersionNegotiationPackets,
|
||||
Allow0RTT: config.Allow0RTT,
|
||||
Tracer: config.Tracer,
|
||||
GetConfigForClient: config.GetConfigForClient,
|
||||
Versions: versions,
|
||||
HandshakeIdleTimeout: handshakeIdleTimeout,
|
||||
MaxIdleTimeout: idleTimeout,
|
||||
RequireAddressValidation: config.RequireAddressValidation,
|
||||
KeepAlivePeriod: config.KeepAlivePeriod,
|
||||
InitialStreamReceiveWindow: initialStreamReceiveWindow,
|
||||
MaxStreamReceiveWindow: maxStreamReceiveWindow,
|
||||
InitialConnectionReceiveWindow: initialConnectionReceiveWindow,
|
||||
MaxConnectionReceiveWindow: maxConnectionReceiveWindow,
|
||||
AllowConnectionWindowIncrease: config.AllowConnectionWindowIncrease,
|
||||
MaxIncomingStreams: maxIncomingStreams,
|
||||
MaxIncomingUniStreams: maxIncomingUniStreams,
|
||||
TokenStore: config.TokenStore,
|
||||
EnableDatagrams: config.EnableDatagrams,
|
||||
DisablePathMTUDiscovery: config.DisablePathMTUDiscovery,
|
||||
Allow0RTT: config.Allow0RTT,
|
||||
Tracer: config.Tracer,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,10 +78,6 @@ var _ = Describe("Config", func() {
|
|||
f.Set(reflect.ValueOf(time.Second))
|
||||
case "MaxIdleTimeout":
|
||||
f.Set(reflect.ValueOf(time.Hour))
|
||||
case "MaxTokenAge":
|
||||
f.Set(reflect.ValueOf(2 * time.Hour))
|
||||
case "MaxRetryTokenAge":
|
||||
f.Set(reflect.ValueOf(2 * time.Minute))
|
||||
case "TokenStore":
|
||||
f.Set(reflect.ValueOf(NewLRUTokenStore(2, 3)))
|
||||
case "InitialStreamReceiveWindow":
|
||||
|
@ -115,12 +111,7 @@ var _ = Describe("Config", func() {
|
|||
return c
|
||||
}
|
||||
|
||||
It("uses 10s handshake timeout for short handshake idle timeouts", func() {
|
||||
c := &Config{HandshakeIdleTimeout: time.Second}
|
||||
Expect(c.handshakeTimeout()).To(Equal(protocol.DefaultHandshakeTimeout))
|
||||
})
|
||||
|
||||
It("uses twice the handshake idle timeouts for the handshake timeout, for long handshake idle timeouts", func() {
|
||||
It("uses twice the handshake idle timeouts for the handshake timeout", func() {
|
||||
c := &Config{HandshakeIdleTimeout: time.Second * 11 / 2}
|
||||
Expect(c.handshakeTimeout()).To(Equal(11 * time.Second))
|
||||
})
|
||||
|
@ -132,7 +123,7 @@ var _ = Describe("Config", func() {
|
|||
GetConfigForClient: func(info *ClientHelloInfo) (*Config, error) { return nil, errors.New("nope") },
|
||||
AllowConnectionWindowIncrease: func(Connection, uint64) bool { calledAllowConnectionWindowIncrease = true; return true },
|
||||
RequireAddressValidation: func(net.Addr) bool { calledAddrValidation = true; return true },
|
||||
Tracer: func(context.Context, logging.Perspective, ConnectionID) logging.ConnectionTracer {
|
||||
Tracer: func(context.Context, logging.Perspective, ConnectionID) *logging.ConnectionTracer {
|
||||
calledTracer = true
|
||||
return nil
|
||||
},
|
||||
|
@ -192,7 +183,6 @@ var _ = Describe("Config", func() {
|
|||
Expect(c.MaxConnectionReceiveWindow).To(BeEquivalentTo(protocol.DefaultMaxReceiveConnectionFlowControlWindow))
|
||||
Expect(c.MaxIncomingStreams).To(BeEquivalentTo(protocol.DefaultMaxIncomingStreams))
|
||||
Expect(c.MaxIncomingUniStreams).To(BeEquivalentTo(protocol.DefaultMaxIncomingUniStreams))
|
||||
Expect(c.DisableVersionNegotiationPackets).To(BeFalse())
|
||||
Expect(c.DisablePathMTUDiscovery).To(BeFalse())
|
||||
Expect(c.GetConfigForClient).To(BeNil())
|
||||
})
|
||||
|
|
191
connection.go
191
connection.go
|
@ -209,7 +209,7 @@ type connection struct {
|
|||
connState ConnectionState
|
||||
|
||||
logID string
|
||||
tracer logging.ConnectionTracer
|
||||
tracer *logging.ConnectionTracer
|
||||
logger utils.Logger
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ var newConnection = func(
|
|||
tlsConf *tls.Config,
|
||||
tokenGenerator *handshake.TokenGenerator,
|
||||
clientAddressValidated bool,
|
||||
tracer logging.ConnectionTracer,
|
||||
tracer *logging.ConnectionTracer,
|
||||
tracingID uint64,
|
||||
logger utils.Logger,
|
||||
v protocol.VersionNumber,
|
||||
|
@ -244,7 +244,7 @@ var newConnection = func(
|
|||
handshakeDestConnID: destConnID,
|
||||
srcConnIDLen: srcConnID.Len(),
|
||||
tokenGenerator: tokenGenerator,
|
||||
oneRTTStream: newCryptoStream(true),
|
||||
oneRTTStream: newCryptoStream(),
|
||||
perspective: protocol.PerspectiveServer,
|
||||
tracer: tracer,
|
||||
logger: logger,
|
||||
|
@ -279,6 +279,7 @@ var newConnection = func(
|
|||
getMaxPacketSize(s.conn.RemoteAddr()),
|
||||
s.rttStats,
|
||||
clientAddressValidated,
|
||||
s.conn.capabilities().ECN,
|
||||
s.perspective,
|
||||
s.tracer,
|
||||
s.logger,
|
||||
|
@ -301,7 +302,7 @@ var newConnection = func(
|
|||
// different from protocol.DefaultActiveConnectionIDLimit.
|
||||
// If set to the default value, it will be omitted from the transport parameters, which will make
|
||||
// old quic-go versions interpret it as 0, instead of the default value of 2.
|
||||
// See https://github.com/quic-go/quic-go/pull/3806.
|
||||
// See https://github.com/refraction-networking/uquic/pull/3806.
|
||||
ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs,
|
||||
InitialSourceConnectionID: srcConnID,
|
||||
RetrySourceConnectionID: retrySrcConnID,
|
||||
|
@ -311,7 +312,7 @@ var newConnection = func(
|
|||
} else {
|
||||
params.MaxDatagramFrameSize = protocol.InvalidByteCount
|
||||
}
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.SentTransportParameters != nil {
|
||||
s.tracer.SentTransportParameters(params)
|
||||
}
|
||||
cs := handshake.NewCryptoSetupServer(
|
||||
|
@ -345,7 +346,7 @@ var newClientConnection = func(
|
|||
initialPacketNumber protocol.PacketNumber,
|
||||
enable0RTT bool,
|
||||
hasNegotiatedVersion bool,
|
||||
tracer logging.ConnectionTracer,
|
||||
tracer *logging.ConnectionTracer,
|
||||
tracingID uint64,
|
||||
logger utils.Logger,
|
||||
v protocol.VersionNumber,
|
||||
|
@ -387,14 +388,15 @@ var newClientConnection = func(
|
|||
initialPacketNumber,
|
||||
getMaxPacketSize(s.conn.RemoteAddr()),
|
||||
s.rttStats,
|
||||
false, /* has no effect */
|
||||
false, // has no effect
|
||||
s.conn.capabilities().ECN,
|
||||
s.perspective,
|
||||
s.tracer,
|
||||
s.logger,
|
||||
)
|
||||
|
||||
s.mtuDiscoverer = newMTUDiscoverer(s.rttStats, getMaxPacketSize(s.conn.RemoteAddr()), s.sentPacketHandler.SetMaxDatagramSize)
|
||||
oneRTTStream := newCryptoStream(true)
|
||||
oneRTTStream := newCryptoStream()
|
||||
params := &wire.TransportParameters{
|
||||
InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
|
||||
InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
|
||||
|
@ -410,7 +412,7 @@ var newClientConnection = func(
|
|||
// different from protocol.DefaultActiveConnectionIDLimit.
|
||||
// If set to the default value, it will be omitted from the transport parameters, which will make
|
||||
// old quic-go versions interpret it as 0, instead of the default value of 2.
|
||||
// See https://github.com/quic-go/quic-go/pull/3806.
|
||||
// See https://github.com/refraction-networking/uquic/pull/3806.
|
||||
ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs,
|
||||
InitialSourceConnectionID: srcConnID,
|
||||
}
|
||||
|
@ -419,8 +421,7 @@ var newClientConnection = func(
|
|||
} else {
|
||||
params.MaxDatagramFrameSize = protocol.InvalidByteCount
|
||||
}
|
||||
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.SentTransportParameters != nil {
|
||||
s.tracer.SentTransportParameters(params)
|
||||
}
|
||||
cs := handshake.NewCryptoSetupClient(
|
||||
|
@ -452,8 +453,8 @@ var newClientConnection = func(
|
|||
}
|
||||
|
||||
func (s *connection) preSetup() {
|
||||
s.initialStream = newCryptoStream(false)
|
||||
s.handshakeStream = newCryptoStream(false)
|
||||
s.initialStream = newCryptoStream()
|
||||
s.handshakeStream = newCryptoStream()
|
||||
s.sendQueue = newSendQueue(s.conn)
|
||||
s.retransmissionQueue = newRetransmissionQueue()
|
||||
s.frameParser = wire.NewFrameParser(s.config.EnableDatagrams)
|
||||
|
@ -645,8 +646,10 @@ runLoop:
|
|||
s.cryptoStreamHandler.Close()
|
||||
s.sendQueue.Close() // close the send queue before sending the CONNECTION_CLOSE
|
||||
s.handleCloseError(&closeErr)
|
||||
if e := (&errCloseForRecreating{}); !errors.As(closeErr.err, &e) && s.tracer != nil {
|
||||
s.tracer.Close()
|
||||
if s.tracer != nil && s.tracer.Close != nil {
|
||||
if e := (&errCloseForRecreating{}); !errors.As(closeErr.err, &e) {
|
||||
s.tracer.Close()
|
||||
}
|
||||
}
|
||||
s.logger.Infof("Connection %s closed.", s.logID)
|
||||
s.timer.Stop()
|
||||
|
@ -676,6 +679,7 @@ func (s *connection) ConnectionState() ConnectionState {
|
|||
cs := s.cryptoStreamHandler.ConnectionState()
|
||||
s.connState.TLS = cs.ConnectionState
|
||||
s.connState.Used0RTT = cs.Used0RTT
|
||||
s.connState.GSO = s.conn.capabilities().GSO
|
||||
return s.connState
|
||||
}
|
||||
|
||||
|
@ -803,14 +807,14 @@ func (s *connection) handlePacketImpl(rp receivedPacket) bool {
|
|||
var err error
|
||||
destConnID, err = wire.ParseConnectionID(p.data, s.srcConnIDLen)
|
||||
if err != nil {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(data)), logging.PacketDropHeaderParseError)
|
||||
}
|
||||
s.logger.Debugf("error parsing packet, couldn't parse connection ID: %s", err)
|
||||
break
|
||||
}
|
||||
if destConnID != lastConnID {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(data)), logging.PacketDropUnknownConnectionID)
|
||||
}
|
||||
s.logger.Debugf("coalesced packet has different destination connection ID: %s, expected %s", destConnID, lastConnID)
|
||||
|
@ -821,7 +825,7 @@ func (s *connection) handlePacketImpl(rp receivedPacket) bool {
|
|||
if wire.IsLongHeaderPacket(p.data[0]) {
|
||||
hdr, packetData, rest, err := wire.ParsePacket(p.data)
|
||||
if err != nil {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
dropReason := logging.PacketDropHeaderParseError
|
||||
if err == wire.ErrUnsupportedVersion {
|
||||
dropReason = logging.PacketDropUnsupportedVersion
|
||||
|
@ -834,7 +838,7 @@ func (s *connection) handlePacketImpl(rp receivedPacket) bool {
|
|||
lastConnID = hdr.DestConnectionID
|
||||
|
||||
if hdr.Version != s.version {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(data)), logging.PacketDropUnexpectedVersion)
|
||||
}
|
||||
s.logger.Debugf("Dropping packet with version %x. Expected %x.", hdr.Version, s.version)
|
||||
|
@ -893,14 +897,14 @@ func (s *connection) handleShortHeaderPacket(p receivedPacket, destConnID protoc
|
|||
|
||||
if s.receivedPacketHandler.IsPotentiallyDuplicate(pn, protocol.Encryption1RTT) {
|
||||
s.logger.Debugf("Dropping (potentially) duplicate packet.")
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketType1RTT, p.Size(), logging.PacketDropDuplicate)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var log func([]logging.Frame)
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.ReceivedShortHeaderPacket != nil {
|
||||
log = func(frames []logging.Frame) {
|
||||
s.tracer.ReceivedShortHeaderPacket(
|
||||
&logging.ShortHeader{
|
||||
|
@ -910,6 +914,7 @@ func (s *connection) handleShortHeaderPacket(p receivedPacket, destConnID protoc
|
|||
KeyPhase: keyPhase,
|
||||
},
|
||||
p.Size(),
|
||||
p.ecn,
|
||||
frames,
|
||||
)
|
||||
}
|
||||
|
@ -932,13 +937,13 @@ func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header)
|
|||
}()
|
||||
|
||||
if hdr.Type == protocol.PacketTypeRetry {
|
||||
return s.handleRetryPacket(hdr, p.data)
|
||||
return s.handleRetryPacket(hdr, p.data, p.rcvTime)
|
||||
}
|
||||
|
||||
// The server can change the source connection ID with the first Handshake packet.
|
||||
// After this, all packets with a different source connection have to be ignored.
|
||||
if s.receivedFirstPacket && hdr.Type == protocol.PacketTypeInitial && hdr.SrcConnectionID != s.handshakeDestConnID {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeInitial, p.Size(), logging.PacketDropUnknownConnectionID)
|
||||
}
|
||||
s.logger.Debugf("Dropping Initial packet (%d bytes) with unexpected source connection ID: %s (expected %s)", p.Size(), hdr.SrcConnectionID, s.handshakeDestConnID)
|
||||
|
@ -946,7 +951,7 @@ func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header)
|
|||
}
|
||||
// drop 0-RTT packets, if we are a client
|
||||
if s.perspective == protocol.PerspectiveClient && hdr.Type == protocol.PacketType0RTT {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketType0RTT, p.Size(), logging.PacketDropKeyUnavailable)
|
||||
}
|
||||
return false
|
||||
|
@ -965,7 +970,7 @@ func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header)
|
|||
|
||||
if s.receivedPacketHandler.IsPotentiallyDuplicate(packet.hdr.PacketNumber, packet.encryptionLevel) {
|
||||
s.logger.Debugf("Dropping (potentially) duplicate packet.")
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropDuplicate)
|
||||
}
|
||||
return false
|
||||
|
@ -981,7 +986,7 @@ func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header)
|
|||
func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.PacketType) (wasQueued bool) {
|
||||
switch err {
|
||||
case handshake.ErrKeysDropped:
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropKeyUnavailable)
|
||||
}
|
||||
s.logger.Debugf("Dropping %s packet (%d bytes) because we already dropped the keys.", pt, p.Size())
|
||||
|
@ -997,7 +1002,7 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P
|
|||
})
|
||||
case handshake.ErrDecryptionFailed:
|
||||
// This might be a packet injected by an attacker. Drop it.
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropPayloadDecryptError)
|
||||
}
|
||||
s.logger.Debugf("Dropping %s packet (%d bytes) that could not be unpacked. Error: %s", pt, p.Size(), err)
|
||||
|
@ -1005,7 +1010,7 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P
|
|||
var headerErr *headerParseError
|
||||
if errors.As(err, &headerErr) {
|
||||
// This might be a packet injected by an attacker. Drop it.
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropHeaderParseError)
|
||||
}
|
||||
s.logger.Debugf("Dropping %s packet (%d bytes) for which we couldn't unpack the header. Error: %s", pt, p.Size(), err)
|
||||
|
@ -1018,16 +1023,16 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P
|
|||
return false
|
||||
}
|
||||
|
||||
func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte) bool /* was this a valid Retry */ {
|
||||
func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime time.Time) bool /* was this a valid Retry */ {
|
||||
if s.perspective == protocol.PerspectiveServer {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)
|
||||
}
|
||||
s.logger.Debugf("Ignoring Retry.")
|
||||
return false
|
||||
}
|
||||
if s.receivedFirstPacket {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)
|
||||
}
|
||||
s.logger.Debugf("Ignoring Retry, since we already received a packet.")
|
||||
|
@ -1035,7 +1040,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte) bool /* wa
|
|||
}
|
||||
destConnID := s.connIDManager.Get()
|
||||
if hdr.SrcConnectionID == destConnID {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)
|
||||
}
|
||||
s.logger.Debugf("Ignoring Retry, since the server didn't change the Source Connection ID.")
|
||||
|
@ -1050,7 +1055,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte) bool /* wa
|
|||
|
||||
tag := handshake.GetRetryIntegrityTag(data[:len(data)-16], destConnID, hdr.Version)
|
||||
if !bytes.Equal(data[len(data)-16:], tag[:]) {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropPayloadDecryptError)
|
||||
}
|
||||
s.logger.Debugf("Ignoring spoofed Retry. Integrity Tag doesn't match.")
|
||||
|
@ -1062,12 +1067,12 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte) bool /* wa
|
|||
(&wire.ExtendedHeader{Header: *hdr}).Log(s.logger)
|
||||
s.logger.Debugf("Switching destination connection ID to: %s", hdr.SrcConnectionID)
|
||||
}
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.ReceivedRetry != nil {
|
||||
s.tracer.ReceivedRetry(hdr)
|
||||
}
|
||||
newDestConnID := hdr.SrcConnectionID
|
||||
s.receivedRetry = true
|
||||
if err := s.sentPacketHandler.ResetForRetry(); err != nil {
|
||||
if err := s.sentPacketHandler.ResetForRetry(rcvTime); err != nil {
|
||||
s.closeLocal(err)
|
||||
return false
|
||||
}
|
||||
|
@ -1083,7 +1088,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte) bool /* wa
|
|||
func (s *connection) handleVersionNegotiationPacket(p receivedPacket) {
|
||||
if s.perspective == protocol.PerspectiveServer || // servers never receive version negotiation packets
|
||||
s.receivedFirstPacket || s.versionNegotiated { // ignore delayed / duplicated version negotiation packets
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedPacket)
|
||||
}
|
||||
return
|
||||
|
@ -1091,7 +1096,7 @@ func (s *connection) handleVersionNegotiationPacket(p receivedPacket) {
|
|||
|
||||
src, dest, supportedVersions, err := wire.ParseVersionNegotiationPacket(p.data)
|
||||
if err != nil {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropHeaderParseError)
|
||||
}
|
||||
s.logger.Debugf("Error parsing Version Negotiation packet: %s", err)
|
||||
|
@ -1100,7 +1105,7 @@ func (s *connection) handleVersionNegotiationPacket(p receivedPacket) {
|
|||
|
||||
for _, v := range supportedVersions {
|
||||
if v == s.version {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedVersion)
|
||||
}
|
||||
// The Version Negotiation packet contains the version that we offered.
|
||||
|
@ -1110,7 +1115,7 @@ func (s *connection) handleVersionNegotiationPacket(p receivedPacket) {
|
|||
}
|
||||
|
||||
s.logger.Infof("Received a Version Negotiation packet. Supported Versions: %s", supportedVersions)
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.ReceivedVersionNegotiationPacket != nil {
|
||||
s.tracer.ReceivedVersionNegotiationPacket(dest, src, supportedVersions)
|
||||
}
|
||||
newVersion, ok := protocol.ChooseSupportedVersion(s.config.Versions, supportedVersions)
|
||||
|
@ -1122,7 +1127,7 @@ func (s *connection) handleVersionNegotiationPacket(p receivedPacket) {
|
|||
s.logger.Infof("No compatible QUIC version found.")
|
||||
return
|
||||
}
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.NegotiatedVersion != nil {
|
||||
s.tracer.NegotiatedVersion(newVersion, s.config.Versions, supportedVersions)
|
||||
}
|
||||
|
||||
|
@ -1142,7 +1147,7 @@ func (s *connection) handleUnpackedLongHeaderPacket(
|
|||
) error {
|
||||
if !s.receivedFirstPacket {
|
||||
s.receivedFirstPacket = true
|
||||
if !s.versionNegotiated && s.tracer != nil {
|
||||
if !s.versionNegotiated && s.tracer != nil && s.tracer.NegotiatedVersion != nil {
|
||||
var clientVersions, serverVersions []protocol.VersionNumber
|
||||
switch s.perspective {
|
||||
case protocol.PerspectiveClient:
|
||||
|
@ -1169,7 +1174,7 @@ func (s *connection) handleUnpackedLongHeaderPacket(
|
|||
s.handshakeDestConnID = packet.hdr.SrcConnectionID
|
||||
s.connIDManager.ChangeInitialConnID(packet.hdr.SrcConnectionID)
|
||||
}
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.StartedConnection != nil {
|
||||
s.tracer.StartedConnection(
|
||||
s.conn.LocalAddr(),
|
||||
s.conn.RemoteAddr(),
|
||||
|
@ -1193,9 +1198,9 @@ func (s *connection) handleUnpackedLongHeaderPacket(
|
|||
s.keepAlivePingSent = false
|
||||
|
||||
var log func([]logging.Frame)
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.ReceivedLongHeaderPacket != nil {
|
||||
log = func(frames []logging.Frame) {
|
||||
s.tracer.ReceivedLongHeaderPacket(packet.hdr, packetSize, frames)
|
||||
s.tracer.ReceivedLongHeaderPacket(packet.hdr, packetSize, ecn, frames)
|
||||
}
|
||||
}
|
||||
isAckEliciting, err := s.handleFrames(packet.data, packet.hdr.DestConnectionID, packet.encryptionLevel, log)
|
||||
|
@ -1341,7 +1346,7 @@ func (s *connection) handlePacket(p receivedPacket) {
|
|||
select {
|
||||
case s.receivedPackets <- p:
|
||||
default:
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention)
|
||||
}
|
||||
}
|
||||
|
@ -1621,7 +1626,7 @@ func (s *connection) handleCloseError(closeErr *closeError) {
|
|||
s.datagramQueue.CloseWithError(e)
|
||||
}
|
||||
|
||||
if s.tracer != nil && !errors.As(e, &recreateErr) {
|
||||
if s.tracer != nil && s.tracer.ClosedConnection != nil && !errors.As(e, &recreateErr) {
|
||||
s.tracer.ClosedConnection(e)
|
||||
}
|
||||
|
||||
|
@ -1648,7 +1653,7 @@ func (s *connection) handleCloseError(closeErr *closeError) {
|
|||
}
|
||||
|
||||
func (s *connection) dropEncryptionLevel(encLevel protocol.EncryptionLevel) error {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedEncryptionLevel != nil {
|
||||
s.tracer.DroppedEncryptionLevel(encLevel)
|
||||
}
|
||||
s.sentPacketHandler.DropPackets(encLevel)
|
||||
|
@ -1683,7 +1688,7 @@ func (s *connection) restoreTransportParameters(params *wire.TransportParameters
|
|||
}
|
||||
|
||||
func (s *connection) handleTransportParameters(params *wire.TransportParameters) error {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.ReceivedTransportParameters != nil {
|
||||
s.tracer.ReceivedTransportParameters(params)
|
||||
}
|
||||
if err := s.checkTransportParameters(params); err != nil {
|
||||
|
@ -1835,9 +1840,10 @@ func (s *connection) sendPackets(now time.Time) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, buf.Len(), false)
|
||||
s.registerPackedShortHeaderPacket(p, now)
|
||||
s.sendQueue.Send(buf, buf.Len())
|
||||
ecn := s.sentPacketHandler.ECNMode(true)
|
||||
s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, buf.Len(), false)
|
||||
s.registerPackedShortHeaderPacket(p, ecn, now)
|
||||
s.sendQueue.Send(buf, 0, ecn)
|
||||
// This is kind of a hack. We need to trigger sending again somehow.
|
||||
s.pacingDeadline = deadlineSendImmediately
|
||||
return nil
|
||||
|
@ -1857,7 +1863,7 @@ func (s *connection) sendPackets(now time.Time) error {
|
|||
return err
|
||||
}
|
||||
s.sentFirstPacket = true
|
||||
if err := s.sendPackedCoalescedPacket(packet, now); err != nil {
|
||||
if err := s.sendPackedCoalescedPacket(packet, s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now); err != nil {
|
||||
return err
|
||||
}
|
||||
sendMode := s.sentPacketHandler.SendMode(now)
|
||||
|
@ -1878,7 +1884,8 @@ func (s *connection) sendPackets(now time.Time) error {
|
|||
func (s *connection) sendPacketsWithoutGSO(now time.Time) error {
|
||||
for {
|
||||
buf := getPacketBuffer()
|
||||
if _, err := s.appendPacket(buf, s.mtuDiscoverer.CurrentSize(), now); err != nil {
|
||||
ecn := s.sentPacketHandler.ECNMode(true)
|
||||
if _, err := s.appendOneShortHeaderPacket(buf, s.mtuDiscoverer.CurrentSize(), ecn, now); err != nil {
|
||||
if err == errNothingToPack {
|
||||
buf.Release()
|
||||
return nil
|
||||
|
@ -1886,7 +1893,7 @@ func (s *connection) sendPacketsWithoutGSO(now time.Time) error {
|
|||
return err
|
||||
}
|
||||
|
||||
s.sendQueue.Send(buf, buf.Len())
|
||||
s.sendQueue.Send(buf, 0, ecn)
|
||||
|
||||
if s.sendQueue.WouldBlock() {
|
||||
return nil
|
||||
|
@ -1911,9 +1918,10 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error {
|
|||
buf := getLargePacketBuffer()
|
||||
maxSize := s.mtuDiscoverer.CurrentSize()
|
||||
|
||||
ecn := s.sentPacketHandler.ECNMode(true)
|
||||
for {
|
||||
var dontSendMore bool
|
||||
size, err := s.appendPacket(buf, maxSize, now)
|
||||
size, err := s.appendOneShortHeaderPacket(buf, maxSize, ecn, now)
|
||||
if err != nil {
|
||||
if err != errNothingToPack {
|
||||
return err
|
||||
|
@ -1935,15 +1943,19 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error {
|
|||
}
|
||||
}
|
||||
|
||||
// Don't send more packets in this batch if they require a different ECN marking than the previous ones.
|
||||
nextECN := s.sentPacketHandler.ECNMode(true)
|
||||
|
||||
// Append another packet if
|
||||
// 1. The congestion controller and pacer allow sending more
|
||||
// 2. The last packet appended was a full-size packet
|
||||
// 3. We still have enough space for another full-size packet in the buffer
|
||||
if !dontSendMore && size == maxSize && buf.Len()+maxSize <= buf.Cap() {
|
||||
// 3. The next packet will have the same ECN marking
|
||||
// 4. We still have enough space for another full-size packet in the buffer
|
||||
if !dontSendMore && size == maxSize && nextECN == ecn && buf.Len()+maxSize <= buf.Cap() {
|
||||
continue
|
||||
}
|
||||
|
||||
s.sendQueue.Send(buf, maxSize)
|
||||
s.sendQueue.Send(buf, uint16(maxSize), ecn)
|
||||
|
||||
if dontSendMore {
|
||||
return nil
|
||||
|
@ -1972,6 +1984,7 @@ func (s *connection) resetPacingDeadline() {
|
|||
|
||||
func (s *connection) maybeSendAckOnlyPacket(now time.Time) error {
|
||||
if !s.handshakeConfirmed {
|
||||
ecn := s.sentPacketHandler.ECNMode(false)
|
||||
packet, err := s.packer.PackCoalescedPacket(true, s.mtuDiscoverer.CurrentSize(), s.version)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -1979,9 +1992,10 @@ func (s *connection) maybeSendAckOnlyPacket(now time.Time) error {
|
|||
if packet == nil {
|
||||
return nil
|
||||
}
|
||||
return s.sendPackedCoalescedPacket(packet, time.Now())
|
||||
return s.sendPackedCoalescedPacket(packet, ecn, time.Now())
|
||||
}
|
||||
|
||||
ecn := s.sentPacketHandler.ECNMode(true)
|
||||
p, buf, err := s.packer.PackAckOnlyPacket(s.mtuDiscoverer.CurrentSize(), s.version)
|
||||
if err != nil {
|
||||
if err == errNothingToPack {
|
||||
|
@ -1989,9 +2003,9 @@ func (s *connection) maybeSendAckOnlyPacket(now time.Time) error {
|
|||
}
|
||||
return err
|
||||
}
|
||||
s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, buf.Len(), false)
|
||||
s.registerPackedShortHeaderPacket(p, now)
|
||||
s.sendQueue.Send(buf, buf.Len())
|
||||
s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, buf.Len(), false)
|
||||
s.registerPackedShortHeaderPacket(p, ecn, now)
|
||||
s.sendQueue.Send(buf, 0, ecn)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -2023,24 +2037,24 @@ func (s *connection) sendProbePacket(encLevel protocol.EncryptionLevel, now time
|
|||
if packet == nil || (len(packet.longHdrPackets) == 0 && packet.shortHdrPacket == nil) {
|
||||
return fmt.Errorf("connection BUG: couldn't pack %s probe packet", encLevel)
|
||||
}
|
||||
return s.sendPackedCoalescedPacket(packet, now)
|
||||
return s.sendPackedCoalescedPacket(packet, s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now)
|
||||
}
|
||||
|
||||
// appendPacket appends a new packet to the given packetBuffer.
|
||||
// appendOneShortHeaderPacket appends a new packet to the given packetBuffer.
|
||||
// If there was nothing to pack, the returned size is 0.
|
||||
func (s *connection) appendPacket(buf *packetBuffer, maxSize protocol.ByteCount, now time.Time) (protocol.ByteCount, error) {
|
||||
func (s *connection) appendOneShortHeaderPacket(buf *packetBuffer, maxSize protocol.ByteCount, ecn protocol.ECN, now time.Time) (protocol.ByteCount, error) {
|
||||
startLen := buf.Len()
|
||||
p, err := s.packer.AppendPacket(buf, maxSize, s.version)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
size := buf.Len() - startLen
|
||||
s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, size, false)
|
||||
s.registerPackedShortHeaderPacket(p, now)
|
||||
s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, size, false)
|
||||
s.registerPackedShortHeaderPacket(p, ecn, now)
|
||||
return size, nil
|
||||
}
|
||||
|
||||
func (s *connection) registerPackedShortHeaderPacket(p shortHeaderPacket, now time.Time) {
|
||||
func (s *connection) registerPackedShortHeaderPacket(p shortHeaderPacket, ecn protocol.ECN, now time.Time) {
|
||||
if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && (len(p.StreamFrames) > 0 || ackhandler.HasAckElicitingFrames(p.Frames)) {
|
||||
s.firstAckElicitingPacketAfterIdleSentTime = now
|
||||
}
|
||||
|
@ -2049,12 +2063,12 @@ func (s *connection) registerPackedShortHeaderPacket(p shortHeaderPacket, now ti
|
|||
if p.Ack != nil {
|
||||
largestAcked = p.Ack.LargestAcked()
|
||||
}
|
||||
s.sentPacketHandler.SentPacket(now, p.PacketNumber, largestAcked, p.StreamFrames, p.Frames, protocol.Encryption1RTT, p.Length, p.IsPathMTUProbePacket)
|
||||
s.sentPacketHandler.SentPacket(now, p.PacketNumber, largestAcked, p.StreamFrames, p.Frames, protocol.Encryption1RTT, ecn, p.Length, p.IsPathMTUProbePacket)
|
||||
s.connIDManager.SentPacket()
|
||||
}
|
||||
|
||||
func (s *connection) sendPackedCoalescedPacket(packet *coalescedPacket, now time.Time) error {
|
||||
s.logCoalescedPacket(packet)
|
||||
func (s *connection) sendPackedCoalescedPacket(packet *coalescedPacket, ecn protocol.ECN, now time.Time) error {
|
||||
s.logCoalescedPacket(packet, ecn)
|
||||
for _, p := range packet.longHdrPackets {
|
||||
if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() {
|
||||
s.firstAckElicitingPacketAfterIdleSentTime = now
|
||||
|
@ -2063,7 +2077,7 @@ func (s *connection) sendPackedCoalescedPacket(packet *coalescedPacket, now time
|
|||
if p.ack != nil {
|
||||
largestAcked = p.ack.LargestAcked()
|
||||
}
|
||||
s.sentPacketHandler.SentPacket(now, p.header.PacketNumber, largestAcked, p.streamFrames, p.frames, p.EncryptionLevel(), p.length, false)
|
||||
s.sentPacketHandler.SentPacket(now, p.header.PacketNumber, largestAcked, p.streamFrames, p.frames, p.EncryptionLevel(), ecn, p.length, false)
|
||||
if s.perspective == protocol.PerspectiveClient && p.EncryptionLevel() == protocol.EncryptionHandshake {
|
||||
// On the client side, Initial keys are dropped as soon as the first Handshake packet is sent.
|
||||
// See Section 4.9.1 of RFC 9001.
|
||||
|
@ -2080,11 +2094,10 @@ func (s *connection) sendPackedCoalescedPacket(packet *coalescedPacket, now time
|
|||
if p.Ack != nil {
|
||||
largestAcked = p.Ack.LargestAcked()
|
||||
}
|
||||
s.sentPacketHandler.SentPacket(now, p.PacketNumber, largestAcked, p.StreamFrames, p.Frames, protocol.Encryption1RTT, p.Length, p.IsPathMTUProbePacket)
|
||||
s.sentPacketHandler.SentPacket(now, p.PacketNumber, largestAcked, p.StreamFrames, p.Frames, protocol.Encryption1RTT, ecn, p.Length, p.IsPathMTUProbePacket)
|
||||
}
|
||||
s.connIDManager.SentPacket()
|
||||
s.sendQueue.Send(packet.buffer, packet.buffer.Len())
|
||||
|
||||
s.sendQueue.Send(packet.buffer, 0, ecn)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -2106,11 +2119,12 @@ func (s *connection) sendConnectionClose(e error) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.logCoalescedPacket(packet)
|
||||
return packet.buffer.Data, s.conn.Write(packet.buffer.Data, packet.buffer.Len())
|
||||
ecn := s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket())
|
||||
s.logCoalescedPacket(packet, ecn)
|
||||
return packet.buffer.Data, s.conn.Write(packet.buffer.Data, 0, ecn)
|
||||
}
|
||||
|
||||
func (s *connection) logLongHeaderPacket(p *longHeaderPacket) {
|
||||
func (s *connection) logLongHeaderPacket(p *longHeaderPacket, ecn protocol.ECN) {
|
||||
// quic-go logging
|
||||
if s.logger.Debug() {
|
||||
p.header.Log(s.logger)
|
||||
|
@ -2126,7 +2140,7 @@ func (s *connection) logLongHeaderPacket(p *longHeaderPacket) {
|
|||
}
|
||||
|
||||
// tracing
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.SentLongHeaderPacket != nil {
|
||||
frames := make([]logging.Frame, 0, len(p.frames))
|
||||
for _, f := range p.frames {
|
||||
frames = append(frames, logutils.ConvertFrame(f.Frame))
|
||||
|
@ -2138,7 +2152,7 @@ func (s *connection) logLongHeaderPacket(p *longHeaderPacket) {
|
|||
if p.ack != nil {
|
||||
ack = logutils.ConvertAckFrame(p.ack)
|
||||
}
|
||||
s.tracer.SentLongHeaderPacket(p.header, p.length, ack, frames)
|
||||
s.tracer.SentLongHeaderPacket(p.header, p.length, ecn, ack, frames)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2150,11 +2164,12 @@ func (s *connection) logShortHeaderPacket(
|
|||
pn protocol.PacketNumber,
|
||||
pnLen protocol.PacketNumberLen,
|
||||
kp protocol.KeyPhaseBit,
|
||||
ecn protocol.ECN,
|
||||
size protocol.ByteCount,
|
||||
isCoalesced bool,
|
||||
) {
|
||||
if s.logger.Debug() && !isCoalesced {
|
||||
s.logger.Debugf("-> Sending packet %d (%d bytes) for connection %s, 1-RTT", pn, size, s.logID)
|
||||
s.logger.Debugf("-> Sending packet %d (%d bytes) for connection %s, 1-RTT (ECN: %s)", pn, size, s.logID, ecn)
|
||||
}
|
||||
// quic-go logging
|
||||
if s.logger.Debug() {
|
||||
|
@ -2171,7 +2186,7 @@ func (s *connection) logShortHeaderPacket(
|
|||
}
|
||||
|
||||
// tracing
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.SentShortHeaderPacket != nil {
|
||||
fs := make([]logging.Frame, 0, len(frames)+len(streamFrames))
|
||||
for _, f := range frames {
|
||||
fs = append(fs, logutils.ConvertFrame(f.Frame))
|
||||
|
@ -2191,13 +2206,14 @@ func (s *connection) logShortHeaderPacket(
|
|||
KeyPhase: kp,
|
||||
},
|
||||
size,
|
||||
ecn,
|
||||
ack,
|
||||
fs,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *connection) logCoalescedPacket(packet *coalescedPacket) {
|
||||
func (s *connection) logCoalescedPacket(packet *coalescedPacket, ecn protocol.ECN) {
|
||||
if s.logger.Debug() {
|
||||
// There's a short period between dropping both Initial and Handshake keys and completion of the handshake,
|
||||
// during which we might call PackCoalescedPacket but just pack a short header packet.
|
||||
|
@ -2210,6 +2226,7 @@ func (s *connection) logCoalescedPacket(packet *coalescedPacket) {
|
|||
packet.shortHdrPacket.PacketNumber,
|
||||
packet.shortHdrPacket.PacketNumberLen,
|
||||
packet.shortHdrPacket.KeyPhase,
|
||||
ecn,
|
||||
packet.shortHdrPacket.Length,
|
||||
false,
|
||||
)
|
||||
|
@ -2222,10 +2239,10 @@ func (s *connection) logCoalescedPacket(packet *coalescedPacket) {
|
|||
}
|
||||
}
|
||||
for _, p := range packet.longHdrPackets {
|
||||
s.logLongHeaderPacket(p)
|
||||
s.logLongHeaderPacket(p, ecn)
|
||||
}
|
||||
if p := packet.shortHdrPacket; p != nil {
|
||||
s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, p.Length, true)
|
||||
s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, p.Length, true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2291,14 +2308,14 @@ func (s *connection) tryQueueingUndecryptablePacket(p receivedPacket, pt logging
|
|||
panic("shouldn't queue undecryptable packets after handshake completion")
|
||||
}
|
||||
if len(s.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets {
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.DroppedPacket != nil {
|
||||
s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropDOSPrevention)
|
||||
}
|
||||
s.logger.Infof("Dropping undecryptable packet (%d bytes). Undecryptable packet queue full.", p.Size())
|
||||
return
|
||||
}
|
||||
s.logger.Infof("Queueing packet (%d bytes) for later decryption", p.Size())
|
||||
if s.tracer != nil {
|
||||
if s.tracer != nil && s.tracer.BufferedPacket != nil {
|
||||
s.tracer.BufferedPacket(pt, p.Size())
|
||||
}
|
||||
s.undecryptablePackets = append(s.undecryptablePackets, p)
|
||||
|
|
|
@ -101,9 +101,9 @@ var _ = Describe("Connection", func() {
|
|||
mconn.EXPECT().capabilities().DoAndReturn(func() connCapabilities { return capabilities }).AnyTimes()
|
||||
mconn.EXPECT().RemoteAddr().Return(remoteAddr).AnyTimes()
|
||||
mconn.EXPECT().LocalAddr().Return(localAddr).AnyTimes()
|
||||
tokenGenerator, err := handshake.NewTokenGenerator(rand.Reader)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
tracer = mocklogging.NewMockConnectionTracer(mockCtrl)
|
||||
tokenGenerator := handshake.NewTokenGenerator([32]byte{0xa, 0xb, 0xc})
|
||||
var tr *logging.ConnectionTracer
|
||||
tr, tracer = mocklogging.NewMockConnectionTracer(mockCtrl)
|
||||
tracer.EXPECT().NegotiatedVersion(gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1)
|
||||
tracer.EXPECT().SentTransportParameters(gomock.Any())
|
||||
tracer.EXPECT().UpdatedKeyFromTLS(gomock.Any(), gomock.Any()).AnyTimes()
|
||||
|
@ -122,7 +122,7 @@ var _ = Describe("Connection", func() {
|
|||
&tls.Config{},
|
||||
tokenGenerator,
|
||||
false,
|
||||
tracer,
|
||||
tr,
|
||||
1234,
|
||||
utils.DefaultLogger,
|
||||
protocol.Version1,
|
||||
|
@ -455,7 +455,7 @@ var _ = Describe("Connection", func() {
|
|||
Expect(e.ErrorMessage).To(BeEmpty())
|
||||
return &coalescedPacket{buffer: buffer}, nil
|
||||
})
|
||||
mconn.EXPECT().Write([]byte("connection close"), gomock.Any())
|
||||
mconn.EXPECT().Write([]byte("connection close"), gomock.Any(), gomock.Any())
|
||||
gomock.InOrder(
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) {
|
||||
var appErr *ApplicationError
|
||||
|
@ -476,7 +476,7 @@ var _ = Describe("Connection", func() {
|
|||
expectReplaceWithClosed()
|
||||
cryptoSetup.EXPECT().Close()
|
||||
packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
conn.shutdown()
|
||||
|
@ -495,7 +495,7 @@ var _ = Describe("Connection", func() {
|
|||
expectReplaceWithClosed()
|
||||
cryptoSetup.EXPECT().Close()
|
||||
packer.EXPECT().PackApplicationClose(expectedErr, gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
gomock.InOrder(
|
||||
tracer.EXPECT().ClosedConnection(expectedErr),
|
||||
tracer.EXPECT().Close(),
|
||||
|
@ -517,7 +517,7 @@ var _ = Describe("Connection", func() {
|
|||
expectReplaceWithClosed()
|
||||
cryptoSetup.EXPECT().Close()
|
||||
packer.EXPECT().PackConnectionClose(expectedErr, gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
gomock.InOrder(
|
||||
tracer.EXPECT().ClosedConnection(expectedErr),
|
||||
tracer.EXPECT().Close(),
|
||||
|
@ -566,7 +566,7 @@ var _ = Describe("Connection", func() {
|
|||
close(returned)
|
||||
}()
|
||||
Consistently(returned).ShouldNot(BeClosed())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
conn.shutdown()
|
||||
|
@ -591,7 +591,7 @@ var _ = Describe("Connection", func() {
|
|||
return 3, protocol.PacketNumberLen2, protocol.KeyPhaseOne, b, nil
|
||||
})
|
||||
gomock.InOrder(
|
||||
tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any()),
|
||||
tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()),
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any()),
|
||||
tracer.EXPECT().Close(),
|
||||
)
|
||||
|
@ -610,14 +610,15 @@ var _ = Describe("Connection", func() {
|
|||
conn.handshakeConfirmed = true
|
||||
sconn := NewMockSendConn(mockCtrl)
|
||||
sconn.EXPECT().capabilities().AnyTimes()
|
||||
sconn.EXPECT().Write(gomock.Any(), gomock.Any()).Return(io.ErrClosedPipe).AnyTimes()
|
||||
sconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any()).Return(io.ErrClosedPipe).AnyTimes()
|
||||
conn.sendQueue = newSendQueue(sconn)
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().GetLossDetectionTimeout().Return(time.Now().Add(time.Hour)).AnyTimes()
|
||||
sph.EXPECT().ECNMode(true).Return(protocol.ECT1).AnyTimes()
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
// only expect a single SentPacket() call
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||
|
@ -778,7 +779,7 @@ var _ = Describe("Connection", func() {
|
|||
conn.receivedPacketHandler = rph
|
||||
packet.rcvTime = rcvTime
|
||||
tracer.EXPECT().StartedConnection(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), []logging.Frame{})
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), logging.ECNCE, []logging.Frame{})
|
||||
Expect(conn.handlePacketImpl(packet)).To(BeTrue())
|
||||
})
|
||||
|
||||
|
@ -796,7 +797,12 @@ var _ = Describe("Connection", func() {
|
|||
)
|
||||
conn.receivedPacketHandler = rph
|
||||
packet.rcvTime = rcvTime
|
||||
tracer.EXPECT().ReceivedShortHeaderPacket(&logging.ShortHeader{PacketNumber: 0x1337, PacketNumberLen: 2, KeyPhase: protocol.KeyPhaseZero}, protocol.ByteCount(len(packet.data)), []logging.Frame{&logging.PingFrame{}})
|
||||
tracer.EXPECT().ReceivedShortHeaderPacket(
|
||||
&logging.ShortHeader{PacketNumber: 0x1337, PacketNumberLen: 2, KeyPhase: protocol.KeyPhaseZero},
|
||||
protocol.ByteCount(len(packet.data)),
|
||||
logging.ECT1,
|
||||
[]logging.Frame{&logging.PingFrame{}},
|
||||
)
|
||||
Expect(conn.handlePacketImpl(packet)).To(BeTrue())
|
||||
})
|
||||
|
||||
|
@ -838,7 +844,7 @@ var _ = Describe("Connection", func() {
|
|||
// make the go routine return
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.closeLocal(errors.New("close"))
|
||||
Eventually(conn.Context().Done()).Should(BeClosed())
|
||||
})
|
||||
|
@ -850,8 +856,7 @@ var _ = Describe("Connection", func() {
|
|||
pn++
|
||||
return pn, protocol.PacketNumberLen2, protocol.KeyPhaseZero, []byte{0} /* PADDING frame */, nil
|
||||
}).Times(3)
|
||||
tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(hdr *logging.ShortHeader, _ protocol.ByteCount, _ []logging.Frame) {
|
||||
}).Times(3)
|
||||
tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
|
||||
packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version) // only expect a single call
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
|
@ -873,7 +878,7 @@ var _ = Describe("Connection", func() {
|
|||
expectReplaceWithClosed()
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.closeLocal(errors.New("close"))
|
||||
Eventually(conn.Context().Done()).Should(BeClosed())
|
||||
})
|
||||
|
@ -886,8 +891,7 @@ var _ = Describe("Connection", func() {
|
|||
pn++
|
||||
return pn, protocol.PacketNumberLen4, protocol.KeyPhaseZero, []byte{0} /* PADDING frame */, nil
|
||||
}).Times(3)
|
||||
tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(hdr *logging.ShortHeader, _ protocol.ByteCount, _ []logging.Frame) {
|
||||
}).Times(3)
|
||||
tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
|
||||
packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).Times(3)
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
|
@ -909,7 +913,7 @@ var _ = Describe("Connection", func() {
|
|||
expectReplaceWithClosed()
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.closeLocal(errors.New("close"))
|
||||
Eventually(conn.Context().Done()).Should(BeClosed())
|
||||
})
|
||||
|
@ -931,7 +935,7 @@ var _ = Describe("Connection", func() {
|
|||
close(done)
|
||||
}()
|
||||
expectReplaceWithClosed()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
packet := getShortHeaderPacket(srcConnID, 0x42, nil)
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
|
@ -959,7 +963,7 @@ var _ = Describe("Connection", func() {
|
|||
packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.shutdown()
|
||||
Eventually(conn.Context().Done()).Should(BeClosed())
|
||||
})
|
||||
|
@ -981,7 +985,7 @@ var _ = Describe("Connection", func() {
|
|||
close(done)
|
||||
}()
|
||||
expectReplaceWithClosed()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
conn.handlePacket(getShortHeaderPacket(srcConnID, 0x42, nil))
|
||||
|
@ -1021,7 +1025,7 @@ var _ = Describe("Connection", func() {
|
|||
}, nil)
|
||||
p1 := getLongHeaderPacket(hdr1, nil)
|
||||
tracer.EXPECT().StartedConnection(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(p1.data)), gomock.Any())
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(p1.data)), gomock.Any(), gomock.Any())
|
||||
Expect(conn.handlePacketImpl(p1)).To(BeTrue())
|
||||
// The next packet has to be ignored, since the source connection ID doesn't match.
|
||||
p2 := getLongHeaderPacket(hdr2, nil)
|
||||
|
@ -1054,7 +1058,7 @@ var _ = Describe("Connection", func() {
|
|||
unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).Return(protocol.PacketNumber(10), protocol.PacketNumberLen2, protocol.KeyPhaseZero, []byte{0} /* one PADDING frame */, nil)
|
||||
packet := getShortHeaderPacket(srcConnID, 0x42, nil)
|
||||
packet.remoteAddr = &net.IPAddr{IP: net.IPv4(192, 168, 0, 100)}
|
||||
tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet.data)), gomock.Any())
|
||||
tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet.data)), gomock.Any(), gomock.Any())
|
||||
Expect(conn.handlePacketImpl(packet)).To(BeTrue())
|
||||
})
|
||||
})
|
||||
|
@ -1094,12 +1098,13 @@ var _ = Describe("Connection", func() {
|
|||
})
|
||||
cryptoSetup.EXPECT().DiscardInitialKeys()
|
||||
tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionInitial)
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet.data)), gomock.Any())
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet.data)), gomock.Any(), gomock.Any())
|
||||
Expect(conn.handlePacketImpl(packet)).To(BeTrue())
|
||||
})
|
||||
|
||||
It("handles coalesced packets", func() {
|
||||
hdrLen1, packet1 := getPacketWithLength(srcConnID, 456)
|
||||
packet1.ecn = protocol.ECT1
|
||||
unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).DoAndReturn(func(_ *wire.Header, _ time.Time, data []byte, _ protocol.VersionNumber) (*unpackedPacket, error) {
|
||||
Expect(data).To(HaveLen(hdrLen1 + 456 - 3))
|
||||
return &unpackedPacket{
|
||||
|
@ -1126,8 +1131,8 @@ var _ = Describe("Connection", func() {
|
|||
tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionInitial).AnyTimes()
|
||||
cryptoSetup.EXPECT().DiscardInitialKeys().AnyTimes()
|
||||
gomock.InOrder(
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet1.data)), gomock.Any()),
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet2.data)), gomock.Any()),
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet1.data)), logging.ECT1, gomock.Any()),
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet2.data)), logging.ECT1, gomock.Any()),
|
||||
)
|
||||
packet1.data = append(packet1.data, packet2.data...)
|
||||
Expect(conn.handlePacketImpl(packet1)).To(BeTrue())
|
||||
|
@ -1152,7 +1157,7 @@ var _ = Describe("Connection", func() {
|
|||
cryptoSetup.EXPECT().DiscardInitialKeys().AnyTimes()
|
||||
gomock.InOrder(
|
||||
tracer.EXPECT().BufferedPacket(gomock.Any(), protocol.ByteCount(len(packet1.data))),
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet2.data)), gomock.Any()),
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet2.data)), gomock.Any(), gomock.Any()),
|
||||
)
|
||||
packet1.data = append(packet1.data, packet2.data...)
|
||||
Expect(conn.handlePacketImpl(packet1)).To(BeTrue())
|
||||
|
@ -1178,7 +1183,7 @@ var _ = Describe("Connection", func() {
|
|||
cryptoSetup.EXPECT().DiscardInitialKeys().AnyTimes()
|
||||
// don't EXPECT any more calls to unpacker.UnpackLongHeader()
|
||||
gomock.InOrder(
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet1.data)), gomock.Any()),
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet1.data)), gomock.Any(), gomock.Any()),
|
||||
tracer.EXPECT().DroppedPacket(gomock.Any(), protocol.ByteCount(len(packet2.data)), logging.PacketDropUnknownConnectionID),
|
||||
)
|
||||
packet1.data = append(packet1.data, packet2.data...)
|
||||
|
@ -1191,6 +1196,7 @@ var _ = Describe("Connection", func() {
|
|||
var (
|
||||
connDone chan struct{}
|
||||
sender *MockSender
|
||||
sph *mockackhandler.MockSentPacketHandler
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
|
@ -1199,14 +1205,17 @@ var _ = Describe("Connection", func() {
|
|||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
conn.sendQueue = sender
|
||||
connDone = make(chan struct{})
|
||||
sph = mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
conn.sentPacketHandler = sph
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||
sph.EXPECT().ECNMode(gomock.Any()).Return(protocol.ECNCE).MaxTimes(1)
|
||||
packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
expectReplaceWithClosed()
|
||||
cryptoSetup.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
sender.EXPECT().Close()
|
||||
|
@ -1227,12 +1236,11 @@ var _ = Describe("Connection", func() {
|
|||
|
||||
It("sends packets", func() {
|
||||
conn.handshakeConfirmed = true
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().TimeUntilSend().AnyTimes()
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.sentPacketHandler = sph
|
||||
sph.EXPECT().ECNMode(true).Return(protocol.ECNNon).AnyTimes()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
runConn()
|
||||
p := shortHeaderPacket{
|
||||
DestConnID: protocol.ParseConnectionID([]byte{1, 2, 3}),
|
||||
|
@ -1244,19 +1252,22 @@ var _ = Describe("Connection", func() {
|
|||
packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack).AnyTimes()
|
||||
sent := make(chan struct{})
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(*packetBuffer, protocol.ByteCount) { close(sent) })
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(sent) })
|
||||
tracer.EXPECT().SentShortHeaderPacket(&logging.ShortHeader{
|
||||
DestConnectionID: p.DestConnID,
|
||||
PacketNumber: p.PacketNumber,
|
||||
PacketNumberLen: p.PacketNumberLen,
|
||||
KeyPhase: p.KeyPhase,
|
||||
}, gomock.Any(), nil, []logging.Frame{})
|
||||
}, gomock.Any(), gomock.Any(), nil, []logging.Frame{})
|
||||
conn.scheduleSending()
|
||||
Eventually(sent).Should(BeClosed())
|
||||
})
|
||||
|
||||
It("doesn't send packets if there's nothing to send", func() {
|
||||
conn.handshakeConfirmed = true
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().ECNMode(true).AnyTimes()
|
||||
runConn()
|
||||
packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack).AnyTimes()
|
||||
conn.receivedPacketHandler.ReceivedPacket(0x035e, protocol.ECNNon, protocol.Encryption1RTT, time.Now(), true)
|
||||
|
@ -1265,13 +1276,12 @@ var _ = Describe("Connection", func() {
|
|||
})
|
||||
|
||||
It("sends ACK only packets", func() {
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().TimeUntilSend().AnyTimes()
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAck)
|
||||
sph.EXPECT().ECNMode(gomock.Any()).Return(protocol.ECT1).AnyTimes()
|
||||
done := make(chan struct{})
|
||||
packer.EXPECT().PackCoalescedPacket(true, gomock.Any(), conn.version).Do(func(bool, protocol.ByteCount, protocol.VersionNumber) { close(done) })
|
||||
conn.sentPacketHandler = sph
|
||||
runConn()
|
||||
conn.scheduleSending()
|
||||
Eventually(done).Should(BeClosed())
|
||||
|
@ -1279,12 +1289,11 @@ var _ = Describe("Connection", func() {
|
|||
|
||||
It("adds a BLOCKED frame when it is connection-level flow control blocked", func() {
|
||||
conn.handshakeConfirmed = true
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().TimeUntilSend().AnyTimes()
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.sentPacketHandler = sph
|
||||
sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
fc := mocks.NewMockConnectionFlowController(mockCtrl)
|
||||
fc.EXPECT().IsNewlyBlocked().Return(true, protocol.ByteCount(1337))
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 13}, []byte("foobar"))
|
||||
|
@ -1292,8 +1301,8 @@ var _ = Describe("Connection", func() {
|
|||
conn.connFlowController = fc
|
||||
runConn()
|
||||
sent := make(chan struct{})
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(*packetBuffer, protocol.ByteCount) { close(sent) })
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), nil, []logging.Frame{})
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(sent) })
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), nil, []logging.Frame{})
|
||||
conn.scheduleSending()
|
||||
Eventually(sent).Should(BeClosed())
|
||||
frames, _ := conn.framer.AppendControlFrames(nil, 1000, protocol.Version1)
|
||||
|
@ -1301,11 +1310,9 @@ var _ = Describe("Connection", func() {
|
|||
})
|
||||
|
||||
It("doesn't send when the SentPacketHandler doesn't allow it", func() {
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone).AnyTimes()
|
||||
sph.EXPECT().TimeUntilSend().AnyTimes()
|
||||
conn.sentPacketHandler = sph
|
||||
runConn()
|
||||
conn.scheduleSending()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
@ -1334,50 +1341,45 @@ var _ = Describe("Connection", func() {
|
|||
})
|
||||
|
||||
It("sends a probe packet", func() {
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().TimeUntilSend().AnyTimes()
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(sendMode)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
|
||||
sph.EXPECT().QueueProbePacket(encLevel)
|
||||
sph.EXPECT().ECNMode(gomock.Any())
|
||||
p := getCoalescedPacket(123, enc != protocol.Encryption1RTT)
|
||||
packer.EXPECT().MaybePackProbePacket(encLevel, gomock.Any(), conn.version).Return(p, nil)
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ time.Time, pn, _ protocol.PacketNumber, _ []ackhandler.StreamFrame, _ []ackhandler.Frame, _ protocol.EncryptionLevel, _ protocol.ByteCount, _ bool) {
|
||||
Expect(pn).To(Equal(protocol.PacketNumber(123)))
|
||||
})
|
||||
sph.EXPECT().SentPacket(gomock.Any(), protocol.PacketNumber(123), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.sentPacketHandler = sph
|
||||
runConn()
|
||||
sent := make(chan struct{})
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(*packetBuffer, protocol.ByteCount) { close(sent) })
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(sent) })
|
||||
if enc == protocol.Encryption1RTT {
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), p.shortHdrPacket.Length, gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), p.shortHdrPacket.Length, gomock.Any(), gomock.Any(), gomock.Any())
|
||||
} else {
|
||||
tracer.EXPECT().SentLongHeaderPacket(gomock.Any(), p.longHdrPackets[0].length, gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().SentLongHeaderPacket(gomock.Any(), p.longHdrPackets[0].length, gomock.Any(), gomock.Any(), gomock.Any())
|
||||
}
|
||||
conn.scheduleSending()
|
||||
Eventually(sent).Should(BeClosed())
|
||||
})
|
||||
|
||||
It("sends a PING as a probe packet", func() {
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().TimeUntilSend().AnyTimes()
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(sendMode)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
|
||||
sph.EXPECT().ECNMode(gomock.Any()).Return(protocol.ECT0)
|
||||
sph.EXPECT().QueueProbePacket(encLevel).Return(false)
|
||||
p := getCoalescedPacket(123, enc != protocol.Encryption1RTT)
|
||||
packer.EXPECT().MaybePackProbePacket(encLevel, gomock.Any(), conn.version).Return(p, nil)
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ time.Time, pn, _ protocol.PacketNumber, _ []ackhandler.StreamFrame, _ []ackhandler.Frame, _ protocol.EncryptionLevel, _ protocol.ByteCount, _ bool) {
|
||||
Expect(pn).To(Equal(protocol.PacketNumber(123)))
|
||||
})
|
||||
conn.sentPacketHandler = sph
|
||||
sph.EXPECT().SentPacket(gomock.Any(), protocol.PacketNumber(123), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
runConn()
|
||||
sent := make(chan struct{})
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(*packetBuffer, protocol.ByteCount) { close(sent) })
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(sent) })
|
||||
if enc == protocol.Encryption1RTT {
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), p.shortHdrPacket.Length, gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), p.shortHdrPacket.Length, logging.ECT0, gomock.Any(), gomock.Any())
|
||||
} else {
|
||||
tracer.EXPECT().SentLongHeaderPacket(gomock.Any(), p.longHdrPackets[0].length, gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().SentLongHeaderPacket(gomock.Any(), p.longHdrPackets[0].length, logging.ECT0, gomock.Any(), gomock.Any())
|
||||
}
|
||||
conn.scheduleSending()
|
||||
Eventually(sent).Should(BeClosed())
|
||||
|
@ -1396,7 +1398,7 @@ var _ = Describe("Connection", func() {
|
|||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||
sph = mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
conn.handshakeConfirmed = true
|
||||
|
@ -1410,10 +1412,11 @@ var _ = Describe("Connection", func() {
|
|||
|
||||
AfterEach(func() {
|
||||
// make the go routine return
|
||||
sph.EXPECT().ECNMode(gomock.Any()).MaxTimes(1)
|
||||
packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
expectReplaceWithClosed()
|
||||
cryptoSetup.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
sender.EXPECT().Close()
|
||||
|
@ -1422,17 +1425,18 @@ var _ = Describe("Connection", func() {
|
|||
})
|
||||
|
||||
It("sends multiple packets one by one immediately", func() {
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2)
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(2)
|
||||
sph.EXPECT().ECNMode(gomock.Any()).Times(2)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited)
|
||||
sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour))
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, []byte("packet10"))
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, []byte("packet11"))
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(b *packetBuffer, _ protocol.ByteCount) {
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
||||
Expect(b.Data).To(Equal([]byte("packet10")))
|
||||
})
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(b *packetBuffer, _ protocol.ByteCount) {
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
||||
Expect(b.Data).To(Equal([]byte("packet11")))
|
||||
})
|
||||
go func() {
|
||||
|
@ -1447,7 +1451,8 @@ var _ = Describe("Connection", func() {
|
|||
|
||||
It("sends multiple packets one by one immediately, with GSO", func() {
|
||||
enableGSO()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2)
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2)
|
||||
sph.EXPECT().ECNMode(true).Return(protocol.ECT1).Times(4)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
|
||||
payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload1)
|
||||
|
@ -1457,7 +1462,7 @@ var _ = Describe("Connection", func() {
|
|||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2)
|
||||
packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any()).Return(shortHeaderPacket{}, errNothingToPack)
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), conn.mtuDiscoverer.CurrentSize()).Do(func(b *packetBuffer, l protocol.ByteCount) {
|
||||
sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
||||
Expect(b.Data).To(Equal(append(payload1, payload2...)))
|
||||
})
|
||||
go func() {
|
||||
|
@ -1472,19 +1477,59 @@ var _ = Describe("Connection", func() {
|
|||
|
||||
It("stops appending packets when a smaller packet is packed, with GSO", func() {
|
||||
enableGSO()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(2)
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
|
||||
sph.EXPECT().ECNMode(true).Times(4)
|
||||
payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload1)
|
||||
payload2 := make([]byte, conn.mtuDiscoverer.CurrentSize()-1)
|
||||
rand.Read(payload2)
|
||||
payload3 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload3)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, payload1)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 12}, payload3)
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), conn.mtuDiscoverer.CurrentSize()).Do(func(b *packetBuffer, l protocol.ByteCount) {
|
||||
sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
||||
Expect(b.Data).To(Equal(append(payload1, payload2...)))
|
||||
})
|
||||
sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
||||
Expect(b.Data).To(Equal(payload3))
|
||||
})
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||
cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
|
||||
conn.run()
|
||||
}()
|
||||
conn.scheduleSending()
|
||||
time.Sleep(50 * time.Millisecond) // make sure that only 2 packets are sent
|
||||
})
|
||||
|
||||
It("stops appending packets when the ECN marking changes, with GSO", func() {
|
||||
enableGSO()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
|
||||
sph.EXPECT().ECNMode(true).Return(protocol.ECT1).Times(2)
|
||||
sph.EXPECT().ECNMode(true).Return(protocol.ECT0).Times(2)
|
||||
payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload1)
|
||||
payload2 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload2)
|
||||
payload3 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload3)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, payload1)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload3)
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
||||
Expect(b.Data).To(Equal(append(payload1, payload2...)))
|
||||
})
|
||||
sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
||||
Expect(b.Data).To(Equal(payload3))
|
||||
})
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||
|
@ -1496,12 +1541,13 @@ var _ = Describe("Connection", func() {
|
|||
})
|
||||
|
||||
It("sends multiple packets, when the pacer allows immediate sending", func() {
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(2)
|
||||
sph.EXPECT().ECNMode(gomock.Any()).Times(2)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, []byte("packet10"))
|
||||
packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any())
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||
|
@ -1513,13 +1559,14 @@ var _ = Describe("Connection", func() {
|
|||
})
|
||||
|
||||
It("allows an ACK to be sent when pacing limited", func() {
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour))
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited)
|
||||
sph.EXPECT().ECNMode(gomock.Any())
|
||||
packer.EXPECT().PackAckOnlyPacket(gomock.Any(), conn.version).Return(shortHeaderPacket{PacketNumber: 123}, getPacketBuffer(), nil)
|
||||
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any())
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||
|
@ -1533,12 +1580,13 @@ var _ = Describe("Connection", func() {
|
|||
// when becoming congestion limited, at some point the SendMode will change from SendAny to SendAck
|
||||
// we shouldn't send the ACK in the same run
|
||||
It("doesn't send an ACK right after becoming congestion limited", func() {
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAck)
|
||||
sph.EXPECT().ECNMode(gomock.Any()).Times(2)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 100}, []byte("packet100"))
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any())
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||
|
@ -1553,19 +1601,21 @@ var _ = Describe("Connection", func() {
|
|||
pacingDelay := scaleDuration(100 * time.Millisecond)
|
||||
gomock.InOrder(
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny),
|
||||
sph.EXPECT().ECNMode(gomock.Any()),
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 100}, []byte("packet100")),
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()),
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()),
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited),
|
||||
sph.EXPECT().TimeUntilSend().Return(time.Now().Add(pacingDelay)),
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny),
|
||||
sph.EXPECT().ECNMode(gomock.Any()),
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 101}, []byte("packet101")),
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()),
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()),
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited),
|
||||
sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour)),
|
||||
)
|
||||
written := make(chan struct{}, 2)
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, protocol.ByteCount) { written <- struct{}{} }).Times(2)
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { written <- struct{}{} }).Times(2)
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||
|
@ -1579,8 +1629,9 @@ var _ = Describe("Connection", func() {
|
|||
})
|
||||
|
||||
It("sends multiple packets at once", func() {
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
|
||||
sph.EXPECT().ECNMode(gomock.Any()).Times(3)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited)
|
||||
sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour))
|
||||
for pn := protocol.PacketNumber(1000); pn < 1003; pn++ {
|
||||
|
@ -1588,7 +1639,7 @@ var _ = Describe("Connection", func() {
|
|||
}
|
||||
written := make(chan struct{}, 3)
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, protocol.ByteCount) { written <- struct{}{} }).Times(3)
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { written <- struct{}{} }).Times(3)
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||
|
@ -1619,11 +1670,12 @@ var _ = Describe("Connection", func() {
|
|||
|
||||
written := make(chan struct{})
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 1000}, []byte("packet1000"))
|
||||
packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, protocol.ByteCount) { close(written) })
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { close(written) })
|
||||
available <- struct{}{}
|
||||
Eventually(written).Should(BeClosed())
|
||||
})
|
||||
|
@ -1640,14 +1692,15 @@ var _ = Describe("Connection", func() {
|
|||
|
||||
written := make(chan struct{})
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(time.Time, protocol.PacketNumber, protocol.PacketNumber, []ackhandler.StreamFrame, []ackhandler.Frame, protocol.EncryptionLevel, protocol.ByteCount, bool) {
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(time.Time, protocol.PacketNumber, protocol.PacketNumber, []ackhandler.StreamFrame, []ackhandler.Frame, protocol.EncryptionLevel, protocol.ECN, protocol.ByteCount, bool) {
|
||||
sph.EXPECT().ReceivedBytes(gomock.Any())
|
||||
conn.handlePacket(receivedPacket{buffer: getPacketBuffer()})
|
||||
})
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, []byte("packet10"))
|
||||
packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, protocol.ByteCount) { close(written) })
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { close(written) })
|
||||
|
||||
conn.scheduleSending()
|
||||
time.Sleep(scaleDuration(50 * time.Millisecond))
|
||||
|
@ -1656,13 +1709,14 @@ var _ = Describe("Connection", func() {
|
|||
})
|
||||
|
||||
It("stops sending when the send queue is full", func() {
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny)
|
||||
sph.EXPECT().ECNMode(gomock.Any())
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 1000}, []byte("packet1000"))
|
||||
written := make(chan struct{}, 1)
|
||||
sender.EXPECT().WouldBlock()
|
||||
sender.EXPECT().WouldBlock().Return(true).Times(2)
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, protocol.ByteCount) { written <- struct{}{} })
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { written <- struct{}{} })
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||
|
@ -1676,12 +1730,13 @@ var _ = Describe("Connection", func() {
|
|||
time.Sleep(scaleDuration(50 * time.Millisecond))
|
||||
|
||||
// now make room in the send queue
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 1001}, []byte("packet1001"))
|
||||
packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, protocol.ByteCount) { written <- struct{}{} })
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { written <- struct{}{} })
|
||||
available <- struct{}{}
|
||||
Eventually(written).Should(Receive())
|
||||
|
||||
|
@ -1692,6 +1747,7 @@ var _ = Describe("Connection", func() {
|
|||
|
||||
It("doesn't set a pacing timer when there is no data to send", func() {
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
|
||||
// don't EXPECT any calls to mconn.Write()
|
||||
|
@ -1709,12 +1765,13 @@ var _ = Describe("Connection", func() {
|
|||
mtuDiscoverer := NewMockMTUDiscoverer(mockCtrl)
|
||||
conn.mtuDiscoverer = mtuDiscoverer
|
||||
conn.config.DisablePathMTUDiscovery = false
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny)
|
||||
sph.EXPECT().ECNMode(true)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
|
||||
written := make(chan struct{}, 1)
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, protocol.ByteCount) { written <- struct{}{} })
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { written <- struct{}{} })
|
||||
mtuDiscoverer.EXPECT().ShouldSendProbe(gomock.Any()).Return(true)
|
||||
ping := ackhandler.Frame{Frame: &wire.PingFrame{}}
|
||||
mtuDiscoverer.EXPECT().GetPing().Return(ping, protocol.ByteCount(1234))
|
||||
|
@ -1748,7 +1805,7 @@ var _ = Describe("Connection", func() {
|
|||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||
packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
cryptoSetup.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sender.EXPECT().Close()
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
|
@ -1761,8 +1818,9 @@ var _ = Describe("Connection", func() {
|
|||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().TimeUntilSend().AnyTimes()
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
|
||||
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.sentPacketHandler = sph
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 1}, []byte("packet1"))
|
||||
packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
|
||||
|
@ -1777,8 +1835,8 @@ var _ = Describe("Connection", func() {
|
|||
time.Sleep(50 * time.Millisecond)
|
||||
// only EXPECT calls after scheduleSending is called
|
||||
written := make(chan struct{})
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(*packetBuffer, protocol.ByteCount) { close(written) })
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(written) })
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||
conn.scheduleSending()
|
||||
Eventually(written).Should(BeClosed())
|
||||
})
|
||||
|
@ -1789,9 +1847,8 @@ var _ = Describe("Connection", func() {
|
|||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ time.Time, pn, _ protocol.PacketNumber, _ []ackhandler.StreamFrame, _ []ackhandler.Frame, _ protocol.EncryptionLevel, _ protocol.ByteCount, _ bool) {
|
||||
Expect(pn).To(Equal(protocol.PacketNumber(1234)))
|
||||
})
|
||||
sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), protocol.PacketNumber(1234), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.sentPacketHandler = sph
|
||||
rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl)
|
||||
rph.EXPECT().GetAlarmTimeout().Return(time.Now().Add(10 * time.Millisecond))
|
||||
|
@ -1800,8 +1857,8 @@ var _ = Describe("Connection", func() {
|
|||
conn.receivedPacketHandler = rph
|
||||
|
||||
written := make(chan struct{})
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(*packetBuffer, protocol.ByteCount) { close(written) })
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(written) })
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||
|
@ -1842,30 +1899,23 @@ var _ = Describe("Connection", func() {
|
|||
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().ECNMode(false).Return(protocol.ECT1).AnyTimes()
|
||||
sph.EXPECT().TimeUntilSend().Return(time.Now()).AnyTimes()
|
||||
gomock.InOrder(
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ time.Time, pn, _ protocol.PacketNumber, _ []ackhandler.StreamFrame, _ []ackhandler.Frame, encLevel protocol.EncryptionLevel, size protocol.ByteCount, _ bool) {
|
||||
Expect(encLevel).To(Equal(protocol.EncryptionInitial))
|
||||
Expect(pn).To(Equal(protocol.PacketNumber(13)))
|
||||
Expect(size).To(BeEquivalentTo(123))
|
||||
}),
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ time.Time, pn, _ protocol.PacketNumber, _ []ackhandler.StreamFrame, _ []ackhandler.Frame, encLevel protocol.EncryptionLevel, size protocol.ByteCount, _ bool) {
|
||||
Expect(encLevel).To(Equal(protocol.EncryptionHandshake))
|
||||
Expect(pn).To(Equal(protocol.PacketNumber(37)))
|
||||
Expect(size).To(BeEquivalentTo(1234))
|
||||
}),
|
||||
sph.EXPECT().SentPacket(gomock.Any(), protocol.PacketNumber(13), gomock.Any(), gomock.Any(), gomock.Any(), protocol.EncryptionInitial, protocol.ECT1, protocol.ByteCount(123), gomock.Any()),
|
||||
sph.EXPECT().SentPacket(gomock.Any(), protocol.PacketNumber(37), gomock.Any(), gomock.Any(), gomock.Any(), protocol.EncryptionHandshake, protocol.ECT1, protocol.ByteCount(1234), gomock.Any()),
|
||||
)
|
||||
gomock.InOrder(
|
||||
tracer.EXPECT().SentLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(hdr *wire.ExtendedHeader, _ protocol.ByteCount, _ *wire.AckFrame, _ []logging.Frame) {
|
||||
tracer.EXPECT().SentLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(hdr *wire.ExtendedHeader, _ protocol.ByteCount, _ logging.ECN, _ *wire.AckFrame, _ []logging.Frame) {
|
||||
Expect(hdr.Type).To(Equal(protocol.PacketTypeInitial))
|
||||
}),
|
||||
tracer.EXPECT().SentLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(hdr *wire.ExtendedHeader, _ protocol.ByteCount, _ *wire.AckFrame, _ []logging.Frame) {
|
||||
tracer.EXPECT().SentLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(hdr *wire.ExtendedHeader, _ protocol.ByteCount, _ logging.ECN, _ *wire.AckFrame, _ []logging.Frame) {
|
||||
Expect(hdr.Type).To(Equal(protocol.PacketTypeHandshake))
|
||||
}),
|
||||
)
|
||||
|
||||
sent := make(chan struct{})
|
||||
mconn.EXPECT().Write([]byte("foobar"), protocol.ByteCount(6)).Do(func([]byte, protocol.ByteCount) { close(sent) })
|
||||
mconn.EXPECT().Write([]byte("foobar"), uint16(0), protocol.ECT1).Do(func([]byte, uint16, protocol.ECN) { close(sent) })
|
||||
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
|
@ -1882,7 +1932,7 @@ var _ = Describe("Connection", func() {
|
|||
expectReplaceWithClosed()
|
||||
packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
cryptoSetup.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
conn.shutdown()
|
||||
|
@ -1953,7 +2003,7 @@ var _ = Describe("Connection", func() {
|
|||
}()
|
||||
handshakeCtx := conn.HandshakeComplete()
|
||||
Consistently(handshakeCtx).ShouldNot(BeClosed())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.closeLocal(errors.New("handshake error"))
|
||||
Consistently(handshakeCtx).ShouldNot(BeClosed())
|
||||
Eventually(conn.Context().Done()).Should(BeClosed())
|
||||
|
@ -1962,12 +2012,13 @@ var _ = Describe("Connection", func() {
|
|||
It("sends a HANDSHAKE_DONE frame when the handshake completes", func() {
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().TimeUntilSend().AnyTimes()
|
||||
sph.EXPECT().SetHandshakeConfirmed()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.sentPacketHandler = sph
|
||||
done := make(chan struct{})
|
||||
connRunner.EXPECT().Retire(clientDestConnID)
|
||||
|
@ -1988,7 +2039,7 @@ var _ = Describe("Connection", func() {
|
|||
cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
|
||||
cryptoSetup.EXPECT().SetHandshakeConfirmed()
|
||||
cryptoSetup.EXPECT().GetSessionTicket()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
Expect(conn.handleHandshakeComplete()).To(Succeed())
|
||||
conn.run()
|
||||
}()
|
||||
|
@ -2017,7 +2068,7 @@ var _ = Describe("Connection", func() {
|
|||
expectReplaceWithClosed()
|
||||
packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
cryptoSetup.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
conn.shutdown()
|
||||
|
@ -2044,7 +2095,7 @@ var _ = Describe("Connection", func() {
|
|||
expectReplaceWithClosed()
|
||||
packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
cryptoSetup.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
Expect(conn.CloseWithError(0x1337, testErr.Error())).To(Succeed())
|
||||
|
@ -2103,7 +2154,7 @@ var _ = Describe("Connection", func() {
|
|||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||
packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
cryptoSetup.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
conn.shutdown()
|
||||
|
@ -2202,7 +2253,7 @@ var _ = Describe("Connection", func() {
|
|||
|
||||
It("times out due to non-completed handshake", func() {
|
||||
conn.handshakeComplete = false
|
||||
conn.creationTime = time.Now().Add(-protocol.DefaultHandshakeTimeout).Add(-time.Second)
|
||||
conn.creationTime = time.Now().Add(-2 * protocol.DefaultHandshakeIdleTimeout).Add(-time.Second)
|
||||
connRunner.EXPECT().Remove(gomock.Any()).Times(2)
|
||||
cryptoSetup.EXPECT().Close()
|
||||
gomock.InOrder(
|
||||
|
@ -2256,13 +2307,13 @@ var _ = Describe("Connection", func() {
|
|||
// make the go routine return
|
||||
expectReplaceWithClosed()
|
||||
cryptoSetup.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
conn.shutdown()
|
||||
Eventually(conn.Context().Done()).Should(BeClosed())
|
||||
})
|
||||
|
||||
It("closes the connection due to the idle timeout before handshake", func() {
|
||||
conn.config.HandshakeIdleTimeout = 0
|
||||
conn.config.HandshakeIdleTimeout = scaleDuration(25 * time.Millisecond)
|
||||
packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).AnyTimes()
|
||||
connRunner.EXPECT().Remove(gomock.Any()).AnyTimes()
|
||||
cryptoSetup.EXPECT().Close()
|
||||
|
@ -2339,7 +2390,7 @@ var _ = Describe("Connection", func() {
|
|||
packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
expectReplaceWithClosed()
|
||||
cryptoSetup.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
conn.shutdown()
|
||||
|
@ -2491,7 +2542,8 @@ var _ = Describe("Client Connection", func() {
|
|||
tlsConf = &tls.Config{}
|
||||
}
|
||||
connRunner = NewMockConnRunner(mockCtrl)
|
||||
tracer = mocklogging.NewMockConnectionTracer(mockCtrl)
|
||||
var tr *logging.ConnectionTracer
|
||||
tr, tracer = mocklogging.NewMockConnectionTracer(mockCtrl)
|
||||
tracer.EXPECT().NegotiatedVersion(gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1)
|
||||
tracer.EXPECT().SentTransportParameters(gomock.Any())
|
||||
tracer.EXPECT().UpdatedKeyFromTLS(gomock.Any(), gomock.Any()).AnyTimes()
|
||||
|
@ -2507,7 +2559,7 @@ var _ = Describe("Client Connection", func() {
|
|||
42, // initial packet number
|
||||
false,
|
||||
false,
|
||||
tracer,
|
||||
tr,
|
||||
1234,
|
||||
utils.DefaultLogger,
|
||||
protocol.Version1,
|
||||
|
@ -2542,7 +2594,7 @@ var _ = Describe("Client Connection", func() {
|
|||
},
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
}, []byte("foobar"))
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), p.Size(), []logging.Frame{})
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), p.Size(), gomock.Any(), []logging.Frame{})
|
||||
Expect(conn.handlePacketImpl(p)).To(BeTrue())
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
|
@ -2555,7 +2607,7 @@ var _ = Describe("Client Connection", func() {
|
|||
packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||
cryptoSetup.EXPECT().Close()
|
||||
connRunner.EXPECT().ReplaceWithClosed([]protocol.ConnectionID{srcConnID}, gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any()).MaxTimes(1)
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1)
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||
tracer.EXPECT().Close()
|
||||
conn.shutdown()
|
||||
|
@ -2586,7 +2638,7 @@ var _ = Describe("Client Connection", func() {
|
|||
DestConnectionID: srcConnID,
|
||||
SrcConnectionID: destConnID,
|
||||
}
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
Expect(conn.handleLongHeaderPacket(receivedPacket{buffer: getPacketBuffer()}, hdr)).To(BeTrue())
|
||||
})
|
||||
|
||||
|
@ -2768,9 +2820,10 @@ var _ = Describe("Client Connection", func() {
|
|||
}
|
||||
|
||||
It("handles Retry packets", func() {
|
||||
now := time.Now()
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
conn.sentPacketHandler = sph
|
||||
sph.EXPECT().ResetForRetry()
|
||||
sph.EXPECT().ResetForRetry(now)
|
||||
sph.EXPECT().ReceivedBytes(gomock.Any())
|
||||
cryptoSetup.EXPECT().ChangeConnectionID(protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}))
|
||||
packer.EXPECT().SetToken([]byte("foobar"))
|
||||
|
@ -2779,7 +2832,9 @@ var _ = Describe("Client Connection", func() {
|
|||
Expect(hdr.SrcConnectionID).To(Equal(retryHdr.SrcConnectionID))
|
||||
Expect(hdr.Token).To(Equal(retryHdr.Token))
|
||||
})
|
||||
Expect(conn.handlePacketImpl(getPacket(retryHdr, getRetryTag(retryHdr)))).To(BeTrue())
|
||||
p := getPacket(retryHdr, getRetryTag(retryHdr))
|
||||
p.rcvTime = now
|
||||
Expect(conn.handlePacketImpl(p)).To(BeTrue())
|
||||
})
|
||||
|
||||
It("ignores Retry packets after receiving a regular packet", func() {
|
||||
|
@ -2849,7 +2904,7 @@ var _ = Describe("Client Connection", func() {
|
|||
packer.EXPECT().PackConnectionClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil).MaxTimes(1)
|
||||
}
|
||||
cryptoSetup.EXPECT().Close()
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any())
|
||||
mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
gomock.InOrder(
|
||||
tracer.EXPECT().ClosedConnection(gomock.Any()),
|
||||
tracer.EXPECT().Close(),
|
||||
|
@ -3095,7 +3150,7 @@ var _ = Describe("Client Connection", func() {
|
|||
hdr: hdr1,
|
||||
data: []byte{0}, // one PADDING frame
|
||||
}, nil)
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
Expect(conn.handlePacketImpl(getPacket(hdr1, nil))).To(BeTrue())
|
||||
// The next packet has to be ignored, since the source connection ID doesn't match.
|
||||
tracer.EXPECT().DroppedPacket(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
|
@ -3122,7 +3177,7 @@ var _ = Describe("Client Connection", func() {
|
|||
It("fails on Initial-level ACK for unsent packet", func() {
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 2}}}
|
||||
initialPacket := testutils.ComposeInitialPacket(destConnID, srcConnID, conn.version, destConnID, []wire.Frame{ack})
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
Expect(conn.handlePacketImpl(wrapPacket(initialPacket))).To(BeFalse())
|
||||
})
|
||||
|
||||
|
@ -3134,7 +3189,7 @@ var _ = Describe("Client Connection", func() {
|
|||
ReasonPhrase: "mitm attacker",
|
||||
}
|
||||
initialPacket := testutils.ComposeInitialPacket(destConnID, srcConnID, conn.version, destConnID, []wire.Frame{connCloseFrame})
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any())
|
||||
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
Expect(conn.handlePacketImpl(wrapPacket(initialPacket))).To(BeTrue())
|
||||
})
|
||||
|
||||
|
@ -3144,7 +3199,7 @@ var _ = Describe("Client Connection", func() {
|
|||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
conn.sentPacketHandler = sph
|
||||
sph.EXPECT().ReceivedBytes(gomock.Any()).Times(2)
|
||||
sph.EXPECT().ResetForRetry()
|
||||
sph.EXPECT().ResetForRetry(gomock.Any())
|
||||
newSrcConnID := protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef})
|
||||
cryptoSetup.EXPECT().ChangeConnectionID(newSrcConnID)
|
||||
packer.EXPECT().SetToken([]byte("foobar"))
|
||||
|
|
|
@ -30,17 +30,10 @@ type cryptoStreamImpl struct {
|
|||
|
||||
writeOffset protocol.ByteCount
|
||||
writeBuf []byte
|
||||
|
||||
// Reassemble TLS handshake messages before returning them from GetCryptoData.
|
||||
// This is only needed because crypto/tls doesn't correctly handle post-handshake messages.
|
||||
onlyCompleteMsg bool
|
||||
}
|
||||
|
||||
func newCryptoStream(onlyCompleteMsg bool) cryptoStream {
|
||||
return &cryptoStreamImpl{
|
||||
queue: newFrameSorter(),
|
||||
onlyCompleteMsg: onlyCompleteMsg,
|
||||
}
|
||||
func newCryptoStream() cryptoStream {
|
||||
return &cryptoStreamImpl{queue: newFrameSorter()}
|
||||
}
|
||||
|
||||
func (s *cryptoStreamImpl) HandleCryptoFrame(f *wire.CryptoFrame) error {
|
||||
|
@ -78,20 +71,6 @@ func (s *cryptoStreamImpl) HandleCryptoFrame(f *wire.CryptoFrame) error {
|
|||
|
||||
// GetCryptoData retrieves data that was received in CRYPTO frames
|
||||
func (s *cryptoStreamImpl) GetCryptoData() []byte {
|
||||
if s.onlyCompleteMsg {
|
||||
if len(s.msgBuf) < 4 {
|
||||
return nil
|
||||
}
|
||||
msgLen := 4 + int(s.msgBuf[1])<<16 + int(s.msgBuf[2])<<8 + int(s.msgBuf[3])
|
||||
if len(s.msgBuf) < msgLen {
|
||||
return nil
|
||||
}
|
||||
msg := make([]byte, msgLen)
|
||||
copy(msg, s.msgBuf[:msgLen])
|
||||
s.msgBuf = s.msgBuf[msgLen:]
|
||||
return msg
|
||||
}
|
||||
|
||||
b := s.msgBuf
|
||||
s.msgBuf = nil
|
||||
return b
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package quic
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
|
||||
"github.com/refraction-networking/uquic/internal/protocol"
|
||||
|
@ -16,7 +15,7 @@ var _ = Describe("Crypto Stream", func() {
|
|||
var str cryptoStream
|
||||
|
||||
BeforeEach(func() {
|
||||
str = newCryptoStream(false)
|
||||
str = newCryptoStream()
|
||||
})
|
||||
|
||||
Context("handling incoming data", func() {
|
||||
|
@ -138,23 +137,4 @@ var _ = Describe("Crypto Stream", func() {
|
|||
Expect(f.Data).To(Equal([]byte("bar")))
|
||||
})
|
||||
})
|
||||
|
||||
It("reassembles data", func() {
|
||||
str = newCryptoStream(true)
|
||||
data := make([]byte, 1337)
|
||||
l := len(data) - 4
|
||||
data[1] = uint8(l >> 16)
|
||||
data[2] = uint8(l >> 8)
|
||||
data[3] = uint8(l)
|
||||
rand.Read(data[4:])
|
||||
|
||||
for i, b := range data {
|
||||
Expect(str.GetCryptoData()).To(BeEmpty())
|
||||
Expect(str.HandleCryptoFrame(&wire.CryptoFrame{
|
||||
Offset: protocol.ByteCount(i),
|
||||
Data: []byte{b},
|
||||
})).To(Succeed())
|
||||
}
|
||||
Expect(str.GetCryptoData()).To(Equal(data))
|
||||
})
|
||||
})
|
||||
|
|
|
@ -59,7 +59,7 @@ func main() {
|
|||
|
||||
var qconf quic.Config
|
||||
if *enableQlog {
|
||||
qconf.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) logging.ConnectionTracer {
|
||||
qconf.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer {
|
||||
filename := fmt.Sprintf("client_%x.qlog", connID)
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
|
|
|
@ -163,7 +163,7 @@ func main() {
|
|||
handler := setupHandler(*www)
|
||||
quicConf := &quic.Config{}
|
||||
if *enableQlog {
|
||||
quicConf.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) logging.ConnectionTracer {
|
||||
quicConf.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer {
|
||||
filename := fmt.Sprintf("server_%x.qlog", connID)
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
|
|
|
@ -2,24 +2,22 @@ package tokens
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math/rand"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/refraction-networking/uquic"
|
||||
"github.com/refraction-networking/uquic/internal/handshake"
|
||||
"github.com/refraction-networking/uquic/internal/protocol"
|
||||
)
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
if len(data) < 8 {
|
||||
if len(data) < 32 {
|
||||
return -1
|
||||
}
|
||||
seed := binary.BigEndian.Uint64(data[:8])
|
||||
data = data[8:]
|
||||
tg, err := handshake.NewTokenGenerator(rand.New(rand.NewSource(int64(seed))))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var key quic.TokenGeneratorKey
|
||||
copy(key[:], data[:32])
|
||||
data = data[32:]
|
||||
tg := handshake.NewTokenGenerator(key)
|
||||
if len(data) < 1 {
|
||||
return -1
|
||||
}
|
||||
|
|
30
go.mod
30
go.mod
|
@ -4,32 +4,32 @@ go 1.20
|
|||
|
||||
require (
|
||||
github.com/francoispqt/gojay v1.2.13
|
||||
github.com/gaukas/clienthellod v0.4.0
|
||||
github.com/onsi/ginkgo/v2 v2.12.0
|
||||
github.com/onsi/gomega v1.27.10
|
||||
github.com/gaukas/clienthellod v0.4.2
|
||||
github.com/onsi/ginkgo/v2 v2.13.0
|
||||
github.com/onsi/gomega v1.29.0
|
||||
github.com/quic-go/qpack v0.4.0
|
||||
github.com/refraction-networking/utls v1.5.2
|
||||
go.uber.org/mock v0.2.0
|
||||
github.com/refraction-networking/utls v1.5.4
|
||||
go.uber.org/mock v0.3.0
|
||||
golang.org/x/crypto v0.14.0
|
||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
|
||||
golang.org/x/net v0.17.0
|
||||
golang.org/x/sync v0.3.0
|
||||
golang.org/x/sync v0.4.0
|
||||
golang.org/x/sys v0.13.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/cloudflare/circl v1.3.3 // indirect
|
||||
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||
github.com/cloudflare/circl v1.3.5 // indirect
|
||||
github.com/gaukas/godicttls v0.0.4 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/gopacket v1.1.19 // indirect
|
||||
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
github.com/quic-go/quic-go v0.38.1 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect
|
||||
github.com/klauspost/compress v1.17.2 // indirect
|
||||
github.com/quic-go/quic-go v0.39.2 // indirect
|
||||
golang.org/x/mod v0.13.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect
|
||||
golang.org/x/tools v0.14.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
62
go.sum
62
go.sum
|
@ -8,15 +8,15 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1
|
|||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
|
||||
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
|
||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/cloudflare/circl v1.3.5 h1:g+wWynZqVALYAlpSQFAa7TscDnUK8mKYtrxMpw6AUKo=
|
||||
github.com/cloudflare/circl v1.3.5/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
@ -26,8 +26,8 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI
|
|||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gaukas/clienthellod v0.4.0 h1:DySeZT4c3Xw6OGMzHRlAuOHx9q1P7vQNjA7YkyHrqac=
|
||||
github.com/gaukas/clienthellod v0.4.0/go.mod h1:gjt7a7cNNzZV4yTe0jKcXtj0a7u6RL2KQvijxFOvcZE=
|
||||
github.com/gaukas/clienthellod v0.4.2 h1:LPJ+LSeqt99pqeCV4C0cllk+pyWmERisP7w6qWr7eqE=
|
||||
github.com/gaukas/clienthellod v0.4.2/go.mod h1:M57+dsu0ZScvmdnNxaxsDPM46WhSEdPYAOdNgfL7IKA=
|
||||
github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
|
||||
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
|
@ -47,16 +47,16 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
|||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ=
|
||||
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0=
|
||||
github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
|
@ -66,8 +66,8 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0
|
|||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
|
||||
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
|
@ -82,10 +82,10 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
|||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||
github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
|
||||
github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
|
||||
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
|
||||
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
@ -96,10 +96,10 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q
|
|||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE=
|
||||
github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4=
|
||||
github.com/refraction-networking/utls v1.5.2 h1:l6diiLbEoRqdQ+/osPDO0z0lTc8O8VZV+p82N+Hi+ws=
|
||||
github.com/refraction-networking/utls v1.5.2/go.mod h1:SPuDbBmgLGp8s+HLNc83FuavwZCFoMmExj+ltUHiHUw=
|
||||
github.com/quic-go/quic-go v0.39.2 h1:hmwAf8zAHlvan0Y5PXxeeBFZEW17IW99sXLry8I2kjk=
|
||||
github.com/quic-go/quic-go v0.39.2/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q=
|
||||
github.com/refraction-networking/utls v1.5.4 h1:9k6EO2b8TaOGsQ7Pl7p9w6PUhx18/ZCeT0WNTZ7Uw4o=
|
||||
github.com/refraction-networking/utls v1.5.4/go.mod h1:SPuDbBmgLGp8s+HLNc83FuavwZCFoMmExj+ltUHiHUw=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||
|
@ -134,8 +134,8 @@ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cb
|
|||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU=
|
||||
go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM=
|
||||
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
@ -145,15 +145,15 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
|
||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
|
||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -176,8 +176,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -197,8 +197,8 @@ golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
|
||||
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
|
||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
|
@ -216,7 +216,7 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE
|
|||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
|
|
|
@ -63,7 +63,8 @@ func (r *body) wasStreamHijacked() bool {
|
|||
}
|
||||
|
||||
func (r *body) Read(b []byte) (int, error) {
|
||||
return r.str.Read(b)
|
||||
n, err := r.str.Read(b)
|
||||
return n, maybeReplaceError(err)
|
||||
}
|
||||
|
||||
func (r *body) Close() error {
|
||||
|
@ -106,7 +107,7 @@ func (r *hijackableBody) Read(b []byte) (int, error) {
|
|||
if err != nil {
|
||||
r.requestDone()
|
||||
}
|
||||
return n, err
|
||||
return n, maybeReplaceError(err)
|
||||
}
|
||||
|
||||
func (r *hijackableBody) requestDone() {
|
||||
|
|
|
@ -321,13 +321,13 @@ func (c *client) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Respon
|
|||
}
|
||||
conn.CloseWithError(quic.ApplicationErrorCode(rerr.connErr), reason)
|
||||
}
|
||||
return nil, rerr.err
|
||||
return nil, maybeReplaceError(rerr.err)
|
||||
}
|
||||
if opt.DontCloseRequestStream {
|
||||
close(reqDone)
|
||||
<-done
|
||||
}
|
||||
return rsp, rerr.err
|
||||
return rsp, maybeReplaceError(rerr.err)
|
||||
}
|
||||
|
||||
// cancelingReader reads from the io.Reader.
|
||||
|
|
58
http3/error.go
Normal file
58
http3/error.go
Normal file
|
@ -0,0 +1,58 @@
|
|||
package http3
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/quic-go/quic-go"
|
||||
)
|
||||
|
||||
// Error is returned from the round tripper (for HTTP clients)
|
||||
// and inside the HTTP handler (for HTTP servers) if an HTTP/3 error occurs.
|
||||
// See section 8 of RFC 9114.
|
||||
type Error struct {
|
||||
Remote bool
|
||||
ErrorCode ErrCode
|
||||
ErrorMessage string
|
||||
}
|
||||
|
||||
var _ error = &Error{}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
s := e.ErrorCode.string()
|
||||
if s == "" {
|
||||
s = fmt.Sprintf("H3 error (%#x)", uint64(e.ErrorCode))
|
||||
}
|
||||
// Usually errors are remote. Only make it explicit for local errors.
|
||||
if !e.Remote {
|
||||
s += " (local)"
|
||||
}
|
||||
if e.ErrorMessage != "" {
|
||||
s += ": " + e.ErrorMessage
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func maybeReplaceError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
e Error
|
||||
strErr *quic.StreamError
|
||||
appErr *quic.ApplicationError
|
||||
)
|
||||
switch {
|
||||
default:
|
||||
return err
|
||||
case errors.As(err, &strErr):
|
||||
e.Remote = strErr.Remote
|
||||
e.ErrorCode = ErrCode(strErr.ErrorCode)
|
||||
case errors.As(err, &appErr):
|
||||
e.Remote = appErr.Remote
|
||||
e.ErrorCode = ErrCode(appErr.ErrorCode)
|
||||
e.ErrorMessage = appErr.ErrorMessage
|
||||
}
|
||||
return &e
|
||||
}
|
|
@ -30,6 +30,14 @@ const (
|
|||
)
|
||||
|
||||
func (e ErrCode) String() string {
|
||||
s := e.string()
|
||||
if s != "" {
|
||||
return s
|
||||
}
|
||||
return fmt.Sprintf("unknown error code: %#x", uint16(e))
|
||||
}
|
||||
|
||||
func (e ErrCode) string() string {
|
||||
switch e {
|
||||
case ErrCodeNoError:
|
||||
return "H3_NO_ERROR"
|
||||
|
@ -68,6 +76,6 @@ func (e ErrCode) String() string {
|
|||
case ErrCodeDatagramError:
|
||||
return "H3_DATAGRAM_ERROR"
|
||||
default:
|
||||
return fmt.Sprintf("unknown error code: %#x", uint16(e))
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
|
41
http3/error_test.go
Normal file
41
http3/error_test.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package http3
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/quic-go/quic-go"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("HTTP/3 errors", func() {
|
||||
It("converts", func() {
|
||||
Expect(maybeReplaceError(nil)).To(BeNil())
|
||||
Expect(maybeReplaceError(errors.New("foobar"))).To(MatchError("foobar"))
|
||||
Expect(maybeReplaceError(&quic.StreamError{
|
||||
ErrorCode: 1337,
|
||||
Remote: true,
|
||||
})).To(Equal(&Error{
|
||||
Remote: true,
|
||||
ErrorCode: 1337,
|
||||
}))
|
||||
Expect(maybeReplaceError(&quic.ApplicationError{
|
||||
ErrorCode: 42,
|
||||
Remote: true,
|
||||
ErrorMessage: "foobar",
|
||||
})).To(Equal(&Error{
|
||||
Remote: true,
|
||||
ErrorCode: 42,
|
||||
ErrorMessage: "foobar",
|
||||
}))
|
||||
})
|
||||
|
||||
It("has a string representation", func() {
|
||||
Expect((&Error{ErrorCode: 0x10c, Remote: true}).Error()).To(Equal("H3_REQUEST_CANCELLED"))
|
||||
Expect((&Error{ErrorCode: 0x10c, Remote: true, ErrorMessage: "foobar"}).Error()).To(Equal("H3_REQUEST_CANCELLED: foobar"))
|
||||
Expect((&Error{ErrorCode: 0x10c, Remote: false}).Error()).To(Equal("H3_REQUEST_CANCELLED (local)"))
|
||||
Expect((&Error{ErrorCode: 0x10c, Remote: false, ErrorMessage: "foobar"}).Error()).To(Equal("H3_REQUEST_CANCELLED (local): foobar"))
|
||||
Expect((&Error{ErrorCode: 0x1337, Remote: true}).Error()).To(Equal("H3 error (0x1337)"))
|
||||
})
|
||||
})
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/http3 (interfaces: QUICEarlyListener)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package http3 -destination mock_quic_early_listener_test.go github.com/refraction-networking/uquic/http3 QUICEarlyListener
|
||||
//
|
||||
// Package http3 is a generated GoMock package.
|
||||
package http3
|
||||
|
||||
|
@ -46,7 +50,7 @@ func (m *MockQUICEarlyListener) Accept(arg0 context.Context) (quic.EarlyConnecti
|
|||
}
|
||||
|
||||
// Accept indicates an expected call of Accept.
|
||||
func (mr *MockQUICEarlyListenerMockRecorder) Accept(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockQUICEarlyListenerMockRecorder) Accept(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accept", reflect.TypeOf((*MockQUICEarlyListener)(nil).Accept), arg0)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/http3 (interfaces: RoundTripCloser)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package http3 -destination mock_roundtripcloser_test.go github.com/refraction-networking/uquic/http3 RoundTripCloser
|
||||
//
|
||||
// Package http3 is a generated GoMock package.
|
||||
package http3
|
||||
|
||||
|
@ -72,7 +76,7 @@ func (m *MockRoundTripCloser) RoundTripOpt(arg0 *http.Request, arg1 RoundTripOpt
|
|||
}
|
||||
|
||||
// RoundTripOpt indicates an expected call of RoundTripOpt.
|
||||
func (mr *MockRoundTripCloserMockRecorder) RoundTripOpt(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockRoundTripCloserMockRecorder) RoundTripOpt(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RoundTripOpt", reflect.TypeOf((*MockRoundTripCloser)(nil).RoundTripOpt), arg0, arg1)
|
||||
}
|
||||
|
|
|
@ -166,9 +166,10 @@ func (w *responseWriter) Write(p []byte) (int, error) {
|
|||
w.buf = w.buf[:0]
|
||||
w.buf = df.Append(w.buf)
|
||||
if _, err := w.bufferedStr.Write(w.buf); err != nil {
|
||||
return 0, err
|
||||
return 0, maybeReplaceError(err)
|
||||
}
|
||||
return w.bufferedStr.Write(p)
|
||||
n, err := w.bufferedStr.Write(p)
|
||||
return n, maybeReplaceError(err)
|
||||
}
|
||||
|
||||
func (w *responseWriter) FlushError() error {
|
||||
|
@ -177,7 +178,7 @@ func (w *responseWriter) FlushError() error {
|
|||
}
|
||||
if !w.written {
|
||||
if err := w.writeHeader(); err != nil {
|
||||
return err
|
||||
return maybeReplaceError(err)
|
||||
}
|
||||
w.written = true
|
||||
}
|
||||
|
|
|
@ -134,8 +134,8 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q
|
|||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||
|
@ -174,8 +174,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
|||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU=
|
||||
go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM=
|
||||
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
@ -194,15 +194,15 @@ golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTk
|
|||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
|
||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
||||
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -305,7 +305,6 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
|
||||
|
|
|
@ -7,11 +7,11 @@ import (
|
|||
"net"
|
||||
"time"
|
||||
|
||||
tls "github.com/refraction-networking/utls"
|
||||
|
||||
quic "github.com/refraction-networking/uquic"
|
||||
quicproxy "github.com/refraction-networking/uquic/integrationtests/tools/proxy"
|
||||
"github.com/refraction-networking/uquic/internal/protocol"
|
||||
"github.com/refraction-networking/uquic/internal/qerr"
|
||||
tls "github.com/refraction-networking/utls"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
@ -80,6 +80,26 @@ var _ = Describe("Handshake tests", func() {
|
|||
}()
|
||||
}
|
||||
|
||||
It("returns the cancellation reason when a dial is canceled", func() {
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
errChan := make(chan error, 1)
|
||||
go func() {
|
||||
_, err := quic.DialAddr(
|
||||
ctx,
|
||||
"localhost:1234", // nobody is listening on this port, but we're going to cancel this dial anyway
|
||||
getTLSClientConfig(),
|
||||
getQuicConfig(nil),
|
||||
)
|
||||
errChan <- err
|
||||
}()
|
||||
|
||||
cancel(errors.New("application cancelled"))
|
||||
var err error
|
||||
Eventually(errChan).Should(Receive(&err))
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError("application cancelled"))
|
||||
})
|
||||
|
||||
// Context("using different cipher suites", func() {
|
||||
// for n, id := range map[string]uint16{
|
||||
// "TLS_AES_128_GCM_SHA256": tls.TLS_AES_128_GCM_SHA256,
|
||||
|
@ -453,16 +473,31 @@ var _ = Describe("Handshake tests", func() {
|
|||
})
|
||||
|
||||
It("rejects invalid Retry token with the INVALID_TOKEN error", func() {
|
||||
const rtt = 10 * time.Millisecond
|
||||
serverConfig.RequireAddressValidation = func(net.Addr) bool { return true }
|
||||
serverConfig.MaxRetryTokenAge = -time.Second
|
||||
// The validity period of the retry token is the handshake timeout,
|
||||
// which is twice the handshake idle timeout.
|
||||
// By setting the handshake timeout shorter than the RTT, the token will have expired by the time
|
||||
// it reaches the server.
|
||||
serverConfig.HandshakeIdleTimeout = rtt / 5
|
||||
|
||||
server, err := quic.ListenAddr("localhost:0", getTLSConfig(), serverConfig)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer server.Close()
|
||||
|
||||
serverPort := server.Addr().(*net.UDPAddr).Port
|
||||
proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{
|
||||
RemoteAddr: fmt.Sprintf("localhost:%d", serverPort),
|
||||
DelayPacket: func(quicproxy.Direction, []byte) time.Duration {
|
||||
return rtt / 2
|
||||
},
|
||||
})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer proxy.Close()
|
||||
|
||||
_, err = quic.DialAddr(
|
||||
context.Background(),
|
||||
fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
|
||||
fmt.Sprintf("localhost:%d", proxy.LocalPort()),
|
||||
getTLSClientConfig(),
|
||||
nil,
|
||||
)
|
||||
|
|
|
@ -307,9 +307,10 @@ var _ = Describe("HTTP tests", func() {
|
|||
for {
|
||||
if _, err := w.Write([]byte("foobar")); err != nil {
|
||||
Expect(r.Context().Done()).To(BeClosed())
|
||||
var strErr *quic.StreamError
|
||||
Expect(errors.As(err, &strErr)).To(BeTrue())
|
||||
Expect(strErr.ErrorCode).To(Equal(quic.StreamErrorCode(0x10c)))
|
||||
var http3Err *http3.Error
|
||||
Expect(errors.As(err, &http3Err)).To(BeTrue())
|
||||
Expect(http3Err.ErrorCode).To(Equal(http3.ErrCode(0x10c)))
|
||||
Expect(http3Err.Error()).To(Equal("H3_REQUEST_CANCELLED"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +326,10 @@ var _ = Describe("HTTP tests", func() {
|
|||
cancel()
|
||||
Eventually(handlerCalled).Should(BeClosed())
|
||||
_, err = resp.Body.Read([]byte{0})
|
||||
Expect(err).To(HaveOccurred())
|
||||
var http3Err *http3.Error
|
||||
Expect(errors.As(err, &http3Err)).To(BeTrue())
|
||||
Expect(http3Err.ErrorCode).To(Equal(http3.ErrCode(0x10c)))
|
||||
Expect(http3Err.Error()).To(Equal("H3_REQUEST_CANCELLED (local)"))
|
||||
})
|
||||
|
||||
It("allows streamed HTTP requests", func() {
|
||||
|
|
|
@ -38,16 +38,13 @@ func countKeyPhases() (sent, received int) {
|
|||
return
|
||||
}
|
||||
|
||||
type keyUpdateConnTracer struct {
|
||||
logging.NullConnectionTracer
|
||||
}
|
||||
|
||||
func (t *keyUpdateConnTracer) SentShortHeaderPacket(hdr *logging.ShortHeader, _ logging.ByteCount, _ *logging.AckFrame, _ []logging.Frame) {
|
||||
sentHeaders = append(sentHeaders, hdr)
|
||||
}
|
||||
|
||||
func (t *keyUpdateConnTracer) ReceivedShortHeaderPacket(hdr *logging.ShortHeader, size logging.ByteCount, frames []logging.Frame) {
|
||||
receivedHeaders = append(receivedHeaders, hdr)
|
||||
var keyUpdateConnTracer = &logging.ConnectionTracer{
|
||||
SentShortHeaderPacket: func(hdr *logging.ShortHeader, _ logging.ByteCount, _ logging.ECN, _ *logging.AckFrame, _ []logging.Frame) {
|
||||
sentHeaders = append(sentHeaders, hdr)
|
||||
},
|
||||
ReceivedShortHeaderPacket: func(hdr *logging.ShortHeader, _ logging.ByteCount, _ logging.ECN, _ []logging.Frame) {
|
||||
receivedHeaders = append(receivedHeaders, hdr)
|
||||
},
|
||||
}
|
||||
|
||||
var _ = Describe("Key Update tests", func() {
|
||||
|
@ -75,8 +72,8 @@ var _ = Describe("Key Update tests", func() {
|
|||
context.Background(),
|
||||
fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
|
||||
getTLSClientConfig(),
|
||||
getQuicConfig(&quic.Config{Tracer: func(context.Context, logging.Perspective, quic.ConnectionID) logging.ConnectionTracer {
|
||||
return &keyUpdateConnTracer{}
|
||||
getQuicConfig(&quic.Config{Tracer: func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return keyUpdateConnTracer
|
||||
}}),
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
|
|
@ -21,7 +21,7 @@ var _ = Describe("Packetization", func() {
|
|||
It("bundles ACKs", func() {
|
||||
const numMsg = 100
|
||||
|
||||
serverTracer := newPacketTracer()
|
||||
serverCounter, serverTracer := newPacketTracer()
|
||||
server, err := quic.ListenAddr(
|
||||
"localhost:0",
|
||||
getTLSConfig(),
|
||||
|
@ -43,7 +43,7 @@ var _ = Describe("Packetization", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
defer proxy.Close()
|
||||
|
||||
clientTracer := newPacketTracer()
|
||||
clientCounter, clientTracer := newPacketTracer()
|
||||
conn, err := quic.DialAddr(
|
||||
context.Background(),
|
||||
fmt.Sprintf("localhost:%d", proxy.LocalPort()),
|
||||
|
@ -104,8 +104,8 @@ var _ = Describe("Packetization", func() {
|
|||
return
|
||||
}
|
||||
|
||||
numBundledIncoming := countBundledPackets(clientTracer.getRcvdShortHeaderPackets())
|
||||
numBundledOutgoing := countBundledPackets(serverTracer.getRcvdShortHeaderPackets())
|
||||
numBundledIncoming := countBundledPackets(clientCounter.getRcvdShortHeaderPackets())
|
||||
numBundledOutgoing := countBundledPackets(serverCounter.getRcvdShortHeaderPackets())
|
||||
fmt.Fprintf(GinkgoWriter, "bundled incoming packets: %d / %d\n", numBundledIncoming, numMsg)
|
||||
fmt.Fprintf(GinkgoWriter, "bundled outgoing packets: %d / %d\n", numBundledOutgoing, numMsg)
|
||||
Expect(numBundledIncoming).To(And(
|
||||
|
|
|
@ -87,7 +87,7 @@ var (
|
|||
logBuf *syncedBuffer
|
||||
versionParam string
|
||||
|
||||
qlogTracer func(context.Context, logging.Perspective, quic.ConnectionID) logging.ConnectionTracer
|
||||
qlogTracer func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer
|
||||
enableQlog bool
|
||||
|
||||
version quic.VersionNumber
|
||||
|
@ -178,10 +178,16 @@ func getQuicConfig(conf *quic.Config) *quic.Config {
|
|||
}
|
||||
if enableQlog {
|
||||
if conf.Tracer == nil {
|
||||
conf.Tracer = qlogTracer
|
||||
conf.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return logging.NewMultiplexedConnectionTracer(
|
||||
qlogTracer(ctx, p, connID),
|
||||
// multiplex it with an empty tracer to check that we're correctly ignoring unset callbacks everywhere
|
||||
&logging.ConnectionTracer{},
|
||||
)
|
||||
}
|
||||
} else if qlogTracer != nil {
|
||||
origTracer := conf.Tracer
|
||||
conf.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) logging.ConnectionTracer {
|
||||
conf.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return logging.NewMultiplexedConnectionTracer(
|
||||
qlogTracer(ctx, p, connID),
|
||||
origTracer(ctx, p, connID),
|
||||
|
@ -243,8 +249,8 @@ func scaleDuration(d time.Duration) time.Duration {
|
|||
return time.Duration(scaleFactor) * d
|
||||
}
|
||||
|
||||
func newTracer(tracer logging.ConnectionTracer) func(context.Context, logging.Perspective, quic.ConnectionID) logging.ConnectionTracer {
|
||||
return func(context.Context, logging.Perspective, quic.ConnectionID) logging.ConnectionTracer { return tracer }
|
||||
func newTracer(tracer *logging.ConnectionTracer) func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer { return tracer }
|
||||
}
|
||||
|
||||
type packet struct {
|
||||
|
@ -259,49 +265,46 @@ type shortHeaderPacket struct {
|
|||
frames []logging.Frame
|
||||
}
|
||||
|
||||
type packetTracer struct {
|
||||
logging.NullConnectionTracer
|
||||
type packetCounter struct {
|
||||
closed chan struct{}
|
||||
sentShortHdr, rcvdShortHdr []shortHeaderPacket
|
||||
rcvdLongHdr []packet
|
||||
}
|
||||
|
||||
func newPacketTracer() *packetTracer {
|
||||
return &packetTracer{closed: make(chan struct{})}
|
||||
}
|
||||
|
||||
func (t *packetTracer) ReceivedLongHeaderPacket(hdr *logging.ExtendedHeader, _ logging.ByteCount, frames []logging.Frame) {
|
||||
t.rcvdLongHdr = append(t.rcvdLongHdr, packet{time: time.Now(), hdr: hdr, frames: frames})
|
||||
}
|
||||
|
||||
func (t *packetTracer) ReceivedShortHeaderPacket(hdr *logging.ShortHeader, _ logging.ByteCount, frames []logging.Frame) {
|
||||
t.rcvdShortHdr = append(t.rcvdShortHdr, shortHeaderPacket{time: time.Now(), hdr: hdr, frames: frames})
|
||||
}
|
||||
|
||||
func (t *packetTracer) SentShortHeaderPacket(hdr *logging.ShortHeader, _ logging.ByteCount, ack *wire.AckFrame, frames []logging.Frame) {
|
||||
if ack != nil {
|
||||
frames = append(frames, ack)
|
||||
}
|
||||
t.sentShortHdr = append(t.sentShortHdr, shortHeaderPacket{time: time.Now(), hdr: hdr, frames: frames})
|
||||
}
|
||||
|
||||
func (t *packetTracer) Close() { close(t.closed) }
|
||||
|
||||
func (t *packetTracer) getSentShortHeaderPackets() []shortHeaderPacket {
|
||||
func (t *packetCounter) getSentShortHeaderPackets() []shortHeaderPacket {
|
||||
<-t.closed
|
||||
return t.sentShortHdr
|
||||
}
|
||||
|
||||
func (t *packetTracer) getRcvdLongHeaderPackets() []packet {
|
||||
func (t *packetCounter) getRcvdLongHeaderPackets() []packet {
|
||||
<-t.closed
|
||||
return t.rcvdLongHdr
|
||||
}
|
||||
|
||||
func (t *packetTracer) getRcvdShortHeaderPackets() []shortHeaderPacket {
|
||||
func (t *packetCounter) getRcvdShortHeaderPackets() []shortHeaderPacket {
|
||||
<-t.closed
|
||||
return t.rcvdShortHdr
|
||||
}
|
||||
|
||||
func newPacketTracer() (*packetCounter, *logging.ConnectionTracer) {
|
||||
c := &packetCounter{closed: make(chan struct{})}
|
||||
return c, &logging.ConnectionTracer{
|
||||
ReceivedLongHeaderPacket: func(hdr *logging.ExtendedHeader, _ logging.ByteCount, _ logging.ECN, frames []logging.Frame) {
|
||||
c.rcvdLongHdr = append(c.rcvdLongHdr, packet{time: time.Now(), hdr: hdr, frames: frames})
|
||||
},
|
||||
ReceivedShortHeaderPacket: func(hdr *logging.ShortHeader, _ logging.ByteCount, _ logging.ECN, frames []logging.Frame) {
|
||||
c.rcvdShortHdr = append(c.rcvdShortHdr, shortHeaderPacket{time: time.Now(), hdr: hdr, frames: frames})
|
||||
},
|
||||
SentShortHeaderPacket: func(hdr *logging.ShortHeader, _ logging.ByteCount, _ logging.ECN, ack *wire.AckFrame, frames []logging.Frame) {
|
||||
if ack != nil {
|
||||
frames = append(frames, ack)
|
||||
}
|
||||
c.sentShortHdr = append(c.sentShortHdr, shortHeaderPacket{time: time.Now(), hdr: hdr, frames: frames})
|
||||
},
|
||||
Close: func() { close(c.closed) },
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelf(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Self integration tests")
|
||||
|
|
|
@ -57,7 +57,7 @@ var _ = Describe("Timeout tests", func() {
|
|||
context.Background(),
|
||||
"localhost:12345",
|
||||
getTLSClientConfig(),
|
||||
getQuicConfig(&quic.Config{HandshakeIdleTimeout: 10 * time.Millisecond}),
|
||||
getQuicConfig(&quic.Config{HandshakeIdleTimeout: scaleDuration(50 * time.Millisecond)}),
|
||||
)
|
||||
errChan <- err
|
||||
}()
|
||||
|
@ -194,7 +194,7 @@ var _ = Describe("Timeout tests", func() {
|
|||
close(serverConnClosed)
|
||||
}()
|
||||
|
||||
tr := newPacketTracer()
|
||||
counter, tr := newPacketTracer()
|
||||
conn, err := quic.DialAddr(
|
||||
context.Background(),
|
||||
fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
|
||||
|
@ -215,7 +215,7 @@ var _ = Describe("Timeout tests", func() {
|
|||
}()
|
||||
Eventually(done, 2*idleTimeout).Should(BeClosed())
|
||||
var lastAckElicitingPacketSentAt time.Time
|
||||
for _, p := range tr.getSentShortHeaderPackets() {
|
||||
for _, p := range counter.getSentShortHeaderPackets() {
|
||||
var hasAckElicitingFrame bool
|
||||
for _, f := range p.frames {
|
||||
if _, ok := f.(*logging.AckFrame); ok {
|
||||
|
@ -228,7 +228,7 @@ var _ = Describe("Timeout tests", func() {
|
|||
lastAckElicitingPacketSentAt = p.time
|
||||
}
|
||||
}
|
||||
rcvdPackets := tr.getRcvdShortHeaderPackets()
|
||||
rcvdPackets := counter.getRcvdShortHeaderPackets()
|
||||
lastPacketRcvdAt := rcvdPackets[len(rcvdPackets)-1].time
|
||||
// We're ignoring here that only the first ack-eliciting packet sent resets the idle timeout.
|
||||
// This is ok since we're dealing with a lossless connection here,
|
||||
|
|
|
@ -26,9 +26,9 @@ var _ = Describe("Handshake tests", func() {
|
|||
|
||||
fmt.Fprintf(GinkgoWriter, "%s using qlog: %t, custom: %t\n", pers, enableQlog, enableCustomTracer)
|
||||
|
||||
var tracerConstructors []func(context.Context, logging.Perspective, quic.ConnectionID) logging.ConnectionTracer
|
||||
var tracerConstructors []func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer
|
||||
if enableQlog {
|
||||
tracerConstructors = append(tracerConstructors, func(_ context.Context, p logging.Perspective, connID quic.ConnectionID) logging.ConnectionTracer {
|
||||
tracerConstructors = append(tracerConstructors, func(_ context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer {
|
||||
if mrand.Int()%2 == 0 { // simulate that a qlog collector might only want to log some connections
|
||||
fmt.Fprintf(GinkgoWriter, "%s qlog tracer deciding to not trace connection %x\n", p, connID)
|
||||
return nil
|
||||
|
@ -38,13 +38,13 @@ var _ = Describe("Handshake tests", func() {
|
|||
})
|
||||
}
|
||||
if enableCustomTracer {
|
||||
tracerConstructors = append(tracerConstructors, func(context.Context, logging.Perspective, quic.ConnectionID) logging.ConnectionTracer {
|
||||
return logging.NullConnectionTracer{}
|
||||
tracerConstructors = append(tracerConstructors, func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return &logging.ConnectionTracer{}
|
||||
})
|
||||
}
|
||||
c := conf.Clone()
|
||||
c.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) logging.ConnectionTracer {
|
||||
tracers := make([]logging.ConnectionTracer, 0, len(tracerConstructors))
|
||||
c.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer {
|
||||
tracers := make([]*logging.ConnectionTracer, 0, len(tracerConstructors))
|
||||
for _, c := range tracerConstructors {
|
||||
if tr := c(ctx, p, connID); tr != nil {
|
||||
tracers = append(tracers, tr)
|
||||
|
|
|
@ -203,7 +203,7 @@ var _ = Describe("0-RTT", func() {
|
|||
Eventually(conn.Context().Done()).Should(BeClosed())
|
||||
}
|
||||
|
||||
// can be used to extract 0-RTT from a packetTracer
|
||||
// can be used to extract 0-RTT from a packetCounter
|
||||
get0RTTPackets := func(packets []packet) []protocol.PacketNumber {
|
||||
var zeroRTTPackets []protocol.PacketNumber
|
||||
for _, p := range packets {
|
||||
|
@ -220,7 +220,7 @@ var _ = Describe("0-RTT", func() {
|
|||
It(fmt.Sprintf("transfers 0-RTT data, with %d byte connection IDs", connIDLen), func() {
|
||||
tlsConf, clientTLSConf := dialAndReceiveSessionTicket(nil)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -245,7 +245,7 @@ var _ = Describe("0-RTT", func() {
|
|||
)
|
||||
|
||||
var numNewConnIDs int
|
||||
for _, p := range tracer.getRcvdLongHeaderPackets() {
|
||||
for _, p := range counter.getRcvdLongHeaderPackets() {
|
||||
for _, f := range p.frames {
|
||||
if _, ok := f.(*logging.NewConnectionIDFrame); ok {
|
||||
numNewConnIDs++
|
||||
|
@ -261,7 +261,7 @@ var _ = Describe("0-RTT", func() {
|
|||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
zeroRTTPackets := get0RTTPackets(tracer.getRcvdLongHeaderPackets())
|
||||
zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets())
|
||||
Expect(len(zeroRTTPackets)).To(BeNumerically(">", 10))
|
||||
Expect(zeroRTTPackets).To(ContainElement(protocol.PacketNumber(0)))
|
||||
})
|
||||
|
@ -274,7 +274,7 @@ var _ = Describe("0-RTT", func() {
|
|||
zeroRTTData := GeneratePRData(5 << 10)
|
||||
oneRTTData := PRData
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -331,7 +331,7 @@ var _ = Describe("0-RTT", func() {
|
|||
|
||||
// check that 0-RTT packets only contain STREAM frames for the first stream
|
||||
var num0RTT int
|
||||
for _, p := range tracer.getRcvdLongHeaderPackets() {
|
||||
for _, p := range counter.getRcvdLongHeaderPackets() {
|
||||
if p.hdr.Header.Type != protocol.PacketType0RTT {
|
||||
continue
|
||||
}
|
||||
|
@ -356,7 +356,7 @@ var _ = Describe("0-RTT", func() {
|
|||
|
||||
tlsConf, clientConf := dialAndReceiveSessionTicket(nil)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -407,7 +407,7 @@ var _ = Describe("0-RTT", func() {
|
|||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets. Dropped %d of those.", num0RTT, numDropped)
|
||||
Expect(numDropped).ToNot(BeZero())
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).ToNot(BeEmpty())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).ToNot(BeEmpty())
|
||||
})
|
||||
|
||||
It("retransmits all 0-RTT data when the server performs a Retry", func() {
|
||||
|
@ -431,7 +431,7 @@ var _ = Describe("0-RTT", func() {
|
|||
return
|
||||
}
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -481,7 +481,7 @@ var _ = Describe("0-RTT", func() {
|
|||
defer mutex.Unlock()
|
||||
Expect(firstCounter).To(BeNumerically("~", 5000+100 /* framing overhead */, 100)) // the FIN bit might be sent extra
|
||||
Expect(secondCounter).To(BeNumerically("~", firstCounter, 20))
|
||||
zeroRTTPackets := get0RTTPackets(tracer.getRcvdLongHeaderPackets())
|
||||
zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets())
|
||||
Expect(len(zeroRTTPackets)).To(BeNumerically(">=", 5))
|
||||
Expect(zeroRTTPackets[0]).To(BeNumerically(">=", protocol.PacketNumber(5)))
|
||||
})
|
||||
|
@ -492,14 +492,12 @@ var _ = Describe("0-RTT", func() {
|
|||
MaxIncomingUniStreams: maxStreams,
|
||||
}))
|
||||
|
||||
tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
getQuicConfig(&quic.Config{
|
||||
MaxIncomingUniStreams: maxStreams + 1,
|
||||
Allow0RTT: true,
|
||||
Tracer: newTracer(tracer),
|
||||
}),
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -537,7 +535,7 @@ var _ = Describe("0-RTT", func() {
|
|||
MaxIncomingStreams: maxStreams,
|
||||
}))
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -557,7 +555,7 @@ var _ = Describe("0-RTT", func() {
|
|||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("rejects 0-RTT when the ALPN changed", func() {
|
||||
|
@ -566,7 +564,7 @@ var _ = Describe("0-RTT", func() {
|
|||
// now close the listener and dial new connection with a different ALPN
|
||||
clientConf.NextProtos = []string{"new-alpn"}
|
||||
tlsConf.NextProtos = []string{"new-alpn"}
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -586,14 +584,14 @@ var _ = Describe("0-RTT", func() {
|
|||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("rejects 0-RTT when the application doesn't allow it", func() {
|
||||
tlsConf, clientConf := dialAndReceiveSessionTicket(nil)
|
||||
|
||||
// now close the listener and dial new connection with a different ALPN
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -613,12 +611,12 @@ var _ = Describe("0-RTT", func() {
|
|||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
})
|
||||
|
||||
DescribeTable("flow control limits",
|
||||
func(addFlowControlLimit func(*quic.Config, uint64)) {
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
firstConf := getQuicConfig(&quic.Config{Allow0RTT: true})
|
||||
addFlowControlLimit(firstConf, 3)
|
||||
tlsConf, clientConf := dialAndReceiveSessionTicket(firstConf)
|
||||
|
@ -670,7 +668,7 @@ var _ = Describe("0-RTT", func() {
|
|||
Eventually(conn.Context().Done()).Should(BeClosed())
|
||||
|
||||
var processedFirst bool
|
||||
for _, p := range tracer.getRcvdLongHeaderPackets() {
|
||||
for _, p := range counter.getRcvdLongHeaderPackets() {
|
||||
for _, f := range p.frames {
|
||||
if sf, ok := f.(*logging.StreamFrame); ok {
|
||||
if !processedFirst {
|
||||
|
@ -696,7 +694,7 @@ var _ = Describe("0-RTT", func() {
|
|||
It(fmt.Sprintf("correctly deals with 0-RTT rejections, for %d byte connection IDs", connIDLen), func() {
|
||||
tlsConf, clientConf := dialAndReceiveSessionTicket(nil)
|
||||
// now dial new connection with different transport parameters
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -765,14 +763,14 @@ var _ = Describe("0-RTT", func() {
|
|||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
})
|
||||
}
|
||||
|
||||
It("queues 0-RTT packets, if the Initial is delayed", func() {
|
||||
tlsConf, clientConf := dialAndReceiveSessionTicket(nil)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -797,8 +795,8 @@ var _ = Describe("0-RTT", func() {
|
|||
|
||||
transfer0RTTData(ln, proxy.LocalPort(), protocol.DefaultConnectionIDLength, clientConf, nil, PRData)
|
||||
|
||||
Expect(tracer.getRcvdLongHeaderPackets()[0].hdr.Type).To(Equal(protocol.PacketTypeInitial))
|
||||
zeroRTTPackets := get0RTTPackets(tracer.getRcvdLongHeaderPackets())
|
||||
Expect(counter.getRcvdLongHeaderPackets()[0].hdr.Type).To(Equal(protocol.PacketTypeInitial))
|
||||
zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets())
|
||||
Expect(len(zeroRTTPackets)).To(BeNumerically(">", 10))
|
||||
Expect(zeroRTTPackets[0]).To(Equal(protocol.PacketNumber(0)))
|
||||
})
|
||||
|
@ -808,7 +806,7 @@ var _ = Describe("0-RTT", func() {
|
|||
EnableDatagrams: true,
|
||||
}))
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -853,12 +851,12 @@ var _ = Describe("0-RTT", func() {
|
|||
|
||||
Expect(conn.ConnectionState().Used0RTT).To(BeTrue())
|
||||
Expect(receivedMessage).To(Equal(sentMessage))
|
||||
Expect(conn.CloseWithError(0, "")).To(Succeed())
|
||||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
zeroRTTPackets := get0RTTPackets(tracer.getRcvdLongHeaderPackets())
|
||||
zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets())
|
||||
Expect(zeroRTTPackets).To(HaveLen(1))
|
||||
Expect(conn.CloseWithError(0, "")).To(Succeed())
|
||||
})
|
||||
|
||||
It("rejects 0-RTT datagrams when the server doesn't support datagrams anymore", func() {
|
||||
|
@ -866,7 +864,7 @@ var _ = Describe("0-RTT", func() {
|
|||
EnableDatagrams: true,
|
||||
}))
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -908,10 +906,10 @@ var _ = Describe("0-RTT", func() {
|
|||
|
||||
Expect(conn.ConnectionState().SupportsDatagrams).To(BeFalse())
|
||||
Expect(conn.ConnectionState().Used0RTT).To(BeFalse())
|
||||
Expect(conn.CloseWithError(0, "")).To(Succeed())
|
||||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
Expect(conn.CloseWithError(0, "")).To(Succeed())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
})
|
||||
})
|
||||
|
|
|
@ -233,7 +233,7 @@ var _ = Describe("0-RTT", func() {
|
|||
Eventually(conn.Context().Done()).Should(BeClosed())
|
||||
}
|
||||
|
||||
// can be used to extract 0-RTT from a packetTracer
|
||||
// can be used to extract 0-RTT from a packetCounter
|
||||
get0RTTPackets := func(packets []packet) []protocol.PacketNumber {
|
||||
var zeroRTTPackets []protocol.PacketNumber
|
||||
for _, p := range packets {
|
||||
|
@ -252,7 +252,7 @@ var _ = Describe("0-RTT", func() {
|
|||
clientTLSConf := getTLSClientConfig()
|
||||
dialAndReceiveSessionTicket(tlsConf, nil, clientTLSConf)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -277,7 +277,7 @@ var _ = Describe("0-RTT", func() {
|
|||
)
|
||||
|
||||
var numNewConnIDs int
|
||||
for _, p := range tracer.getRcvdLongHeaderPackets() {
|
||||
for _, p := range counter.getRcvdLongHeaderPackets() {
|
||||
for _, f := range p.frames {
|
||||
if _, ok := f.(*logging.NewConnectionIDFrame); ok {
|
||||
numNewConnIDs++
|
||||
|
@ -293,7 +293,7 @@ var _ = Describe("0-RTT", func() {
|
|||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
zeroRTTPackets := get0RTTPackets(tracer.getRcvdLongHeaderPackets())
|
||||
zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets())
|
||||
Expect(len(zeroRTTPackets)).To(BeNumerically(">", 10))
|
||||
Expect(zeroRTTPackets).To(ContainElement(protocol.PacketNumber(0)))
|
||||
})
|
||||
|
@ -308,7 +308,7 @@ var _ = Describe("0-RTT", func() {
|
|||
zeroRTTData := GeneratePRData(5 << 10)
|
||||
oneRTTData := PRData
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -365,7 +365,7 @@ var _ = Describe("0-RTT", func() {
|
|||
|
||||
// check that 0-RTT packets only contain STREAM frames for the first stream
|
||||
var num0RTT int
|
||||
for _, p := range tracer.getRcvdLongHeaderPackets() {
|
||||
for _, p := range counter.getRcvdLongHeaderPackets() {
|
||||
if p.hdr.Header.Type != protocol.PacketType0RTT {
|
||||
continue
|
||||
}
|
||||
|
@ -392,7 +392,7 @@ var _ = Describe("0-RTT", func() {
|
|||
clientConf := getTLSClientConfig()
|
||||
dialAndReceiveSessionTicket(tlsConf, nil, clientConf)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -443,7 +443,7 @@ var _ = Describe("0-RTT", func() {
|
|||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets. Dropped %d of those.", num0RTT, numDropped)
|
||||
Expect(numDropped).ToNot(BeZero())
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).ToNot(BeEmpty())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).ToNot(BeEmpty())
|
||||
})
|
||||
|
||||
It("retransmits all 0-RTT data when the server performs a Retry", func() {
|
||||
|
@ -469,7 +469,7 @@ var _ = Describe("0-RTT", func() {
|
|||
return
|
||||
}
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -519,7 +519,7 @@ var _ = Describe("0-RTT", func() {
|
|||
defer mutex.Unlock()
|
||||
Expect(firstCounter).To(BeNumerically("~", 5000+100 /* framing overhead */, 100)) // the FIN bit might be sent extra
|
||||
Expect(secondCounter).To(BeNumerically("~", firstCounter, 20))
|
||||
zeroRTTPackets := get0RTTPackets(tracer.getRcvdLongHeaderPackets())
|
||||
zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets())
|
||||
Expect(len(zeroRTTPackets)).To(BeNumerically(">=", 5))
|
||||
Expect(zeroRTTPackets[0]).To(BeNumerically(">=", protocol.PacketNumber(5)))
|
||||
})
|
||||
|
@ -532,14 +532,12 @@ var _ = Describe("0-RTT", func() {
|
|||
MaxIncomingUniStreams: maxStreams,
|
||||
}), clientConf)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
getQuicConfig(&quic.Config{
|
||||
MaxIncomingUniStreams: maxStreams + 1,
|
||||
Allow0RTT: true,
|
||||
Tracer: newTracer(tracer),
|
||||
}),
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -579,7 +577,7 @@ var _ = Describe("0-RTT", func() {
|
|||
MaxIncomingStreams: maxStreams,
|
||||
}), clientConf)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -600,7 +598,7 @@ var _ = Describe("0-RTT", func() {
|
|||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("rejects 0-RTT when the ALPN changed", func() {
|
||||
|
@ -613,7 +611,7 @@ var _ = Describe("0-RTT", func() {
|
|||
// Append to the client's ALPN.
|
||||
// crypto/tls will attempt to resume with the ALPN from the original connection
|
||||
clientConf.NextProtos = append(clientConf.NextProtos, "new-alpn")
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -633,7 +631,7 @@ var _ = Describe("0-RTT", func() {
|
|||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("rejects 0-RTT when the application doesn't allow it", func() {
|
||||
|
@ -642,7 +640,7 @@ var _ = Describe("0-RTT", func() {
|
|||
dialAndReceiveSessionTicket(tlsConf, nil, clientConf)
|
||||
|
||||
// now close the listener and dial new connection with a different ALPN
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -662,12 +660,12 @@ var _ = Describe("0-RTT", func() {
|
|||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
})
|
||||
|
||||
DescribeTable("flow control limits",
|
||||
func(addFlowControlLimit func(*quic.Config, uint64)) {
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
firstConf := getQuicConfig(&quic.Config{Allow0RTT: true})
|
||||
addFlowControlLimit(firstConf, 3)
|
||||
tlsConf := getTLSConfig()
|
||||
|
@ -721,7 +719,7 @@ var _ = Describe("0-RTT", func() {
|
|||
Eventually(conn.Context().Done()).Should(BeClosed())
|
||||
|
||||
var processedFirst bool
|
||||
for _, p := range tracer.getRcvdLongHeaderPackets() {
|
||||
for _, p := range counter.getRcvdLongHeaderPackets() {
|
||||
for _, f := range p.frames {
|
||||
if sf, ok := f.(*logging.StreamFrame); ok {
|
||||
if !processedFirst {
|
||||
|
@ -749,7 +747,7 @@ var _ = Describe("0-RTT", func() {
|
|||
clientConf := getTLSClientConfig()
|
||||
dialAndReceiveSessionTicket(tlsConf, nil, clientConf)
|
||||
// now dial new connection with different transport parameters
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -818,7 +816,7 @@ var _ = Describe("0-RTT", func() {
|
|||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -827,7 +825,7 @@ var _ = Describe("0-RTT", func() {
|
|||
clientConf := getTLSClientConfig()
|
||||
dialAndReceiveSessionTicket(tlsConf, nil, clientConf)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -852,8 +850,8 @@ var _ = Describe("0-RTT", func() {
|
|||
|
||||
transfer0RTTData(ln, proxy.LocalPort(), protocol.DefaultConnectionIDLength, clientConf, nil, PRData)
|
||||
|
||||
Expect(tracer.getRcvdLongHeaderPackets()[0].hdr.Type).To(Equal(protocol.PacketTypeInitial))
|
||||
zeroRTTPackets := get0RTTPackets(tracer.getRcvdLongHeaderPackets())
|
||||
Expect(counter.getRcvdLongHeaderPackets()[0].hdr.Type).To(Equal(protocol.PacketTypeInitial))
|
||||
zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets())
|
||||
Expect(len(zeroRTTPackets)).To(BeNumerically(">", 10))
|
||||
Expect(zeroRTTPackets[0]).To(Equal(protocol.PacketNumber(0)))
|
||||
})
|
||||
|
@ -879,14 +877,10 @@ var _ = Describe("0-RTT", func() {
|
|||
clientTLSConf := getTLSClientConfig()
|
||||
dialAndReceiveSessionTicket(tlsConf, nil, clientTLSConf)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
getQuicConfig(&quic.Config{
|
||||
Allow0RTT: true,
|
||||
Tracer: newTracer(tracer),
|
||||
}),
|
||||
getQuicConfig(&quic.Config{Allow0RTT: true}),
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer ln.Close()
|
||||
|
@ -917,14 +911,10 @@ var _ = Describe("0-RTT", func() {
|
|||
}
|
||||
dialAndReceiveSessionTicket(tlsConf, nil, clientTLSConf)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
getQuicConfig(&quic.Config{
|
||||
Allow0RTT: true,
|
||||
Tracer: newTracer(tracer),
|
||||
}),
|
||||
getQuicConfig(&quic.Config{Allow0RTT: true}),
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer ln.Close()
|
||||
|
@ -947,7 +937,7 @@ var _ = Describe("0-RTT", func() {
|
|||
EnableDatagrams: true,
|
||||
}), clientTLSConf)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -990,13 +980,13 @@ var _ = Describe("0-RTT", func() {
|
|||
<-received
|
||||
|
||||
Expect(conn.ConnectionState().Used0RTT).To(BeTrue())
|
||||
Expect(conn.CloseWithError(0, "")).To(Succeed())
|
||||
Expect(receivedMessage).To(Equal(sentMessage))
|
||||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
zeroRTTPackets := get0RTTPackets(tracer.getRcvdLongHeaderPackets())
|
||||
zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets())
|
||||
Expect(zeroRTTPackets).To(HaveLen(1))
|
||||
Expect(conn.CloseWithError(0, "")).To(Succeed())
|
||||
})
|
||||
|
||||
It("rejects 0-RTT datagrams when the server doesn't support datagrams anymore", func() {
|
||||
|
@ -1006,7 +996,7 @@ var _ = Describe("0-RTT", func() {
|
|||
EnableDatagrams: true,
|
||||
}), clientTLSConf)
|
||||
|
||||
tracer := newPacketTracer()
|
||||
counter, tracer := newPacketTracer()
|
||||
ln, err := quic.ListenAddrEarly(
|
||||
"localhost:0",
|
||||
tlsConf,
|
||||
|
@ -1048,10 +1038,10 @@ var _ = Describe("0-RTT", func() {
|
|||
|
||||
Expect(conn.ConnectionState().SupportsDatagrams).To(BeFalse())
|
||||
Expect(conn.ConnectionState().Used0RTT).To(BeFalse())
|
||||
Expect(conn.CloseWithError(0, "")).To(Succeed())
|
||||
num0RTT := atomic.LoadUint32(num0RTTPackets)
|
||||
fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT)
|
||||
Expect(num0RTT).ToNot(BeZero())
|
||||
Expect(get0RTTPackets(tracer.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
Expect(conn.CloseWithError(0, "")).To(Succeed())
|
||||
Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty())
|
||||
})
|
||||
})
|
||||
|
|
|
@ -14,8 +14,8 @@ import (
|
|||
"github.com/refraction-networking/uquic/qlog"
|
||||
)
|
||||
|
||||
func NewQlogger(logger io.Writer) func(context.Context, logging.Perspective, quic.ConnectionID) logging.ConnectionTracer {
|
||||
return func(_ context.Context, p logging.Perspective, connID quic.ConnectionID) logging.ConnectionTracer {
|
||||
func NewQlogger(logger io.Writer) func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return func(_ context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer {
|
||||
role := "server"
|
||||
if p == logging.PerspectiveClient {
|
||||
role = "client"
|
||||
|
|
|
@ -2,8 +2,10 @@ package versionnegotiation
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
tls "github.com/refraction-networking/utls"
|
||||
|
||||
|
@ -20,29 +22,29 @@ type versioner interface {
|
|||
GetVersion() protocol.VersionNumber
|
||||
}
|
||||
|
||||
type versionNegotiationTracer struct {
|
||||
logging.NullConnectionTracer
|
||||
|
||||
type result struct {
|
||||
loggedVersions bool
|
||||
receivedVersionNegotiation bool
|
||||
chosen logging.VersionNumber
|
||||
clientVersions, serverVersions []logging.VersionNumber
|
||||
}
|
||||
|
||||
var _ logging.ConnectionTracer = &versionNegotiationTracer{}
|
||||
|
||||
func (t *versionNegotiationTracer) NegotiatedVersion(chosen logging.VersionNumber, clientVersions, serverVersions []logging.VersionNumber) {
|
||||
if t.loggedVersions {
|
||||
Fail("only expected one call to NegotiatedVersions")
|
||||
func newVersionNegotiationTracer() (*result, *logging.ConnectionTracer) {
|
||||
r := &result{}
|
||||
return r, &logging.ConnectionTracer{
|
||||
NegotiatedVersion: func(chosen logging.VersionNumber, clientVersions, serverVersions []logging.VersionNumber) {
|
||||
if r.loggedVersions {
|
||||
Fail("only expected one call to NegotiatedVersions")
|
||||
}
|
||||
r.loggedVersions = true
|
||||
r.chosen = chosen
|
||||
r.clientVersions = clientVersions
|
||||
r.serverVersions = serverVersions
|
||||
},
|
||||
ReceivedVersionNegotiationPacket: func(dest, src logging.ArbitraryLenConnectionID, _ []logging.VersionNumber) {
|
||||
r.receivedVersionNegotiation = true
|
||||
},
|
||||
}
|
||||
t.loggedVersions = true
|
||||
t.chosen = chosen
|
||||
t.clientVersions = clientVersions
|
||||
t.serverVersions = serverVersions
|
||||
}
|
||||
|
||||
func (t *versionNegotiationTracer) ReceivedVersionNegotiationPacket(dest, src logging.ArbitraryLenConnectionID, _ []logging.VersionNumber) {
|
||||
t.receivedVersionNegotiation = true
|
||||
}
|
||||
|
||||
var _ = Describe("Handshake tests", func() {
|
||||
|
@ -85,54 +87,54 @@ var _ = Describe("Handshake tests", func() {
|
|||
// but it supports a bunch of versions that the client doesn't speak
|
||||
serverConfig := &quic.Config{}
|
||||
serverConfig.Versions = []protocol.VersionNumber{7, 8, protocol.SupportedVersions[0], 9}
|
||||
serverTracer := &versionNegotiationTracer{}
|
||||
serverConfig.Tracer = func(context.Context, logging.Perspective, quic.ConnectionID) logging.ConnectionTracer {
|
||||
serverResult, serverTracer := newVersionNegotiationTracer()
|
||||
serverConfig.Tracer = func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return serverTracer
|
||||
}
|
||||
server, cl := startServer(getTLSConfig(), serverConfig)
|
||||
defer cl()
|
||||
clientTracer := &versionNegotiationTracer{}
|
||||
clientResult, clientTracer := newVersionNegotiationTracer()
|
||||
conn, err := quic.DialAddr(
|
||||
context.Background(),
|
||||
fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
|
||||
getTLSClientConfig(),
|
||||
maybeAddQLOGTracer(&quic.Config{Tracer: func(ctx context.Context, perspective logging.Perspective, id quic.ConnectionID) logging.ConnectionTracer {
|
||||
maybeAddQLOGTracer(&quic.Config{Tracer: func(ctx context.Context, perspective logging.Perspective, id quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return clientTracer
|
||||
}}),
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(conn.(versioner).GetVersion()).To(Equal(expectedVersion))
|
||||
Expect(conn.CloseWithError(0, "")).To(Succeed())
|
||||
Expect(clientTracer.chosen).To(Equal(expectedVersion))
|
||||
Expect(clientTracer.receivedVersionNegotiation).To(BeFalse())
|
||||
Expect(clientTracer.clientVersions).To(Equal(protocol.SupportedVersions))
|
||||
Expect(clientTracer.serverVersions).To(BeEmpty())
|
||||
Expect(serverTracer.chosen).To(Equal(expectedVersion))
|
||||
Expect(serverTracer.serverVersions).To(Equal(serverConfig.Versions))
|
||||
Expect(serverTracer.clientVersions).To(BeEmpty())
|
||||
Expect(clientResult.chosen).To(Equal(expectedVersion))
|
||||
Expect(clientResult.receivedVersionNegotiation).To(BeFalse())
|
||||
Expect(clientResult.clientVersions).To(Equal(protocol.SupportedVersions))
|
||||
Expect(clientResult.serverVersions).To(BeEmpty())
|
||||
Expect(serverResult.chosen).To(Equal(expectedVersion))
|
||||
Expect(serverResult.serverVersions).To(Equal(serverConfig.Versions))
|
||||
Expect(serverResult.clientVersions).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("when the client supports more versions than the server supports", func() {
|
||||
expectedVersion := protocol.SupportedVersions[0]
|
||||
// the server doesn't support the highest supported version, which is the first one the client will try
|
||||
// The server doesn't support the highest supported version, which is the first one the client will try,
|
||||
// but it supports a bunch of versions that the client doesn't speak
|
||||
serverTracer := &versionNegotiationTracer{}
|
||||
serverResult, serverTracer := newVersionNegotiationTracer()
|
||||
serverConfig := &quic.Config{}
|
||||
serverConfig.Versions = supportedVersions
|
||||
serverConfig.Tracer = func(context.Context, logging.Perspective, quic.ConnectionID) logging.ConnectionTracer {
|
||||
serverConfig.Tracer = func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return serverTracer
|
||||
}
|
||||
server, cl := startServer(getTLSConfig(), serverConfig)
|
||||
defer cl()
|
||||
clientVersions := []protocol.VersionNumber{7, 8, 9, protocol.SupportedVersions[0], 10}
|
||||
clientTracer := &versionNegotiationTracer{}
|
||||
clientResult, clientTracer := newVersionNegotiationTracer()
|
||||
conn, err := quic.DialAddr(
|
||||
context.Background(),
|
||||
fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
|
||||
getTLSClientConfig(),
|
||||
maybeAddQLOGTracer(&quic.Config{
|
||||
Versions: clientVersions,
|
||||
Tracer: func(context.Context, logging.Perspective, quic.ConnectionID) logging.ConnectionTracer {
|
||||
Tracer: func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return clientTracer
|
||||
},
|
||||
}),
|
||||
|
@ -140,13 +142,53 @@ var _ = Describe("Handshake tests", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(conn.(versioner).GetVersion()).To(Equal(protocol.SupportedVersions[0]))
|
||||
Expect(conn.CloseWithError(0, "")).To(Succeed())
|
||||
Expect(clientTracer.chosen).To(Equal(expectedVersion))
|
||||
Expect(clientTracer.receivedVersionNegotiation).To(BeTrue())
|
||||
Expect(clientTracer.clientVersions).To(Equal(clientVersions))
|
||||
Expect(clientTracer.serverVersions).To(ContainElements(supportedVersions)) // may contain greased versions
|
||||
Expect(serverTracer.chosen).To(Equal(expectedVersion))
|
||||
Expect(serverTracer.serverVersions).To(Equal(serverConfig.Versions))
|
||||
Expect(serverTracer.clientVersions).To(BeEmpty())
|
||||
Expect(clientResult.chosen).To(Equal(expectedVersion))
|
||||
Expect(clientResult.receivedVersionNegotiation).To(BeTrue())
|
||||
Expect(clientResult.clientVersions).To(Equal(clientVersions))
|
||||
Expect(clientResult.serverVersions).To(ContainElements(supportedVersions)) // may contain greased versions
|
||||
Expect(serverResult.chosen).To(Equal(expectedVersion))
|
||||
Expect(serverResult.serverVersions).To(Equal(serverConfig.Versions))
|
||||
Expect(serverResult.clientVersions).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("fails if the server disables version negotiation", func() {
|
||||
// The server doesn't support the highest supported version, which is the first one the client will try,
|
||||
// but it supports a bunch of versions that the client doesn't speak
|
||||
_, serverTracer := newVersionNegotiationTracer()
|
||||
serverConfig := &quic.Config{}
|
||||
serverConfig.Versions = supportedVersions
|
||||
serverConfig.Tracer = func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return serverTracer
|
||||
}
|
||||
conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
tr := &quic.Transport{
|
||||
Conn: conn,
|
||||
DisableVersionNegotiationPackets: true,
|
||||
}
|
||||
ln, err := tr.Listen(getTLSConfig(), serverConfig)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer ln.Close()
|
||||
|
||||
clientVersions := []protocol.VersionNumber{7, 8, 9, protocol.SupportedVersions[0], 10}
|
||||
clientResult, clientTracer := newVersionNegotiationTracer()
|
||||
_, err = quic.DialAddr(
|
||||
context.Background(),
|
||||
fmt.Sprintf("localhost:%d", conn.LocalAddr().(*net.UDPAddr).Port),
|
||||
getTLSClientConfig(),
|
||||
maybeAddQLOGTracer(&quic.Config{
|
||||
Versions: clientVersions,
|
||||
Tracer: func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return clientTracer
|
||||
},
|
||||
HandshakeIdleTimeout: 100 * time.Millisecond,
|
||||
}),
|
||||
)
|
||||
Expect(err).To(HaveOccurred())
|
||||
var nerr net.Error
|
||||
Expect(errors.As(err, &nerr)).To(BeTrue())
|
||||
Expect(nerr.Timeout()).To(BeTrue())
|
||||
Expect(clientResult.receivedVersionNegotiation).To(BeFalse())
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
|
@ -70,7 +70,7 @@ func maybeAddQLOGTracer(c *quic.Config) *quic.Config {
|
|||
c.Tracer = qlogger
|
||||
} else if qlogger != nil {
|
||||
origTracer := c.Tracer
|
||||
c.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) logging.ConnectionTracer {
|
||||
c.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer {
|
||||
return logging.NewMultiplexedConnectionTracer(
|
||||
qlogger(ctx, p, connID),
|
||||
origTracer(ctx, p, connID),
|
||||
|
|
21
interface.go
21
interface.go
|
@ -213,6 +213,9 @@ type EarlyConnection interface {
|
|||
// StatelessResetKey is a key used to derive stateless reset tokens.
|
||||
type StatelessResetKey [32]byte
|
||||
|
||||
// TokenGeneratorKey is a key used to encrypt session resumption tokens.
|
||||
type TokenGeneratorKey = handshake.TokenProtectorKey
|
||||
|
||||
// A ConnectionID is a QUIC Connection ID, as defined in RFC 9000.
|
||||
// It is not able to handle QUIC Connection IDs longer than 20 bytes,
|
||||
// as they are allowed by RFC 8999.
|
||||
|
@ -251,7 +254,8 @@ type Config struct {
|
|||
// If not set, it uses all versions available.
|
||||
Versions []VersionNumber
|
||||
// HandshakeIdleTimeout is the idle timeout before completion of the handshake.
|
||||
// Specifically, if we don't receive any packet from the peer within this time, the connection attempt is aborted.
|
||||
// If we don't receive any packet from the peer within this time, the connection attempt is aborted.
|
||||
// Additionally, if the handshake doesn't complete in twice this time, the connection attempt is also aborted.
|
||||
// If this value is zero, the timeout is set to 5 seconds.
|
||||
HandshakeIdleTimeout time.Duration
|
||||
// MaxIdleTimeout is the maximum duration that may pass without any incoming network activity.
|
||||
|
@ -265,13 +269,6 @@ type Config struct {
|
|||
// See https://datatracker.ietf.org/doc/html/rfc9000#section-8 for details.
|
||||
// If not set, every client is forced to prove its remote address.
|
||||
RequireAddressValidation func(net.Addr) bool
|
||||
// MaxRetryTokenAge is the maximum age of a Retry token.
|
||||
// If not set, it defaults to 5 seconds. Only valid for a server.
|
||||
MaxRetryTokenAge time.Duration
|
||||
// MaxTokenAge is the maximum age of the token presented during the handshake,
|
||||
// for tokens that were issued on a previous connection.
|
||||
// If not set, it defaults to 24 hours. Only valid for a server.
|
||||
MaxTokenAge time.Duration
|
||||
// The TokenStore stores tokens received from the server.
|
||||
// Tokens are used to skip address validation on future connection attempts.
|
||||
// The key used to store tokens is the ServerName from the tls.Config, if set
|
||||
|
@ -323,16 +320,12 @@ type Config struct {
|
|||
// Path MTU discovery is only available on systems that allow setting of the Don't Fragment (DF) bit.
|
||||
// If unavailable or disabled, packets will be at most 1252 (IPv4) / 1232 (IPv6) bytes in size.
|
||||
DisablePathMTUDiscovery bool
|
||||
// DisableVersionNegotiationPackets disables the sending of Version Negotiation packets.
|
||||
// This can be useful if version information is exchanged out-of-band.
|
||||
// It has no effect for a client.
|
||||
DisableVersionNegotiationPackets bool
|
||||
// Allow0RTT allows the application to decide if a 0-RTT connection attempt should be accepted.
|
||||
// Only valid for the server.
|
||||
Allow0RTT bool
|
||||
// Enable QUIC datagram support (RFC 9221).
|
||||
EnableDatagrams bool
|
||||
Tracer func(context.Context, logging.Perspective, ConnectionID) logging.ConnectionTracer
|
||||
Tracer func(context.Context, logging.Perspective, ConnectionID) *logging.ConnectionTracer
|
||||
}
|
||||
|
||||
type ClientHelloInfo struct {
|
||||
|
@ -352,4 +345,6 @@ type ConnectionState struct {
|
|||
Used0RTT bool
|
||||
// Version is the QUIC version of the QUIC connection.
|
||||
Version VersionNumber
|
||||
// GSO says if generic segmentation offload is used
|
||||
GSO bool
|
||||
}
|
||||
|
|
|
@ -14,10 +14,11 @@ func NewAckHandler(
|
|||
initialMaxDatagramSize protocol.ByteCount,
|
||||
rttStats *utils.RTTStats,
|
||||
clientAddressValidated bool,
|
||||
enableECN bool,
|
||||
pers protocol.Perspective,
|
||||
tracer logging.ConnectionTracer,
|
||||
tracer *logging.ConnectionTracer,
|
||||
logger utils.Logger,
|
||||
) (SentPacketHandler, ReceivedPacketHandler) {
|
||||
sph := newSentPacketHandler(initialPacketNumber, initialMaxDatagramSize, rttStats, clientAddressValidated, pers, tracer, logger)
|
||||
sph := newSentPacketHandler(initialPacketNumber, initialMaxDatagramSize, rttStats, clientAddressValidated, enableECN, pers, tracer, logger)
|
||||
return sph, newReceivedPacketHandler(sph, rttStats, logger)
|
||||
}
|
||||
|
|
296
internal/ackhandler/ecn.go
Normal file
296
internal/ackhandler/ecn.go
Normal file
|
@ -0,0 +1,296 @@
|
|||
package ackhandler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
"github.com/quic-go/quic-go/logging"
|
||||
)
|
||||
|
||||
type ecnState uint8
|
||||
|
||||
const (
|
||||
ecnStateInitial ecnState = iota
|
||||
ecnStateTesting
|
||||
ecnStateUnknown
|
||||
ecnStateCapable
|
||||
ecnStateFailed
|
||||
)
|
||||
|
||||
// must fit into an uint8, otherwise numSentTesting and numLostTesting must have a larger type
|
||||
const numECNTestingPackets = 10
|
||||
|
||||
type ecnHandler interface {
|
||||
SentPacket(protocol.PacketNumber, protocol.ECN)
|
||||
Mode() protocol.ECN
|
||||
HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64) (congested bool)
|
||||
LostPacket(protocol.PacketNumber)
|
||||
}
|
||||
|
||||
// The ecnTracker performs ECN validation of a path.
|
||||
// Once failed, it doesn't do any re-validation of the path.
|
||||
// It is designed only work for 1-RTT packets, it doesn't handle multiple packet number spaces.
|
||||
// In order to avoid revealing any internal state to on-path observers,
|
||||
// callers should make sure to start using ECN (i.e. calling Mode) for the very first 1-RTT packet sent.
|
||||
// The validation logic implemented here strictly follows the algorithm described in RFC 9000 section 13.4.2 and A.4.
|
||||
type ecnTracker struct {
|
||||
state ecnState
|
||||
numSentTesting, numLostTesting uint8
|
||||
|
||||
firstTestingPacket protocol.PacketNumber
|
||||
lastTestingPacket protocol.PacketNumber
|
||||
firstCapablePacket protocol.PacketNumber
|
||||
|
||||
numSentECT0, numSentECT1 int64
|
||||
numAckedECT0, numAckedECT1, numAckedECNCE int64
|
||||
|
||||
tracer *logging.ConnectionTracer
|
||||
logger utils.Logger
|
||||
}
|
||||
|
||||
var _ ecnHandler = &ecnTracker{}
|
||||
|
||||
func newECNTracker(logger utils.Logger, tracer *logging.ConnectionTracer) *ecnTracker {
|
||||
return &ecnTracker{
|
||||
firstTestingPacket: protocol.InvalidPacketNumber,
|
||||
lastTestingPacket: protocol.InvalidPacketNumber,
|
||||
firstCapablePacket: protocol.InvalidPacketNumber,
|
||||
state: ecnStateInitial,
|
||||
logger: logger,
|
||||
tracer: tracer,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ecnTracker) SentPacket(pn protocol.PacketNumber, ecn protocol.ECN) {
|
||||
//nolint:exhaustive // These are the only ones we need to take care of.
|
||||
switch ecn {
|
||||
case protocol.ECNNon:
|
||||
return
|
||||
case protocol.ECT0:
|
||||
e.numSentECT0++
|
||||
case protocol.ECT1:
|
||||
e.numSentECT1++
|
||||
case protocol.ECNUnsupported:
|
||||
if e.state != ecnStateFailed {
|
||||
panic("didn't expect ECN to be unsupported")
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("sent packet with unexpected ECN marking: %s", ecn))
|
||||
}
|
||||
|
||||
if e.state == ecnStateCapable && e.firstCapablePacket == protocol.InvalidPacketNumber {
|
||||
e.firstCapablePacket = pn
|
||||
}
|
||||
|
||||
if e.state != ecnStateTesting {
|
||||
return
|
||||
}
|
||||
|
||||
e.numSentTesting++
|
||||
if e.firstTestingPacket == protocol.InvalidPacketNumber {
|
||||
e.firstTestingPacket = pn
|
||||
}
|
||||
if e.numSentECT0+e.numSentECT1 >= numECNTestingPackets {
|
||||
if e.tracer != nil && e.tracer.ECNStateUpdated != nil {
|
||||
e.tracer.ECNStateUpdated(logging.ECNStateUnknown, logging.ECNTriggerNoTrigger)
|
||||
}
|
||||
e.state = ecnStateUnknown
|
||||
e.lastTestingPacket = pn
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ecnTracker) Mode() protocol.ECN {
|
||||
switch e.state {
|
||||
case ecnStateInitial:
|
||||
if e.tracer != nil && e.tracer.ECNStateUpdated != nil {
|
||||
e.tracer.ECNStateUpdated(logging.ECNStateTesting, logging.ECNTriggerNoTrigger)
|
||||
}
|
||||
e.state = ecnStateTesting
|
||||
return e.Mode()
|
||||
case ecnStateTesting, ecnStateCapable:
|
||||
return protocol.ECT0
|
||||
case ecnStateUnknown, ecnStateFailed:
|
||||
return protocol.ECNNon
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown ECN state: %d", e.state))
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ecnTracker) LostPacket(pn protocol.PacketNumber) {
|
||||
if e.state != ecnStateTesting && e.state != ecnStateUnknown {
|
||||
return
|
||||
}
|
||||
if !e.isTestingPacket(pn) {
|
||||
return
|
||||
}
|
||||
e.numLostTesting++
|
||||
// Only proceed if we have sent all 10 testing packets.
|
||||
if e.state != ecnStateUnknown {
|
||||
return
|
||||
}
|
||||
if e.numLostTesting >= e.numSentTesting {
|
||||
e.logger.Debugf("Disabling ECN. All testing packets were lost.")
|
||||
if e.tracer != nil && e.tracer.ECNStateUpdated != nil {
|
||||
e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedLostAllTestingPackets)
|
||||
}
|
||||
e.state = ecnStateFailed
|
||||
return
|
||||
}
|
||||
// Path validation also fails if some testing packets are lost, and all other testing packets where CE-marked
|
||||
e.failIfMangled()
|
||||
}
|
||||
|
||||
// HandleNewlyAcked handles the ECN counts on an ACK frame.
|
||||
// It must only be called for ACK frames that increase the largest acknowledged packet number,
|
||||
// see section 13.4.2.1 of RFC 9000.
|
||||
func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64) (congested bool) {
|
||||
if e.state == ecnStateFailed {
|
||||
return false
|
||||
}
|
||||
|
||||
// ECN validation can fail if the received total count for either ECT(0) or ECT(1) exceeds
|
||||
// the total number of packets sent with each corresponding ECT codepoint.
|
||||
if ect0 > e.numSentECT0 || ect1 > e.numSentECT1 {
|
||||
e.logger.Debugf("Disabling ECN. Received more ECT(0) / ECT(1) acknowledgements than packets sent.")
|
||||
if e.tracer != nil && e.tracer.ECNStateUpdated != nil {
|
||||
e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedMoreECNCountsThanSent)
|
||||
}
|
||||
e.state = ecnStateFailed
|
||||
return false
|
||||
}
|
||||
|
||||
// Count ECT0 and ECT1 marks that we used when sending the packets that are now being acknowledged.
|
||||
var ackedECT0, ackedECT1 int64
|
||||
for _, p := range packets {
|
||||
//nolint:exhaustive // We only ever send ECT(0) and ECT(1).
|
||||
switch e.ecnMarking(p.PacketNumber) {
|
||||
case protocol.ECT0:
|
||||
ackedECT0++
|
||||
case protocol.ECT1:
|
||||
ackedECT1++
|
||||
}
|
||||
}
|
||||
|
||||
// If an ACK frame newly acknowledges a packet that the endpoint sent with either the ECT(0) or ECT(1)
|
||||
// codepoint set, ECN validation fails if the corresponding ECN counts are not present in the ACK frame.
|
||||
// This check detects:
|
||||
// * paths that bleach all ECN marks, and
|
||||
// * peers that don't report any ECN counts
|
||||
if (ackedECT0 > 0 || ackedECT1 > 0) && ect0 == 0 && ect1 == 0 && ecnce == 0 {
|
||||
e.logger.Debugf("Disabling ECN. ECN-marked packet acknowledged, but no ECN counts on ACK frame.")
|
||||
if e.tracer != nil && e.tracer.ECNStateUpdated != nil {
|
||||
e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedNoECNCounts)
|
||||
}
|
||||
e.state = ecnStateFailed
|
||||
return false
|
||||
}
|
||||
|
||||
// Determine the increase in ECT0, ECT1 and ECNCE marks
|
||||
newECT0 := ect0 - e.numAckedECT0
|
||||
newECT1 := ect1 - e.numAckedECT1
|
||||
newECNCE := ecnce - e.numAckedECNCE
|
||||
|
||||
// We're only processing ACKs that increase the Largest Acked.
|
||||
// Therefore, the ECN counters should only ever increase.
|
||||
// Any decrease means that the peer's counting logic is broken.
|
||||
if newECT0 < 0 || newECT1 < 0 || newECNCE < 0 {
|
||||
e.logger.Debugf("Disabling ECN. ECN counts decreased unexpectedly.")
|
||||
if e.tracer != nil && e.tracer.ECNStateUpdated != nil {
|
||||
e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedDecreasedECNCounts)
|
||||
}
|
||||
e.state = ecnStateFailed
|
||||
return false
|
||||
}
|
||||
|
||||
// ECN validation also fails if the sum of the increase in ECT(0) and ECN-CE counts is less than the number
|
||||
// of newly acknowledged packets that were originally sent with an ECT(0) marking.
|
||||
// This could be the result of (partial) bleaching.
|
||||
if newECT0+newECNCE < ackedECT0 {
|
||||
e.logger.Debugf("Disabling ECN. Received less ECT(0) + ECN-CE than packets sent with ECT(0).")
|
||||
if e.tracer != nil && e.tracer.ECNStateUpdated != nil {
|
||||
e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedTooFewECNCounts)
|
||||
}
|
||||
e.state = ecnStateFailed
|
||||
return false
|
||||
}
|
||||
// Similarly, ECN validation fails if the sum of the increases to ECT(1) and ECN-CE counts is less than
|
||||
// the number of newly acknowledged packets sent with an ECT(1) marking.
|
||||
if newECT1+newECNCE < ackedECT1 {
|
||||
e.logger.Debugf("Disabling ECN. Received less ECT(1) + ECN-CE than packets sent with ECT(1).")
|
||||
if e.tracer != nil && e.tracer.ECNStateUpdated != nil {
|
||||
e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedTooFewECNCounts)
|
||||
}
|
||||
e.state = ecnStateFailed
|
||||
return false
|
||||
}
|
||||
|
||||
// update our counters
|
||||
e.numAckedECT0 = ect0
|
||||
e.numAckedECT1 = ect1
|
||||
e.numAckedECNCE = ecnce
|
||||
|
||||
// Detect mangling (a path remarking all ECN-marked testing packets as CE),
|
||||
// once all 10 testing packets have been sent out.
|
||||
if e.state == ecnStateUnknown {
|
||||
e.failIfMangled()
|
||||
if e.state == ecnStateFailed {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if e.state == ecnStateTesting || e.state == ecnStateUnknown {
|
||||
var ackedTestingPacket bool
|
||||
for _, p := range packets {
|
||||
if e.isTestingPacket(p.PacketNumber) {
|
||||
ackedTestingPacket = true
|
||||
break
|
||||
}
|
||||
}
|
||||
// This check won't succeed if the path is mangling ECN-marks (i.e. rewrites all ECN-marked packets to CE).
|
||||
if ackedTestingPacket && (newECT0 > 0 || newECT1 > 0) {
|
||||
e.logger.Debugf("ECN capability confirmed.")
|
||||
if e.tracer != nil && e.tracer.ECNStateUpdated != nil {
|
||||
e.tracer.ECNStateUpdated(logging.ECNStateCapable, logging.ECNTriggerNoTrigger)
|
||||
}
|
||||
e.state = ecnStateCapable
|
||||
}
|
||||
}
|
||||
|
||||
// Don't trust CE marks before having confirmed ECN capability of the path.
|
||||
// Otherwise, mangling would be misinterpreted as actual congestion.
|
||||
return e.state == ecnStateCapable && newECNCE > 0
|
||||
}
|
||||
|
||||
// failIfMangled fails ECN validation if all testing packets are lost or CE-marked.
|
||||
func (e *ecnTracker) failIfMangled() {
|
||||
numAckedECNCE := e.numAckedECNCE + int64(e.numLostTesting)
|
||||
if e.numSentECT0+e.numSentECT1 > numAckedECNCE {
|
||||
return
|
||||
}
|
||||
if e.tracer != nil && e.tracer.ECNStateUpdated != nil {
|
||||
e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected)
|
||||
}
|
||||
e.state = ecnStateFailed
|
||||
}
|
||||
|
||||
func (e *ecnTracker) ecnMarking(pn protocol.PacketNumber) protocol.ECN {
|
||||
if pn < e.firstTestingPacket || e.firstTestingPacket == protocol.InvalidPacketNumber {
|
||||
return protocol.ECNNon
|
||||
}
|
||||
if pn < e.lastTestingPacket || e.lastTestingPacket == protocol.InvalidPacketNumber {
|
||||
return protocol.ECT0
|
||||
}
|
||||
if pn < e.firstCapablePacket || e.firstCapablePacket == protocol.InvalidPacketNumber {
|
||||
return protocol.ECNNon
|
||||
}
|
||||
// We don't need to deal with the case when ECN validation fails,
|
||||
// since we're ignoring any ECN counts reported in ACK frames in that case.
|
||||
return protocol.ECT0
|
||||
}
|
||||
|
||||
func (e *ecnTracker) isTestingPacket(pn protocol.PacketNumber) bool {
|
||||
if e.firstTestingPacket == protocol.InvalidPacketNumber {
|
||||
return false
|
||||
}
|
||||
return pn >= e.firstTestingPacket && (pn <= e.lastTestingPacket || e.lastTestingPacket == protocol.InvalidPacketNumber)
|
||||
}
|
272
internal/ackhandler/ecn_test.go
Normal file
272
internal/ackhandler/ecn_test.go
Normal file
|
@ -0,0 +1,272 @@
|
|||
package ackhandler
|
||||
|
||||
import (
|
||||
mocklogging "github.com/quic-go/quic-go/internal/mocks/logging"
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
"github.com/quic-go/quic-go/logging"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("ECN tracker", func() {
|
||||
var ecnTracker *ecnTracker
|
||||
var tracer *mocklogging.MockConnectionTracer
|
||||
|
||||
getAckedPackets := func(pns ...protocol.PacketNumber) []*packet {
|
||||
var packets []*packet
|
||||
for _, p := range pns {
|
||||
packets = append(packets, &packet{PacketNumber: p})
|
||||
}
|
||||
return packets
|
||||
}
|
||||
|
||||
BeforeEach(func() {
|
||||
var tr *logging.ConnectionTracer
|
||||
tr, tracer = mocklogging.NewMockConnectionTracer(mockCtrl)
|
||||
ecnTracker = newECNTracker(utils.DefaultLogger, tr)
|
||||
})
|
||||
|
||||
It("sends exactly 10 testing packets", func() {
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateTesting, logging.ECNTriggerNoTrigger)
|
||||
for i := 0; i < 9; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECT0))
|
||||
// Do this twice to make sure only sent packets are counted
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECT0))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(10+i), protocol.ECT0)
|
||||
}
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECT0))
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateUnknown, logging.ECNTriggerNoTrigger)
|
||||
ecnTracker.SentPacket(20, protocol.ECT0)
|
||||
// In unknown state, packets shouldn't be ECN-marked.
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
})
|
||||
|
||||
sendAllTestingPackets := func() {
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateTesting, logging.ECNTriggerNoTrigger)
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateUnknown, logging.ECNTriggerNoTrigger)
|
||||
for i := 0; i < 10; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECT0))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECT0)
|
||||
}
|
||||
}
|
||||
|
||||
It("fails ECN validation if all ECN testing packets are lost", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
for i := 0; i < 9; i++ {
|
||||
ecnTracker.LostPacket(protocol.PacketNumber(i))
|
||||
}
|
||||
// We don't care about the loss of non-testing packets
|
||||
ecnTracker.LostPacket(15)
|
||||
// Now lose the last testing packet.
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedLostAllTestingPackets)
|
||||
ecnTracker.LostPacket(9)
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
// We still don't care about more non-testing packets being lost
|
||||
ecnTracker.LostPacket(16)
|
||||
})
|
||||
|
||||
It("only detects ECN mangling after sending all testing packets", func() {
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateTesting, logging.ECNTriggerNoTrigger)
|
||||
for i := 0; i < 9; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECT0))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECT0)
|
||||
ecnTracker.LostPacket(protocol.PacketNumber(i))
|
||||
}
|
||||
// Send the last testing packet, and receive a
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateUnknown, logging.ECNTriggerNoTrigger)
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECT0))
|
||||
ecnTracker.SentPacket(9, protocol.ECT0)
|
||||
// Now lose the last testing packet.
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedLostAllTestingPackets)
|
||||
ecnTracker.LostPacket(9)
|
||||
})
|
||||
|
||||
It("passes ECN validation when a testing packet is acknowledged, while still in testing state", func() {
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateTesting, logging.ECNTriggerNoTrigger)
|
||||
for i := 0; i < 5; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECT0))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECT0)
|
||||
}
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateCapable, logging.ECNTriggerNoTrigger)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(3), 1, 0, 0)).To(BeFalse())
|
||||
// make sure we continue sending ECT(0) packets
|
||||
for i := 5; i < 100; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECT0))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECT0)
|
||||
}
|
||||
})
|
||||
|
||||
It("passes ECN validation when a testing packet is acknowledged, while in unknown state", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
// Lose some packets to make sure this doesn't influence the outcome.
|
||||
for i := 0; i < 5; i++ {
|
||||
ecnTracker.LostPacket(protocol.PacketNumber(i))
|
||||
}
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateCapable, logging.ECNTriggerNoTrigger)
|
||||
Expect(ecnTracker.HandleNewlyAcked([]*packet{{PacketNumber: 7}}, 1, 0, 0)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("fails ECN validation when the ACK contains more ECN counts than we sent packets", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
// only 10 ECT(0) packets were sent, but the ACK claims to have received 12 of them
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedMoreECNCountsThanSent)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), 12, 0, 0)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("fails ECN validation when the ACK contains ECN counts for the wrong code point", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
// We sent ECT(0), but this ACK acknowledges ECT(1).
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedMoreECNCountsThanSent)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), 0, 1, 0)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("fails ECN validation when the ACK doesn't contain ECN counts", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
// First only acknowledge packets sent without ECN marks.
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(12, 13, 14), 0, 0, 0)).To(BeFalse())
|
||||
// Now acknowledge some packets sent with ECN marks.
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedNoECNCounts)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(1, 2, 3, 15), 0, 0, 0)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("fails ECN validation when an ACK decreases ECN counts", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateCapable, logging.ECNTriggerNoTrigger)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(1, 2, 3, 12), 3, 0, 0)).To(BeFalse())
|
||||
// Now acknowledge some more packets, but decrease the ECN counts. Obviously, this doesn't make any sense.
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedDecreasedECNCounts)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(4, 5, 6, 13), 2, 0, 0)).To(BeFalse())
|
||||
// make sure that new ACKs are ignored
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(7, 8, 9, 14), 5, 0, 0)).To(BeFalse())
|
||||
})
|
||||
|
||||
// This can happen if ACK are lost / reordered.
|
||||
It("doesn't fail validation if the ACK contains more ECN counts than it acknowledges packets", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateCapable, logging.ECNTriggerNoTrigger)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(1, 2, 3, 12), 8, 0, 0)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("fails ECN validation when the ACK doesn't contain enough ECN counts", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
// First only acknowledge some packets sent with ECN marks.
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateCapable, logging.ECNTriggerNoTrigger)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(1, 2, 3, 12), 2, 0, 1)).To(BeTrue())
|
||||
// Now acknowledge some more packets sent with ECN marks, but don't increase the counters enough.
|
||||
// This ACK acknowledges 3 more ECN-marked packets, but the counters only increase by 2.
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedTooFewECNCounts)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(4, 5, 6, 15), 3, 0, 2)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("detects ECN mangling if all testing packets are marked CE", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
// ECN capability not confirmed yet, therefore CE marks are not regarded as congestion events
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(0, 1, 2, 3), 0, 0, 4)).To(BeFalse())
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(4, 5, 6, 10, 11, 12), 0, 0, 7)).To(BeFalse())
|
||||
// With the next ACK, all testing packets will now have been marked CE.
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(7, 8, 9, 13), 0, 0, 10)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("only detects ECN mangling after sending all testing packets", func() {
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateTesting, logging.ECNTriggerNoTrigger)
|
||||
for i := 0; i < 9; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECT0))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECT0)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(protocol.PacketNumber(i)), 0, 0, int64(i+1))).To(BeFalse())
|
||||
}
|
||||
// Send the last testing packet, and receive a
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateUnknown, logging.ECNTriggerNoTrigger)
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECT0))
|
||||
ecnTracker.SentPacket(9, protocol.ECT0)
|
||||
// This ACK now reports the last testing packets as CE as well.
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(9), 0, 0, 10)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("detects ECN mangling, if some testing packets are marked CE, and then others are lost", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
// ECN capability not confirmed yet, therefore CE marks are not regarded as congestion events
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(0, 1, 2, 3), 0, 0, 4)).To(BeFalse())
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(6, 7, 8, 9), 0, 0, 8)).To(BeFalse())
|
||||
// Lose one of the two unacknowledged packets.
|
||||
ecnTracker.LostPacket(4)
|
||||
// By losing the last unacknowledged testing packets, we should detect the mangling.
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected)
|
||||
ecnTracker.LostPacket(5)
|
||||
})
|
||||
|
||||
It("detects ECN mangling, if some testing packets are lost, and then others are marked CE", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
// Lose a few packets.
|
||||
ecnTracker.LostPacket(0)
|
||||
ecnTracker.LostPacket(1)
|
||||
ecnTracker.LostPacket(2)
|
||||
// ECN capability not confirmed yet, therefore CE marks are not regarded as congestion events
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(3, 4, 5, 6, 7, 8), 0, 0, 6)).To(BeFalse())
|
||||
// By CE-marking the last unacknowledged testing packets, we should detect the mangling.
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(9), 0, 0, 7)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("declares congestion", func() {
|
||||
sendAllTestingPackets()
|
||||
for i := 10; i < 20; i++ {
|
||||
Expect(ecnTracker.Mode()).To(Equal(protocol.ECNNon))
|
||||
ecnTracker.SentPacket(protocol.PacketNumber(i), protocol.ECNNon)
|
||||
}
|
||||
// Receive one CE count.
|
||||
tracer.EXPECT().ECNStateUpdated(logging.ECNStateCapable, logging.ECNTriggerNoTrigger)
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(1, 2, 3, 12), 2, 0, 1)).To(BeTrue())
|
||||
// No increase in CE. No congestion.
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(4, 5, 6, 13), 5, 0, 1)).To(BeFalse())
|
||||
// Increase in CE. More congestion.
|
||||
Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(7, 8, 9, 14), 7, 0, 2)).To(BeTrue())
|
||||
})
|
||||
})
|
|
@ -10,13 +10,13 @@ import (
|
|||
// SentPacketHandler handles ACKs received for outgoing packets
|
||||
type SentPacketHandler interface {
|
||||
// SentPacket may modify the packet
|
||||
SentPacket(t time.Time, pn, largestAcked protocol.PacketNumber, streamFrames []StreamFrame, frames []Frame, encLevel protocol.EncryptionLevel, size protocol.ByteCount, isPathMTUProbePacket bool)
|
||||
SentPacket(t time.Time, pn, largestAcked protocol.PacketNumber, streamFrames []StreamFrame, frames []Frame, encLevel protocol.EncryptionLevel, ecn protocol.ECN, size protocol.ByteCount, isPathMTUProbePacket bool)
|
||||
// ReceivedAck processes an ACK frame.
|
||||
// It does not store a copy of the frame.
|
||||
ReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, recvTime time.Time) (bool /* 1-RTT packet acked */, error)
|
||||
ReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool /* 1-RTT packet acked */, error)
|
||||
ReceivedBytes(protocol.ByteCount)
|
||||
DropPackets(protocol.EncryptionLevel)
|
||||
ResetForRetry() error
|
||||
ResetForRetry(rcvTime time.Time) error
|
||||
SetHandshakeConfirmed()
|
||||
|
||||
// The SendMode determines if and what kind of packets can be sent.
|
||||
|
@ -29,6 +29,7 @@ type SentPacketHandler interface {
|
|||
// only to be called once the handshake is complete
|
||||
QueueProbePacket(protocol.EncryptionLevel) bool /* was a packet queued */
|
||||
|
||||
ECNMode(isShortHeaderPacket bool) protocol.ECN // isShortHeaderPacket should only be true for non-coalesced 1-RTT packets
|
||||
PeekPacketNumber(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen)
|
||||
PopPacketNumber(protocol.EncryptionLevel) protocol.PacketNumber
|
||||
|
||||
|
@ -44,7 +45,7 @@ type sentPacketTracker interface {
|
|||
// ReceivedPacketHandler handles ACKs needed to send for incoming packets
|
||||
type ReceivedPacketHandler interface {
|
||||
IsPotentiallyDuplicate(protocol.PacketNumber, protocol.EncryptionLevel) bool
|
||||
ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, encLevel protocol.EncryptionLevel, rcvTime time.Time, shouldInstigateAck bool) error
|
||||
ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, encLevel protocol.EncryptionLevel, rcvTime time.Time, ackEliciting bool) error
|
||||
DropPackets(protocol.EncryptionLevel)
|
||||
|
||||
GetAlarmTimeout() time.Time
|
||||
|
|
91
internal/ackhandler/mock_ecn_handler_test.go
Normal file
91
internal/ackhandler/mock_ecn_handler_test.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/quic-go/quic-go/internal/ackhandler (interfaces: ECNHandler)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package ackhandler -destination mock_ecn_handler_test.go github.com/quic-go/quic-go/internal/ackhandler ECNHandler
|
||||
//
|
||||
// Package ackhandler is a generated GoMock package.
|
||||
package ackhandler
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
protocol "github.com/quic-go/quic-go/internal/protocol"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockECNHandler is a mock of ECNHandler interface.
|
||||
type MockECNHandler struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockECNHandlerMockRecorder
|
||||
}
|
||||
|
||||
// MockECNHandlerMockRecorder is the mock recorder for MockECNHandler.
|
||||
type MockECNHandlerMockRecorder struct {
|
||||
mock *MockECNHandler
|
||||
}
|
||||
|
||||
// NewMockECNHandler creates a new mock instance.
|
||||
func NewMockECNHandler(ctrl *gomock.Controller) *MockECNHandler {
|
||||
mock := &MockECNHandler{ctrl: ctrl}
|
||||
mock.recorder = &MockECNHandlerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockECNHandler) EXPECT() *MockECNHandlerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// HandleNewlyAcked mocks base method.
|
||||
func (m *MockECNHandler) HandleNewlyAcked(arg0 []*packet, arg1, arg2, arg3 int64) bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HandleNewlyAcked", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HandleNewlyAcked indicates an expected call of HandleNewlyAcked.
|
||||
func (mr *MockECNHandlerMockRecorder) HandleNewlyAcked(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleNewlyAcked", reflect.TypeOf((*MockECNHandler)(nil).HandleNewlyAcked), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// LostPacket mocks base method.
|
||||
func (m *MockECNHandler) LostPacket(arg0 protocol.PacketNumber) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "LostPacket", arg0)
|
||||
}
|
||||
|
||||
// LostPacket indicates an expected call of LostPacket.
|
||||
func (mr *MockECNHandlerMockRecorder) LostPacket(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LostPacket", reflect.TypeOf((*MockECNHandler)(nil).LostPacket), arg0)
|
||||
}
|
||||
|
||||
// Mode mocks base method.
|
||||
func (m *MockECNHandler) Mode() protocol.ECN {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Mode")
|
||||
ret0, _ := ret[0].(protocol.ECN)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Mode indicates an expected call of Mode.
|
||||
func (mr *MockECNHandlerMockRecorder) Mode() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Mode", reflect.TypeOf((*MockECNHandler)(nil).Mode))
|
||||
}
|
||||
|
||||
// SentPacket mocks base method.
|
||||
func (m *MockECNHandler) SentPacket(arg0 protocol.PacketNumber, arg1 protocol.ECN) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentPacket", arg0, arg1)
|
||||
}
|
||||
|
||||
// SentPacket indicates an expected call of SentPacket.
|
||||
func (mr *MockECNHandlerMockRecorder) SentPacket(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockECNHandler)(nil).SentPacket), arg0, arg1)
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/internal/ackhandler (interfaces: SentPacketTracker)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package ackhandler -destination mock_sent_packet_tracker_test.go github.com/refraction-networking/uquic/internal/ackhandler SentPacketTracker
|
||||
//
|
||||
// Package ackhandler is a generated GoMock package.
|
||||
package ackhandler
|
||||
|
||||
|
@ -55,7 +59,7 @@ func (m *MockSentPacketTracker) ReceivedPacket(arg0 protocol.EncryptionLevel) {
|
|||
}
|
||||
|
||||
// ReceivedPacket indicates an expected call of ReceivedPacket.
|
||||
func (mr *MockSentPacketTrackerMockRecorder) ReceivedPacket(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSentPacketTrackerMockRecorder) ReceivedPacket(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedPacket", reflect.TypeOf((*MockSentPacketTracker)(nil).ReceivedPacket), arg0)
|
||||
}
|
||||
|
|
|
@ -4,3 +4,6 @@ package ackhandler
|
|||
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package ackhandler -destination mock_sent_packet_tracker_test.go github.com/refraction-networking/uquic/internal/ackhandler SentPacketTracker"
|
||||
type SentPacketTracker = sentPacketTracker
|
||||
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package ackhandler -destination mock_ecn_handler_test.go github.com/quic-go/quic-go/internal/ackhandler ECNHandler"
|
||||
type ECNHandler = ecnHandler
|
||||
|
|
|
@ -40,29 +40,29 @@ func (h *receivedPacketHandler) ReceivedPacket(
|
|||
ecn protocol.ECN,
|
||||
encLevel protocol.EncryptionLevel,
|
||||
rcvTime time.Time,
|
||||
shouldInstigateAck bool,
|
||||
ackEliciting bool,
|
||||
) error {
|
||||
h.sentPackets.ReceivedPacket(encLevel)
|
||||
switch encLevel {
|
||||
case protocol.EncryptionInitial:
|
||||
return h.initialPackets.ReceivedPacket(pn, ecn, rcvTime, shouldInstigateAck)
|
||||
return h.initialPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting)
|
||||
case protocol.EncryptionHandshake:
|
||||
// The Handshake packet number space might already have been dropped as a result
|
||||
// of processing the CRYPTO frame that was contained in this packet.
|
||||
if h.handshakePackets == nil {
|
||||
return nil
|
||||
}
|
||||
return h.handshakePackets.ReceivedPacket(pn, ecn, rcvTime, shouldInstigateAck)
|
||||
return h.handshakePackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting)
|
||||
case protocol.Encryption0RTT:
|
||||
if h.lowest1RTTPacket != protocol.InvalidPacketNumber && pn > h.lowest1RTTPacket {
|
||||
return fmt.Errorf("received packet number %d on a 0-RTT packet after receiving %d on a 1-RTT packet", pn, h.lowest1RTTPacket)
|
||||
}
|
||||
return h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, shouldInstigateAck)
|
||||
return h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting)
|
||||
case protocol.Encryption1RTT:
|
||||
if h.lowest1RTTPacket == protocol.InvalidPacketNumber || pn < h.lowest1RTTPacket {
|
||||
h.lowest1RTTPacket = pn
|
||||
}
|
||||
if err := h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, shouldInstigateAck); err != nil {
|
||||
if err := h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting); err != nil {
|
||||
return err
|
||||
}
|
||||
h.appDataPackets.IgnoreBelow(h.sentPackets.GetLowestPacketNotConfirmedAcked())
|
||||
|
|
|
@ -13,10 +13,10 @@ import (
|
|||
const packetsBeforeAck = 2
|
||||
|
||||
type receivedPacketTracker struct {
|
||||
largestObserved protocol.PacketNumber
|
||||
ignoreBelow protocol.PacketNumber
|
||||
largestObservedReceivedTime time.Time
|
||||
ect0, ect1, ecnce uint64
|
||||
largestObserved protocol.PacketNumber
|
||||
ignoreBelow protocol.PacketNumber
|
||||
largestObservedRcvdTime time.Time
|
||||
ect0, ect1, ecnce uint64
|
||||
|
||||
packetHistory *receivedPacketHistory
|
||||
|
||||
|
@ -45,25 +45,25 @@ func newReceivedPacketTracker(
|
|||
}
|
||||
}
|
||||
|
||||
func (h *receivedPacketTracker) ReceivedPacket(packetNumber protocol.PacketNumber, ecn protocol.ECN, rcvTime time.Time, shouldInstigateAck bool) error {
|
||||
if isNew := h.packetHistory.ReceivedPacket(packetNumber); !isNew {
|
||||
return fmt.Errorf("recevedPacketTracker BUG: ReceivedPacket called for old / duplicate packet %d", packetNumber)
|
||||
func (h *receivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, rcvTime time.Time, ackEliciting bool) error {
|
||||
if isNew := h.packetHistory.ReceivedPacket(pn); !isNew {
|
||||
return fmt.Errorf("recevedPacketTracker BUG: ReceivedPacket called for old / duplicate packet %d", pn)
|
||||
}
|
||||
|
||||
isMissing := h.isMissing(packetNumber)
|
||||
if packetNumber >= h.largestObserved {
|
||||
h.largestObserved = packetNumber
|
||||
h.largestObservedReceivedTime = rcvTime
|
||||
isMissing := h.isMissing(pn)
|
||||
if pn >= h.largestObserved {
|
||||
h.largestObserved = pn
|
||||
h.largestObservedRcvdTime = rcvTime
|
||||
}
|
||||
|
||||
if shouldInstigateAck {
|
||||
if ackEliciting {
|
||||
h.hasNewAck = true
|
||||
}
|
||||
if shouldInstigateAck {
|
||||
h.maybeQueueAck(packetNumber, rcvTime, isMissing)
|
||||
if ackEliciting {
|
||||
h.maybeQueueACK(pn, rcvTime, isMissing)
|
||||
}
|
||||
//nolint:exhaustive // Only need to count ECT(0), ECT(1) and ECNCE.
|
||||
switch ecn {
|
||||
case protocol.ECNNon:
|
||||
case protocol.ECT0:
|
||||
h.ect0++
|
||||
case protocol.ECT1:
|
||||
|
@ -76,14 +76,14 @@ func (h *receivedPacketTracker) ReceivedPacket(packetNumber protocol.PacketNumbe
|
|||
|
||||
// IgnoreBelow sets a lower limit for acknowledging packets.
|
||||
// Packets with packet numbers smaller than p will not be acked.
|
||||
func (h *receivedPacketTracker) IgnoreBelow(p protocol.PacketNumber) {
|
||||
if p <= h.ignoreBelow {
|
||||
func (h *receivedPacketTracker) IgnoreBelow(pn protocol.PacketNumber) {
|
||||
if pn <= h.ignoreBelow {
|
||||
return
|
||||
}
|
||||
h.ignoreBelow = p
|
||||
h.packetHistory.DeleteBelow(p)
|
||||
h.ignoreBelow = pn
|
||||
h.packetHistory.DeleteBelow(pn)
|
||||
if h.logger.Debug() {
|
||||
h.logger.Debugf("\tIgnoring all packets below %d.", p)
|
||||
h.logger.Debugf("\tIgnoring all packets below %d.", pn)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,8 +103,8 @@ func (h *receivedPacketTracker) hasNewMissingPackets() bool {
|
|||
return highestRange.Smallest > h.lastAck.LargestAcked()+1 && highestRange.Len() == 1
|
||||
}
|
||||
|
||||
// maybeQueueAck queues an ACK, if necessary.
|
||||
func (h *receivedPacketTracker) maybeQueueAck(pn protocol.PacketNumber, rcvTime time.Time, wasMissing bool) {
|
||||
// maybeQueueACK queues an ACK, if necessary.
|
||||
func (h *receivedPacketTracker) maybeQueueACK(pn protocol.PacketNumber, rcvTime time.Time, wasMissing bool) {
|
||||
// always acknowledge the first packet
|
||||
if h.lastAck == nil {
|
||||
if !h.ackQueued {
|
||||
|
@ -175,7 +175,7 @@ func (h *receivedPacketTracker) GetAckFrame(onlyIfQueued bool) *wire.AckFrame {
|
|||
ack = &wire.AckFrame{}
|
||||
}
|
||||
ack.Reset()
|
||||
ack.DelayTime = utils.Max(0, now.Sub(h.largestObservedReceivedTime))
|
||||
ack.DelayTime = utils.Max(0, now.Sub(h.largestObservedRcvdTime))
|
||||
ack.ECT0 = h.ect0
|
||||
ack.ECT1 = h.ect1
|
||||
ack.ECNCE = h.ecnce
|
||||
|
|
|
@ -25,26 +25,26 @@ var _ = Describe("Received Packet Tracker", func() {
|
|||
Context("accepting packets", func() {
|
||||
It("saves the time when each packet arrived", func() {
|
||||
Expect(tracker.ReceivedPacket(protocol.PacketNumber(3), protocol.ECNNon, time.Now(), true)).To(Succeed())
|
||||
Expect(tracker.largestObservedReceivedTime).To(BeTemporally("~", time.Now(), 10*time.Millisecond))
|
||||
Expect(tracker.largestObservedRcvdTime).To(BeTemporally("~", time.Now(), 10*time.Millisecond))
|
||||
})
|
||||
|
||||
It("updates the largestObserved and the largestObservedReceivedTime", func() {
|
||||
It("updates the largestObserved and the largestObservedRcvdTime", func() {
|
||||
now := time.Now()
|
||||
tracker.largestObserved = 3
|
||||
tracker.largestObservedReceivedTime = now.Add(-1 * time.Second)
|
||||
tracker.largestObservedRcvdTime = now.Add(-1 * time.Second)
|
||||
Expect(tracker.ReceivedPacket(5, protocol.ECNNon, now, true)).To(Succeed())
|
||||
Expect(tracker.largestObserved).To(Equal(protocol.PacketNumber(5)))
|
||||
Expect(tracker.largestObservedReceivedTime).To(Equal(now))
|
||||
Expect(tracker.largestObservedRcvdTime).To(Equal(now))
|
||||
})
|
||||
|
||||
It("doesn't update the largestObserved and the largestObservedReceivedTime for a belated packet", func() {
|
||||
It("doesn't update the largestObserved and the largestObservedRcvdTime for a belated packet", func() {
|
||||
now := time.Now()
|
||||
timestamp := now.Add(-1 * time.Second)
|
||||
tracker.largestObserved = 5
|
||||
tracker.largestObservedReceivedTime = timestamp
|
||||
tracker.largestObservedRcvdTime = timestamp
|
||||
Expect(tracker.ReceivedPacket(4, protocol.ECNNon, now, true)).To(Succeed())
|
||||
Expect(tracker.largestObserved).To(Equal(protocol.PacketNumber(5)))
|
||||
Expect(tracker.largestObservedReceivedTime).To(Equal(timestamp))
|
||||
Expect(tracker.largestObservedRcvdTime).To(Equal(timestamp))
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -92,9 +92,12 @@ type sentPacketHandler struct {
|
|||
// The alarm timeout
|
||||
alarm time.Time
|
||||
|
||||
enableECN bool
|
||||
ecnTracker ecnHandler
|
||||
|
||||
perspective protocol.Perspective
|
||||
|
||||
tracer logging.ConnectionTracer
|
||||
tracer *logging.ConnectionTracer
|
||||
logger utils.Logger
|
||||
}
|
||||
|
||||
|
@ -110,8 +113,9 @@ func newSentPacketHandler(
|
|||
initialMaxDatagramSize protocol.ByteCount,
|
||||
rttStats *utils.RTTStats,
|
||||
clientAddressValidated bool,
|
||||
enableECN bool,
|
||||
pers protocol.Perspective,
|
||||
tracer logging.ConnectionTracer,
|
||||
tracer *logging.ConnectionTracer,
|
||||
logger utils.Logger,
|
||||
) *sentPacketHandler {
|
||||
congestion := congestion.NewCubicSender(
|
||||
|
@ -122,7 +126,7 @@ func newSentPacketHandler(
|
|||
tracer,
|
||||
)
|
||||
|
||||
return &sentPacketHandler{
|
||||
h := &sentPacketHandler{
|
||||
peerCompletedAddressValidation: pers == protocol.PerspectiveServer,
|
||||
peerAddressValidated: pers == protocol.PerspectiveClient || clientAddressValidated,
|
||||
initialPackets: newPacketNumberSpace(initialPN, false),
|
||||
|
@ -134,6 +138,11 @@ func newSentPacketHandler(
|
|||
tracer: tracer,
|
||||
logger: logger,
|
||||
}
|
||||
if enableECN {
|
||||
h.enableECN = true
|
||||
h.ecnTracker = newECNTracker(logger, tracer)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) removeFromBytesInFlight(p *packet) {
|
||||
|
@ -187,7 +196,7 @@ func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel) {
|
|||
default:
|
||||
panic(fmt.Sprintf("Cannot drop keys for encryption level %s", encLevel))
|
||||
}
|
||||
if h.tracer != nil && h.ptoCount != 0 {
|
||||
if h.tracer != nil && h.tracer.UpdatedPTOCount != nil && h.ptoCount != 0 {
|
||||
h.tracer.UpdatedPTOCount(0)
|
||||
}
|
||||
h.ptoCount = 0
|
||||
|
@ -228,6 +237,7 @@ func (h *sentPacketHandler) SentPacket(
|
|||
streamFrames []StreamFrame,
|
||||
frames []Frame,
|
||||
encLevel protocol.EncryptionLevel,
|
||||
ecn protocol.ECN,
|
||||
size protocol.ByteCount,
|
||||
isPathMTUProbePacket bool,
|
||||
) {
|
||||
|
@ -252,6 +262,10 @@ func (h *sentPacketHandler) SentPacket(
|
|||
}
|
||||
h.congestion.OnPacketSent(t, h.bytesInFlight, pn, size, isAckEliciting)
|
||||
|
||||
if encLevel == protocol.Encryption1RTT && h.ecnTracker != nil {
|
||||
h.ecnTracker.SentPacket(pn, ecn)
|
||||
}
|
||||
|
||||
if !isAckEliciting {
|
||||
pnSpace.history.SentNonAckElicitingPacket(pn)
|
||||
if !h.peerCompletedAddressValidation {
|
||||
|
@ -272,7 +286,7 @@ func (h *sentPacketHandler) SentPacket(
|
|||
p.includedInBytesInFlight = true
|
||||
|
||||
pnSpace.history.SentAckElicitingPacket(p)
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.UpdatedMetrics != nil {
|
||||
h.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight())
|
||||
}
|
||||
h.setLossDetectionTimer()
|
||||
|
@ -302,8 +316,6 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En
|
|||
}
|
||||
}
|
||||
|
||||
pnSpace.largestAcked = utils.Max(pnSpace.largestAcked, largestAcked)
|
||||
|
||||
// Servers complete address validation when a protected packet is received.
|
||||
if h.perspective == protocol.PerspectiveClient && !h.peerCompletedAddressValidation &&
|
||||
(encLevel == protocol.EncryptionHandshake || encLevel == protocol.Encryption1RTT) {
|
||||
|
@ -333,6 +345,17 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En
|
|||
h.congestion.MaybeExitSlowStart()
|
||||
}
|
||||
}
|
||||
|
||||
// Only inform the ECN tracker about new 1-RTT ACKs if the ACK increases the largest acked.
|
||||
if encLevel == protocol.Encryption1RTT && h.ecnTracker != nil && largestAcked > pnSpace.largestAcked {
|
||||
congested := h.ecnTracker.HandleNewlyAcked(ackedPackets, int64(ack.ECT0), int64(ack.ECT1), int64(ack.ECNCE))
|
||||
if congested {
|
||||
h.congestion.OnCongestionEvent(largestAcked, 0, priorInFlight)
|
||||
}
|
||||
}
|
||||
|
||||
pnSpace.largestAcked = utils.Max(pnSpace.largestAcked, largestAcked)
|
||||
|
||||
if err := h.detectLostPackets(rcvTime, encLevel); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -353,14 +376,14 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En
|
|||
|
||||
// Reset the pto_count unless the client is unsure if the server has validated the client's address.
|
||||
if h.peerCompletedAddressValidation {
|
||||
if h.tracer != nil && h.ptoCount != 0 {
|
||||
if h.tracer != nil && h.tracer.UpdatedPTOCount != nil && h.ptoCount != 0 {
|
||||
h.tracer.UpdatedPTOCount(0)
|
||||
}
|
||||
h.ptoCount = 0
|
||||
}
|
||||
h.numProbesToSend = 0
|
||||
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.UpdatedMetrics != nil {
|
||||
h.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight())
|
||||
}
|
||||
|
||||
|
@ -439,7 +462,7 @@ func (h *sentPacketHandler) detectAndRemoveAckedPackets(ack *wire.AckFrame, encL
|
|||
if err := pnSpace.history.Remove(p.PacketNumber); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.AcknowledgedPacket != nil {
|
||||
h.tracer.AcknowledgedPacket(encLevel, p.PacketNumber)
|
||||
}
|
||||
}
|
||||
|
@ -532,7 +555,7 @@ func (h *sentPacketHandler) setLossDetectionTimer() {
|
|||
if !lossTime.IsZero() {
|
||||
// Early retransmit timer or time loss detection.
|
||||
h.alarm = lossTime
|
||||
if h.tracer != nil && h.alarm != oldAlarm {
|
||||
if h.tracer != nil && h.tracer.SetLossTimer != nil && h.alarm != oldAlarm {
|
||||
h.tracer.SetLossTimer(logging.TimerTypeACK, encLevel, h.alarm)
|
||||
}
|
||||
return
|
||||
|
@ -543,7 +566,7 @@ func (h *sentPacketHandler) setLossDetectionTimer() {
|
|||
h.alarm = time.Time{}
|
||||
if !oldAlarm.IsZero() {
|
||||
h.logger.Debugf("Canceling loss detection timer. Amplification limited.")
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.LossTimerCanceled != nil {
|
||||
h.tracer.LossTimerCanceled()
|
||||
}
|
||||
}
|
||||
|
@ -555,7 +578,7 @@ func (h *sentPacketHandler) setLossDetectionTimer() {
|
|||
h.alarm = time.Time{}
|
||||
if !oldAlarm.IsZero() {
|
||||
h.logger.Debugf("Canceling loss detection timer. No packets in flight.")
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.LossTimerCanceled != nil {
|
||||
h.tracer.LossTimerCanceled()
|
||||
}
|
||||
}
|
||||
|
@ -568,14 +591,14 @@ func (h *sentPacketHandler) setLossDetectionTimer() {
|
|||
if !oldAlarm.IsZero() {
|
||||
h.alarm = time.Time{}
|
||||
h.logger.Debugf("Canceling loss detection timer. No PTO needed..")
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.LossTimerCanceled != nil {
|
||||
h.tracer.LossTimerCanceled()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
h.alarm = ptoTime
|
||||
if h.tracer != nil && h.alarm != oldAlarm {
|
||||
if h.tracer != nil && h.tracer.SetLossTimer != nil && h.alarm != oldAlarm {
|
||||
h.tracer.SetLossTimer(logging.TimerTypePTO, encLevel, h.alarm)
|
||||
}
|
||||
}
|
||||
|
@ -606,7 +629,7 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E
|
|||
if h.logger.Debug() {
|
||||
h.logger.Debugf("\tlost packet %d (time threshold)", p.PacketNumber)
|
||||
}
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.LostPacket != nil {
|
||||
h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossTimeThreshold)
|
||||
}
|
||||
}
|
||||
|
@ -616,7 +639,7 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E
|
|||
if h.logger.Debug() {
|
||||
h.logger.Debugf("\tlost packet %d (reordering threshold)", p.PacketNumber)
|
||||
}
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.LostPacket != nil {
|
||||
h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossReorderingThreshold)
|
||||
}
|
||||
}
|
||||
|
@ -635,7 +658,10 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E
|
|||
h.removeFromBytesInFlight(p)
|
||||
h.queueFramesForRetransmission(p)
|
||||
if !p.IsPathMTUProbePacket {
|
||||
h.congestion.OnPacketLost(p.PacketNumber, p.Length, priorInFlight)
|
||||
h.congestion.OnCongestionEvent(p.PacketNumber, p.Length, priorInFlight)
|
||||
}
|
||||
if encLevel == protocol.Encryption1RTT && h.ecnTracker != nil {
|
||||
h.ecnTracker.LostPacket(p.PacketNumber)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -650,7 +676,7 @@ func (h *sentPacketHandler) OnLossDetectionTimeout() error {
|
|||
if h.logger.Debug() {
|
||||
h.logger.Debugf("Loss detection alarm fired in loss timer mode. Loss time: %s", earliestLossTime)
|
||||
}
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.LossTimerExpired != nil {
|
||||
h.tracer.LossTimerExpired(logging.TimerTypeACK, encLevel)
|
||||
}
|
||||
// Early retransmit or time loss detection
|
||||
|
@ -687,8 +713,12 @@ func (h *sentPacketHandler) OnLossDetectionTimeout() error {
|
|||
h.logger.Debugf("Loss detection alarm for %s fired in PTO mode. PTO count: %d", encLevel, h.ptoCount)
|
||||
}
|
||||
if h.tracer != nil {
|
||||
h.tracer.LossTimerExpired(logging.TimerTypePTO, encLevel)
|
||||
h.tracer.UpdatedPTOCount(h.ptoCount)
|
||||
if h.tracer.LossTimerExpired != nil {
|
||||
h.tracer.LossTimerExpired(logging.TimerTypePTO, encLevel)
|
||||
}
|
||||
if h.tracer.UpdatedPTOCount != nil {
|
||||
h.tracer.UpdatedPTOCount(h.ptoCount)
|
||||
}
|
||||
}
|
||||
h.numProbesToSend += 2
|
||||
//nolint:exhaustive // We never arm a PTO timer for 0-RTT packets.
|
||||
|
@ -712,6 +742,16 @@ func (h *sentPacketHandler) GetLossDetectionTimeout() time.Time {
|
|||
return h.alarm
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) ECNMode(isShortHeaderPacket bool) protocol.ECN {
|
||||
if !h.enableECN {
|
||||
return protocol.ECNUnsupported
|
||||
}
|
||||
if !isShortHeaderPacket {
|
||||
return protocol.ECNNon
|
||||
}
|
||||
return h.ecnTracker.Mode()
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) PeekPacketNumber(encLevel protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen) {
|
||||
pnSpace := h.getPacketNumberSpace(encLevel)
|
||||
pn := pnSpace.pns.Peek()
|
||||
|
@ -825,7 +865,7 @@ func (h *sentPacketHandler) queueFramesForRetransmission(p *packet) {
|
|||
p.Frames = nil
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) ResetForRetry() error {
|
||||
func (h *sentPacketHandler) ResetForRetry(now time.Time) error {
|
||||
h.bytesInFlight = 0
|
||||
var firstPacketSendTime time.Time
|
||||
h.initialPackets.history.Iterate(func(p *packet) (bool, error) {
|
||||
|
@ -851,12 +891,11 @@ func (h *sentPacketHandler) ResetForRetry() 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.
|
||||
now := time.Now()
|
||||
h.rttStats.UpdateRTT(utils.Max(minRTTAfterRetry, now.Sub(firstPacketSendTime)), 0, now)
|
||||
if h.logger.Debug() {
|
||||
h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation())
|
||||
}
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.UpdatedMetrics != nil {
|
||||
h.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight())
|
||||
}
|
||||
}
|
||||
|
@ -865,8 +904,10 @@ func (h *sentPacketHandler) ResetForRetry() error {
|
|||
oldAlarm := h.alarm
|
||||
h.alarm = time.Time{}
|
||||
if h.tracer != nil {
|
||||
h.tracer.UpdatedPTOCount(0)
|
||||
if !oldAlarm.IsZero() {
|
||||
if h.tracer.UpdatedPTOCount != nil {
|
||||
h.tracer.UpdatedPTOCount(0)
|
||||
}
|
||||
if !oldAlarm.IsZero() && h.tracer.LossTimerCanceled != nil {
|
||||
h.tracer.LossTimerCanceled()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
JustBeforeEach(func() {
|
||||
lostPackets = nil
|
||||
rttStats := utils.NewRTTStats()
|
||||
handler = newSentPacketHandler(42, protocol.InitialPacketSizeIPv4, rttStats, false, perspective, nil, utils.DefaultLogger)
|
||||
handler = newSentPacketHandler(42, protocol.InitialPacketSizeIPv4, rttStats, false, false, perspective, nil, utils.DefaultLogger)
|
||||
streamFrame = wire.StreamFrame{
|
||||
StreamID: 5,
|
||||
Data: []byte{0x13, 0x37},
|
||||
|
@ -106,7 +106,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
}
|
||||
|
||||
sentPacket := func(p *packet) {
|
||||
handler.SentPacket(p.SendTime, p.PacketNumber, p.LargestAcked, p.StreamFrames, p.Frames, p.EncryptionLevel, p.Length, p.IsPathMTUProbePacket)
|
||||
handler.SentPacket(p.SendTime, p.PacketNumber, p.LargestAcked, p.StreamFrames, p.Frames, p.EncryptionLevel, protocol.ECNNon, p.Length, p.IsPathMTUProbePacket)
|
||||
}
|
||||
|
||||
expectInPacketHistory := func(expected []protocol.PacketNumber, encLevel protocol.EncryptionLevel) {
|
||||
|
@ -563,7 +563,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
// lose packet 1
|
||||
gomock.InOrder(
|
||||
cong.EXPECT().MaybeExitSlowStart(),
|
||||
cong.EXPECT().OnPacketLost(protocol.PacketNumber(1), protocol.ByteCount(1), protocol.ByteCount(2)),
|
||||
cong.EXPECT().OnCongestionEvent(protocol.PacketNumber(1), protocol.ByteCount(1), protocol.ByteCount(2)),
|
||||
cong.EXPECT().OnPacketAcked(protocol.PacketNumber(2), protocol.ByteCount(1), protocol.ByteCount(2), gomock.Any()),
|
||||
)
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 2}}}
|
||||
|
@ -575,7 +575,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("doesn't call OnPacketLost when a Path MTU probe packet is lost", func() {
|
||||
It("doesn't call OnCongestionEvent when a Path MTU probe packet is lost", func() {
|
||||
cong.EXPECT().OnPacketSent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2)
|
||||
var mtuPacketDeclaredLost bool
|
||||
sentPacket(ackElicitingPacket(&packet{
|
||||
|
@ -590,7 +590,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
},
|
||||
}))
|
||||
sentPacket(ackElicitingPacket(&packet{PacketNumber: 2}))
|
||||
// lose packet 1, but don't EXPECT any calls to OnPacketLost()
|
||||
// lose packet 1, but don't EXPECT any calls to OnCongestionEvent()
|
||||
gomock.InOrder(
|
||||
cong.EXPECT().MaybeExitSlowStart(),
|
||||
cong.EXPECT().OnPacketAcked(protocol.PacketNumber(2), protocol.ByteCount(1), protocol.ByteCount(2), gomock.Any()),
|
||||
|
@ -602,7 +602,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
Expect(handler.bytesInFlight).To(BeZero())
|
||||
})
|
||||
|
||||
It("calls OnPacketAcked and OnPacketLost with the right bytes_in_flight value", func() {
|
||||
It("calls OnPacketAcked and OnCongestionEvent with the right bytes_in_flight value", func() {
|
||||
cong.EXPECT().OnPacketSent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(4)
|
||||
sentPacket(ackElicitingPacket(&packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)}))
|
||||
sentPacket(ackElicitingPacket(&packet{PacketNumber: 2, SendTime: time.Now().Add(-30 * time.Minute)}))
|
||||
|
@ -611,7 +611,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
// receive the first ACK
|
||||
gomock.InOrder(
|
||||
cong.EXPECT().MaybeExitSlowStart(),
|
||||
cong.EXPECT().OnPacketLost(protocol.PacketNumber(1), protocol.ByteCount(1), protocol.ByteCount(4)),
|
||||
cong.EXPECT().OnCongestionEvent(protocol.PacketNumber(1), protocol.ByteCount(1), protocol.ByteCount(4)),
|
||||
cong.EXPECT().OnPacketAcked(protocol.PacketNumber(2), protocol.ByteCount(1), protocol.ByteCount(4), gomock.Any()),
|
||||
)
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 2}}}
|
||||
|
@ -620,7 +620,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
// receive the second ACK
|
||||
gomock.InOrder(
|
||||
cong.EXPECT().MaybeExitSlowStart(),
|
||||
cong.EXPECT().OnPacketLost(protocol.PacketNumber(3), protocol.ByteCount(1), protocol.ByteCount(2)),
|
||||
cong.EXPECT().OnCongestionEvent(protocol.PacketNumber(3), protocol.ByteCount(1), protocol.ByteCount(2)),
|
||||
cong.EXPECT().OnPacketAcked(protocol.PacketNumber(4), protocol.ByteCount(1), protocol.ByteCount(2), gomock.Any()),
|
||||
)
|
||||
ack = &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 4, Largest: 4}}}
|
||||
|
@ -984,7 +984,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
Context("amplification limit, for the server, with validated address", func() {
|
||||
JustBeforeEach(func() {
|
||||
rttStats := utils.NewRTTStats()
|
||||
handler = newSentPacketHandler(42, protocol.InitialPacketSizeIPv4, rttStats, true, perspective, nil, utils.DefaultLogger)
|
||||
handler = newSentPacketHandler(42, protocol.InitialPacketSizeIPv4, rttStats, true, false, perspective, nil, utils.DefaultLogger)
|
||||
})
|
||||
|
||||
It("do not limits the window", func() {
|
||||
|
@ -1334,7 +1334,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
Expect(handler.bytesInFlight).ToNot(BeZero())
|
||||
Expect(handler.SendMode(time.Now())).To(Equal(SendAny))
|
||||
// now receive a Retry
|
||||
Expect(handler.ResetForRetry()).To(Succeed())
|
||||
Expect(handler.ResetForRetry(time.Now())).To(Succeed())
|
||||
Expect(lostPackets).To(Equal([]protocol.PacketNumber{42}))
|
||||
Expect(handler.bytesInFlight).To(BeZero())
|
||||
Expect(handler.GetLossDetectionTimeout()).To(BeZero())
|
||||
|
@ -1369,7 +1369,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
})
|
||||
Expect(handler.bytesInFlight).ToNot(BeZero())
|
||||
// now receive a Retry
|
||||
Expect(handler.ResetForRetry()).To(Succeed())
|
||||
Expect(handler.ResetForRetry(time.Now())).To(Succeed())
|
||||
Expect(handler.bytesInFlight).To(BeZero())
|
||||
Expect(lostInitial).To(BeTrue())
|
||||
Expect(lost0RTT).To(BeTrue())
|
||||
|
@ -1379,50 +1379,201 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
})
|
||||
|
||||
It("uses a Retry for an RTT estimate, if it was not retransmitted", func() {
|
||||
now := time.Now()
|
||||
sentPacket(ackElicitingPacket(&packet{
|
||||
PacketNumber: 42,
|
||||
EncryptionLevel: protocol.EncryptionInitial,
|
||||
SendTime: time.Now().Add(-500 * time.Millisecond),
|
||||
SendTime: now,
|
||||
}))
|
||||
sentPacket(ackElicitingPacket(&packet{
|
||||
PacketNumber: 43,
|
||||
EncryptionLevel: protocol.EncryptionInitial,
|
||||
SendTime: time.Now().Add(-10 * time.Millisecond),
|
||||
SendTime: now.Add(500 * time.Millisecond),
|
||||
}))
|
||||
Expect(handler.ResetForRetry()).To(Succeed())
|
||||
Expect(handler.rttStats.SmoothedRTT()).To(BeNumerically("~", 500*time.Millisecond, 100*time.Millisecond))
|
||||
Expect(handler.ResetForRetry(now.Add(time.Second))).To(Succeed())
|
||||
Expect(handler.rttStats.SmoothedRTT()).To(Equal(time.Second))
|
||||
})
|
||||
|
||||
It("uses a Retry for an RTT estimate, but doesn't set the RTT to a value lower than 5ms", func() {
|
||||
now := time.Now()
|
||||
sentPacket(ackElicitingPacket(&packet{
|
||||
PacketNumber: 42,
|
||||
EncryptionLevel: protocol.EncryptionInitial,
|
||||
SendTime: time.Now().Add(-500 * time.Microsecond),
|
||||
SendTime: now,
|
||||
}))
|
||||
sentPacket(ackElicitingPacket(&packet{
|
||||
PacketNumber: 43,
|
||||
EncryptionLevel: protocol.EncryptionInitial,
|
||||
SendTime: time.Now().Add(-10 * time.Microsecond),
|
||||
SendTime: now.Add(2 * time.Millisecond),
|
||||
}))
|
||||
Expect(handler.ResetForRetry()).To(Succeed())
|
||||
Expect(handler.ResetForRetry(now.Add(4 * time.Millisecond))).To(Succeed())
|
||||
Expect(minRTTAfterRetry).To(BeNumerically(">", 4*time.Millisecond))
|
||||
Expect(handler.rttStats.SmoothedRTT()).To(Equal(minRTTAfterRetry))
|
||||
})
|
||||
|
||||
It("doesn't use a Retry for an RTT estimate, if it was not retransmitted", func() {
|
||||
now := time.Now()
|
||||
sentPacket(ackElicitingPacket(&packet{
|
||||
PacketNumber: 42,
|
||||
EncryptionLevel: protocol.EncryptionInitial,
|
||||
SendTime: time.Now().Add(-800 * time.Millisecond),
|
||||
SendTime: now,
|
||||
}))
|
||||
Expect(handler.OnLossDetectionTimeout()).To(Succeed())
|
||||
Expect(handler.SendMode(time.Now())).To(Equal(SendPTOInitial))
|
||||
sentPacket(ackElicitingPacket(&packet{
|
||||
PacketNumber: 43,
|
||||
EncryptionLevel: protocol.EncryptionInitial,
|
||||
SendTime: time.Now().Add(-100 * time.Millisecond),
|
||||
SendTime: now.Add(500 * time.Millisecond),
|
||||
}))
|
||||
Expect(handler.ResetForRetry()).To(Succeed())
|
||||
Expect(handler.ResetForRetry(now.Add(time.Second))).To(Succeed())
|
||||
Expect(handler.rttStats.SmoothedRTT()).To(BeZero())
|
||||
})
|
||||
})
|
||||
|
||||
Context("ECN handling", func() {
|
||||
var ecnHandler *MockECNHandler
|
||||
var cong *mocks.MockSendAlgorithmWithDebugInfos
|
||||
|
||||
JustBeforeEach(func() {
|
||||
cong = mocks.NewMockSendAlgorithmWithDebugInfos(mockCtrl)
|
||||
cong.EXPECT().OnPacketSent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||
cong.EXPECT().OnPacketAcked(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||
cong.EXPECT().MaybeExitSlowStart().AnyTimes()
|
||||
ecnHandler = NewMockECNHandler(mockCtrl)
|
||||
lostPackets = nil
|
||||
rttStats := utils.NewRTTStats()
|
||||
rttStats.UpdateRTT(time.Hour, 0, time.Now())
|
||||
handler = newSentPacketHandler(42, protocol.InitialPacketSizeIPv4, rttStats, false, false, perspective, nil, utils.DefaultLogger)
|
||||
handler.ecnTracker = ecnHandler
|
||||
handler.congestion = cong
|
||||
})
|
||||
|
||||
It("informs about sent packets", func() {
|
||||
// Check that only 1-RTT packets are reported
|
||||
handler.SentPacket(time.Now(), 100, -1, nil, nil, protocol.EncryptionInitial, protocol.ECT1, 1200, false)
|
||||
handler.SentPacket(time.Now(), 101, -1, nil, nil, protocol.EncryptionHandshake, protocol.ECT0, 1200, false)
|
||||
handler.SentPacket(time.Now(), 102, -1, nil, nil, protocol.Encryption0RTT, protocol.ECNCE, 1200, false)
|
||||
|
||||
ecnHandler.EXPECT().SentPacket(protocol.PacketNumber(103), protocol.ECT1)
|
||||
handler.SentPacket(time.Now(), 103, -1, nil, nil, protocol.Encryption1RTT, protocol.ECT1, 1200, false)
|
||||
})
|
||||
|
||||
It("informs about sent packets", func() {
|
||||
// Check that only 1-RTT packets are reported
|
||||
handler.SentPacket(time.Now(), 100, -1, nil, nil, protocol.EncryptionInitial, protocol.ECT1, 1200, false)
|
||||
handler.SentPacket(time.Now(), 101, -1, nil, nil, protocol.EncryptionHandshake, protocol.ECT0, 1200, false)
|
||||
handler.SentPacket(time.Now(), 102, -1, nil, nil, protocol.Encryption0RTT, protocol.ECNCE, 1200, false)
|
||||
|
||||
ecnHandler.EXPECT().SentPacket(protocol.PacketNumber(103), protocol.ECT1)
|
||||
handler.SentPacket(time.Now(), 103, -1, nil, nil, protocol.Encryption1RTT, protocol.ECT1, 1200, false)
|
||||
})
|
||||
|
||||
It("informs about lost packets", func() {
|
||||
for i := 10; i < 20; i++ {
|
||||
ecnHandler.EXPECT().SentPacket(protocol.PacketNumber(i), protocol.ECT1)
|
||||
handler.SentPacket(time.Now(), protocol.PacketNumber(i), -1, []StreamFrame{{Frame: &streamFrame}}, nil, protocol.Encryption1RTT, protocol.ECT1, 1200, false)
|
||||
}
|
||||
cong.EXPECT().OnCongestionEvent(gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
|
||||
ecnHandler.EXPECT().LostPacket(protocol.PacketNumber(10))
|
||||
ecnHandler.EXPECT().LostPacket(protocol.PacketNumber(11))
|
||||
ecnHandler.EXPECT().LostPacket(protocol.PacketNumber(12))
|
||||
ecnHandler.EXPECT().HandleNewlyAcked(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
_, err := handler.ReceivedAck(&wire.AckFrame{AckRanges: []wire.AckRange{{Largest: 16, Smallest: 13}}}, protocol.Encryption1RTT, time.Now())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("processes ACKs", func() {
|
||||
// Check that we only care about 1-RTT packets.
|
||||
handler.SentPacket(time.Now(), 100, -1, []StreamFrame{{Frame: &streamFrame}}, nil, protocol.EncryptionInitial, protocol.ECT1, 1200, false)
|
||||
_, err := handler.ReceivedAck(&wire.AckFrame{AckRanges: []wire.AckRange{{Largest: 100, Smallest: 100}}}, protocol.EncryptionInitial, time.Now())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
for i := 10; i < 20; i++ {
|
||||
ecnHandler.EXPECT().SentPacket(protocol.PacketNumber(i), protocol.ECT1)
|
||||
handler.SentPacket(time.Now(), protocol.PacketNumber(i), -1, []StreamFrame{{Frame: &streamFrame}}, nil, protocol.Encryption1RTT, protocol.ECT1, 1200, false)
|
||||
}
|
||||
ecnHandler.EXPECT().HandleNewlyAcked(gomock.Any(), int64(1), int64(2), int64(3)).DoAndReturn(func(packets []*packet, _, _, _ int64) bool {
|
||||
Expect(packets).To(HaveLen(5))
|
||||
Expect(packets[0].PacketNumber).To(Equal(protocol.PacketNumber(10)))
|
||||
Expect(packets[1].PacketNumber).To(Equal(protocol.PacketNumber(11)))
|
||||
Expect(packets[2].PacketNumber).To(Equal(protocol.PacketNumber(12)))
|
||||
Expect(packets[3].PacketNumber).To(Equal(protocol.PacketNumber(14)))
|
||||
Expect(packets[4].PacketNumber).To(Equal(protocol.PacketNumber(15)))
|
||||
return false
|
||||
})
|
||||
_, err = handler.ReceivedAck(&wire.AckFrame{
|
||||
AckRanges: []wire.AckRange{
|
||||
{Largest: 15, Smallest: 14},
|
||||
{Largest: 12, Smallest: 10},
|
||||
},
|
||||
ECT0: 1,
|
||||
ECT1: 2,
|
||||
ECNCE: 3,
|
||||
}, protocol.Encryption1RTT, time.Now())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("ignores reordered ACKs", func() {
|
||||
for i := 10; i < 20; i++ {
|
||||
ecnHandler.EXPECT().SentPacket(protocol.PacketNumber(i), protocol.ECT1)
|
||||
handler.SentPacket(time.Now(), protocol.PacketNumber(i), -1, []StreamFrame{{Frame: &streamFrame}}, nil, protocol.Encryption1RTT, protocol.ECT1, 1200, false)
|
||||
}
|
||||
ecnHandler.EXPECT().HandleNewlyAcked(gomock.Any(), int64(1), int64(2), int64(3)).DoAndReturn(func(packets []*packet, _, _, _ int64) bool {
|
||||
Expect(packets).To(HaveLen(2))
|
||||
Expect(packets[0].PacketNumber).To(Equal(protocol.PacketNumber(11)))
|
||||
Expect(packets[1].PacketNumber).To(Equal(protocol.PacketNumber(12)))
|
||||
return false
|
||||
})
|
||||
_, err := handler.ReceivedAck(&wire.AckFrame{
|
||||
AckRanges: []wire.AckRange{{Largest: 12, Smallest: 11}},
|
||||
ECT0: 1,
|
||||
ECT1: 2,
|
||||
ECNCE: 3,
|
||||
}, protocol.Encryption1RTT, time.Now())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
// acknowledge packet 10 now, but don't increase the largest acked
|
||||
_, err = handler.ReceivedAck(&wire.AckFrame{
|
||||
AckRanges: []wire.AckRange{{Largest: 12, Smallest: 10}},
|
||||
ECT0: 1,
|
||||
ECNCE: 3,
|
||||
}, protocol.Encryption1RTT, time.Now())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("ignores ACKs that don't increase the largest acked", func() {
|
||||
for i := 10; i < 20; i++ {
|
||||
ecnHandler.EXPECT().SentPacket(protocol.PacketNumber(i), protocol.ECT1)
|
||||
handler.SentPacket(time.Now(), protocol.PacketNumber(i), -1, []StreamFrame{{Frame: &streamFrame}}, nil, protocol.Encryption1RTT, protocol.ECT1, 1200, false)
|
||||
}
|
||||
ecnHandler.EXPECT().HandleNewlyAcked(gomock.Any(), int64(1), int64(2), int64(3)).DoAndReturn(func(packets []*packet, _, _, _ int64) bool {
|
||||
Expect(packets).To(HaveLen(1))
|
||||
Expect(packets[0].PacketNumber).To(Equal(protocol.PacketNumber(11)))
|
||||
return false
|
||||
})
|
||||
_, err := handler.ReceivedAck(&wire.AckFrame{
|
||||
AckRanges: []wire.AckRange{{Largest: 11, Smallest: 11}},
|
||||
ECT0: 1,
|
||||
ECT1: 2,
|
||||
ECNCE: 3,
|
||||
}, protocol.Encryption1RTT, time.Now())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = handler.ReceivedAck(&wire.AckFrame{
|
||||
AckRanges: []wire.AckRange{{Largest: 11, Smallest: 10}},
|
||||
ECT0: 1,
|
||||
ECNCE: 3,
|
||||
}, protocol.Encryption1RTT, time.Now())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("informs the congestion controller about CE events", func() {
|
||||
for i := 10; i < 20; i++ {
|
||||
ecnHandler.EXPECT().SentPacket(protocol.PacketNumber(i), protocol.ECT0)
|
||||
handler.SentPacket(time.Now(), protocol.PacketNumber(i), -1, []StreamFrame{{Frame: &streamFrame}}, nil, protocol.Encryption1RTT, protocol.ECT0, 1200, false)
|
||||
}
|
||||
ecnHandler.EXPECT().HandleNewlyAcked(gomock.Any(), int64(0), int64(0), int64(0)).Return(true)
|
||||
cong.EXPECT().OnCongestionEvent(protocol.PacketNumber(15), gomock.Any(), gomock.Any())
|
||||
_, err := handler.ReceivedAck(&wire.AckFrame{AckRanges: []wire.AckRange{{Largest: 15, Smallest: 10}}}, protocol.Encryption1RTT, time.Now())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -56,7 +56,7 @@ type cubicSender struct {
|
|||
maxDatagramSize protocol.ByteCount
|
||||
|
||||
lastState logging.CongestionState
|
||||
tracer logging.ConnectionTracer
|
||||
tracer *logging.ConnectionTracer
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -70,7 +70,7 @@ func NewCubicSender(
|
|||
rttStats *utils.RTTStats,
|
||||
initialMaxDatagramSize protocol.ByteCount,
|
||||
reno bool,
|
||||
tracer logging.ConnectionTracer,
|
||||
tracer *logging.ConnectionTracer,
|
||||
) *cubicSender {
|
||||
return newCubicSender(
|
||||
clock,
|
||||
|
@ -90,7 +90,7 @@ func newCubicSender(
|
|||
initialMaxDatagramSize,
|
||||
initialCongestionWindow,
|
||||
initialMaxCongestionWindow protocol.ByteCount,
|
||||
tracer logging.ConnectionTracer,
|
||||
tracer *logging.ConnectionTracer,
|
||||
) *cubicSender {
|
||||
c := &cubicSender{
|
||||
rttStats: rttStats,
|
||||
|
@ -108,7 +108,7 @@ func newCubicSender(
|
|||
maxDatagramSize: initialMaxDatagramSize,
|
||||
}
|
||||
c.pacer = newPacer(c.BandwidthEstimate)
|
||||
if c.tracer != nil {
|
||||
if c.tracer != nil && c.tracer.UpdatedCongestionState != nil {
|
||||
c.lastState = logging.CongestionStateSlowStart
|
||||
c.tracer.UpdatedCongestionState(logging.CongestionStateSlowStart)
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ func (c *cubicSender) OnPacketAcked(
|
|||
}
|
||||
}
|
||||
|
||||
func (c *cubicSender) OnPacketLost(packetNumber protocol.PacketNumber, lostBytes, priorInFlight protocol.ByteCount) {
|
||||
func (c *cubicSender) OnCongestionEvent(packetNumber protocol.PacketNumber, lostBytes, priorInFlight protocol.ByteCount) {
|
||||
// TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets
|
||||
// already sent should be treated as a single loss event, since it's expected.
|
||||
if packetNumber <= c.largestSentAtLastCutback {
|
||||
|
@ -296,7 +296,7 @@ func (c *cubicSender) OnConnectionMigration() {
|
|||
}
|
||||
|
||||
func (c *cubicSender) maybeTraceStateChange(new logging.CongestionState) {
|
||||
if c.tracer == nil || new == c.lastState {
|
||||
if c.tracer == nil || c.tracer.UpdatedCongestionState == nil || new == c.lastState {
|
||||
return
|
||||
}
|
||||
c.tracer.UpdatedCongestionState(new)
|
||||
|
|
|
@ -80,14 +80,14 @@ var _ = Describe("Cubic Sender", func() {
|
|||
LoseNPacketsLen := func(n int, packetLength protocol.ByteCount) {
|
||||
for i := 0; i < n; i++ {
|
||||
ackedPacketNumber++
|
||||
sender.OnPacketLost(ackedPacketNumber, packetLength, bytesInFlight)
|
||||
sender.OnCongestionEvent(ackedPacketNumber, packetLength, bytesInFlight)
|
||||
}
|
||||
bytesInFlight -= protocol.ByteCount(n) * packetLength
|
||||
}
|
||||
|
||||
// Does not increment acked_packet_number_.
|
||||
LosePacket := func(number protocol.PacketNumber) {
|
||||
sender.OnPacketLost(number, maxDatagramSize, bytesInFlight)
|
||||
sender.OnCongestionEvent(number, maxDatagramSize, bytesInFlight)
|
||||
bytesInFlight -= maxDatagramSize
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ type SendAlgorithm interface {
|
|||
CanSend(bytesInFlight protocol.ByteCount) bool
|
||||
MaybeExitSlowStart()
|
||||
OnPacketAcked(number protocol.PacketNumber, ackedBytes protocol.ByteCount, priorInFlight protocol.ByteCount, eventTime time.Time)
|
||||
OnPacketLost(number protocol.PacketNumber, lostBytes protocol.ByteCount, priorInFlight protocol.ByteCount)
|
||||
OnCongestionEvent(number protocol.PacketNumber, lostBytes protocol.ByteCount, priorInFlight protocol.ByteCount)
|
||||
OnRetransmissionTimeout(packetsRetransmitted bool)
|
||||
SetMaxDatagramSize(protocol.ByteCount)
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ type cryptoSetup struct {
|
|||
|
||||
rttStats *utils.RTTStats
|
||||
|
||||
tracer logging.ConnectionTracer
|
||||
tracer *logging.ConnectionTracer
|
||||
logger utils.Logger
|
||||
|
||||
perspective protocol.Perspective
|
||||
|
@ -78,7 +78,7 @@ func NewCryptoSetupClient(
|
|||
tlsConf *tls.Config,
|
||||
enable0RTT bool,
|
||||
rttStats *utils.RTTStats,
|
||||
tracer logging.ConnectionTracer,
|
||||
tracer *logging.ConnectionTracer,
|
||||
logger utils.Logger,
|
||||
version protocol.VersionNumber,
|
||||
) CryptoSetup {
|
||||
|
@ -112,7 +112,7 @@ func NewCryptoSetupServer(
|
|||
tlsConf *tls.Config,
|
||||
allow0RTT bool,
|
||||
rttStats *utils.RTTStats,
|
||||
tracer logging.ConnectionTracer,
|
||||
tracer *logging.ConnectionTracer,
|
||||
logger utils.Logger,
|
||||
version protocol.VersionNumber,
|
||||
) CryptoSetup {
|
||||
|
@ -128,7 +128,7 @@ func NewCryptoSetupServer(
|
|||
cs.allow0RTT = allow0RTT
|
||||
|
||||
quicConf := &qtls.QUICConfig{TLSConfig: tlsConf}
|
||||
qtls.SetupConfigForServer(quicConf, cs.allow0RTT, cs.getDataForSessionTicket, cs.accept0RTT)
|
||||
qtls.SetupConfigForServer(quicConf, cs.allow0RTT, cs.getDataForSessionTicket, cs.handleSessionTicket)
|
||||
addConnToClientHelloInfo(quicConf.TLSConfig, localAddr, remoteAddr)
|
||||
|
||||
cs.tlsConf = quicConf.TLSConfig
|
||||
|
@ -166,13 +166,13 @@ func newCryptoSetup(
|
|||
connID protocol.ConnectionID,
|
||||
tp *wire.TransportParameters,
|
||||
rttStats *utils.RTTStats,
|
||||
tracer logging.ConnectionTracer,
|
||||
tracer *logging.ConnectionTracer,
|
||||
logger utils.Logger,
|
||||
perspective protocol.Perspective,
|
||||
version protocol.VersionNumber,
|
||||
) *cryptoSetup {
|
||||
initialSealer, initialOpener := NewInitialAEAD(connID, perspective, version)
|
||||
if tracer != nil {
|
||||
if tracer != nil && tracer.UpdatedKeyFromTLS != nil {
|
||||
tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveClient)
|
||||
tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveServer)
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ func (h *cryptoSetup) ChangeConnectionID(id protocol.ConnectionID) {
|
|||
initialSealer, initialOpener := NewInitialAEAD(id, h.perspective, h.version)
|
||||
h.initialSealer = initialSealer
|
||||
h.initialOpener = initialOpener
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil {
|
||||
h.tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveClient)
|
||||
h.tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveServer)
|
||||
}
|
||||
|
@ -349,10 +349,13 @@ func (h *cryptoSetup) handleDataFromSessionStateImpl(data []byte) (*wire.Transpo
|
|||
}
|
||||
|
||||
func (h *cryptoSetup) getDataForSessionTicket() []byte {
|
||||
return (&sessionTicket{
|
||||
Parameters: h.ourParams,
|
||||
RTT: h.rttStats.SmoothedRTT(),
|
||||
}).Marshal()
|
||||
ticket := &sessionTicket{
|
||||
RTT: h.rttStats.SmoothedRTT(),
|
||||
}
|
||||
if h.allow0RTT {
|
||||
ticket.Parameters = h.ourParams
|
||||
}
|
||||
return ticket.Marshal()
|
||||
}
|
||||
|
||||
// GetSessionTicket generates a new session ticket.
|
||||
|
@ -381,12 +384,16 @@ func (h *cryptoSetup) GetSessionTicket() ([]byte, error) {
|
|||
return ticket, nil
|
||||
}
|
||||
|
||||
// accept0RTT is called for the server when receiving the client's session ticket.
|
||||
// It decides whether to accept 0-RTT.
|
||||
func (h *cryptoSetup) accept0RTT(sessionTicketData []byte) bool {
|
||||
// handleSessionTicket is called for the server when receiving the client's session ticket.
|
||||
// It reads parameters from the session ticket and decides whether to accept 0-RTT when the session ticket is used for 0-RTT.
|
||||
func (h *cryptoSetup) handleSessionTicket(sessionTicketData []byte, using0RTT bool) bool {
|
||||
var t sessionTicket
|
||||
if err := t.Unmarshal(sessionTicketData); err != nil {
|
||||
h.logger.Debugf("Unmarshalling transport parameters from session ticket failed: %s", err.Error())
|
||||
if err := t.Unmarshal(sessionTicketData, using0RTT); err != nil {
|
||||
h.logger.Debugf("Unmarshalling session ticket failed: %s", err.Error())
|
||||
return false
|
||||
}
|
||||
h.rttStats.SetInitialRTT(t.RTT)
|
||||
if !using0RTT {
|
||||
return false
|
||||
}
|
||||
valid := h.ourParams.ValidFor0RTT(t.Parameters)
|
||||
|
@ -399,7 +406,6 @@ func (h *cryptoSetup) accept0RTT(sessionTicketData []byte) bool {
|
|||
return false
|
||||
}
|
||||
h.logger.Debugf("Accepting 0-RTT. Restoring RTT from session ticket: %s", t.RTT)
|
||||
h.rttStats.SetInitialRTT(t.RTT)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -453,7 +459,7 @@ func (h *cryptoSetup) SetReadKey(el qtls.QUICEncryptionLevel, suiteID uint16, tr
|
|||
}
|
||||
h.mutex.Unlock()
|
||||
h.events = append(h.events, Event{Kind: EventReceivedReadKeys})
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil {
|
||||
h.tracer.UpdatedKeyFromTLS(qtls.FromTLSEncryptionLevel(el), h.perspective.Opposite())
|
||||
}
|
||||
}
|
||||
|
@ -475,7 +481,7 @@ func (h *cryptoSetup) SetWriteKey(el qtls.QUICEncryptionLevel, suiteID uint16, t
|
|||
if h.logger.Debug() {
|
||||
h.logger.Debugf("Installed 0-RTT Write keys (using %s)", tls.CipherSuiteName(suite.ID))
|
||||
}
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil {
|
||||
h.tracer.UpdatedKeyFromTLS(protocol.Encryption0RTT, h.perspective)
|
||||
}
|
||||
// don't set used0RTT here. 0-RTT might still get rejected.
|
||||
|
@ -499,7 +505,7 @@ func (h *cryptoSetup) SetWriteKey(el qtls.QUICEncryptionLevel, suiteID uint16, t
|
|||
h.used0RTT.Store(true)
|
||||
h.zeroRTTSealer = nil
|
||||
h.logger.Debugf("Dropping 0-RTT keys.")
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.DroppedEncryptionLevel != nil {
|
||||
h.tracer.DroppedEncryptionLevel(protocol.Encryption0RTT)
|
||||
}
|
||||
}
|
||||
|
@ -507,7 +513,7 @@ func (h *cryptoSetup) SetWriteKey(el qtls.QUICEncryptionLevel, suiteID uint16, t
|
|||
panic("unexpected write encryption level")
|
||||
}
|
||||
h.mutex.Unlock()
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil {
|
||||
h.tracer.UpdatedKeyFromTLS(qtls.FromTLSEncryptionLevel(el), h.perspective)
|
||||
}
|
||||
}
|
||||
|
@ -647,7 +653,7 @@ func (h *cryptoSetup) Get1RTTOpener() (ShortHeaderOpener, error) {
|
|||
if h.zeroRTTOpener != nil && time.Since(h.handshakeCompleteTime) > 3*h.rttStats.PTO(true) {
|
||||
h.zeroRTTOpener = nil
|
||||
h.logger.Debugf("Dropping 0-RTT keys.")
|
||||
if h.tracer != nil {
|
||||
if h.tracer != nil && h.tracer.DroppedEncryptionLevel != nil {
|
||||
h.tracer.DroppedEncryptionLevel(protocol.Encryption0RTT)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
"crypto/x509/pkix"
|
||||
"math/big"
|
||||
"net"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
tls "github.com/refraction-networking/utls"
|
||||
|
@ -418,11 +420,13 @@ var _ = Describe("Crypto Setup TLS", func() {
|
|||
close(receivedSessionTicket)
|
||||
})
|
||||
clientConf.ClientSessionCache = csc
|
||||
const serverRTT = 25 * time.Millisecond // RTT as measured by the server. Should be restored.
|
||||
const clientRTT = 30 * time.Millisecond // RTT as measured by the client. Should be restored.
|
||||
serverOrigRTTStats := newRTTStatsWithRTT(serverRTT)
|
||||
clientOrigRTTStats := newRTTStatsWithRTT(clientRTT)
|
||||
client, _, clientErr, server, _, serverErr := handshakeWithTLSConf(
|
||||
clientConf, serverConf,
|
||||
clientOrigRTTStats, &utils.RTTStats{},
|
||||
clientOrigRTTStats, serverOrigRTTStats,
|
||||
&wire.TransportParameters{ActiveConnectionIDLimit: 2}, &wire.TransportParameters{ActiveConnectionIDLimit: 2},
|
||||
false,
|
||||
)
|
||||
|
@ -435,9 +439,10 @@ var _ = Describe("Crypto Setup TLS", func() {
|
|||
csc.EXPECT().Get(gomock.Any()).Return(state, true)
|
||||
csc.EXPECT().Put(gomock.Any(), gomock.Any()).MaxTimes(1)
|
||||
clientRTTStats := &utils.RTTStats{}
|
||||
serverRTTStats := &utils.RTTStats{}
|
||||
client, _, clientErr, server, _, serverErr = handshakeWithTLSConf(
|
||||
clientConf, serverConf,
|
||||
clientRTTStats, &utils.RTTStats{},
|
||||
clientRTTStats, serverRTTStats,
|
||||
&wire.TransportParameters{ActiveConnectionIDLimit: 2}, &wire.TransportParameters{ActiveConnectionIDLimit: 2},
|
||||
false,
|
||||
)
|
||||
|
@ -447,6 +452,9 @@ var _ = Describe("Crypto Setup TLS", func() {
|
|||
Expect(server.ConnectionState().DidResume).To(BeTrue())
|
||||
Expect(client.ConnectionState().DidResume).To(BeTrue())
|
||||
Expect(clientRTTStats.SmoothedRTT()).To(Equal(clientRTT))
|
||||
if !strings.Contains(runtime.Version(), "go1.20") {
|
||||
Expect(serverRTTStats.SmoothedRTT()).To(Equal(serverRTT))
|
||||
}
|
||||
})
|
||||
|
||||
It("doesn't use session resumption if the server disabled it", func() {
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/refraction-networking/uquic/quicvarint"
|
||||
)
|
||||
|
||||
const sessionTicketRevision = 3
|
||||
const sessionTicketRevision = 4
|
||||
|
||||
type sessionTicket struct {
|
||||
Parameters *wire.TransportParameters
|
||||
|
@ -21,10 +21,13 @@ func (t *sessionTicket) Marshal() []byte {
|
|||
b := make([]byte, 0, 256)
|
||||
b = quicvarint.Append(b, sessionTicketRevision)
|
||||
b = quicvarint.Append(b, uint64(t.RTT.Microseconds()))
|
||||
if t.Parameters == nil {
|
||||
return b
|
||||
}
|
||||
return t.Parameters.MarshalForSessionTicket(b)
|
||||
}
|
||||
|
||||
func (t *sessionTicket) Unmarshal(b []byte) error {
|
||||
func (t *sessionTicket) Unmarshal(b []byte, using0RTT bool) error {
|
||||
r := bytes.NewReader(b)
|
||||
rev, err := quicvarint.Read(r)
|
||||
if err != nil {
|
||||
|
@ -37,11 +40,15 @@ func (t *sessionTicket) Unmarshal(b []byte) error {
|
|||
if err != nil {
|
||||
return errors.New("failed to read RTT")
|
||||
}
|
||||
var tp wire.TransportParameters
|
||||
if err := tp.UnmarshalFromSessionTicket(r); err != nil {
|
||||
return fmt.Errorf("unmarshaling transport parameters from session ticket failed: %s", err.Error())
|
||||
if using0RTT {
|
||||
var tp wire.TransportParameters
|
||||
if err := tp.UnmarshalFromSessionTicket(r); err != nil {
|
||||
return fmt.Errorf("unmarshaling transport parameters from session ticket failed: %s", err.Error())
|
||||
}
|
||||
t.Parameters = &tp
|
||||
} else if r.Len() > 0 {
|
||||
return fmt.Errorf("the session ticket has more bytes than expected")
|
||||
}
|
||||
t.Parameters = &tp
|
||||
t.RTT = time.Duration(rtt) * time.Microsecond
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
)
|
||||
|
||||
var _ = Describe("Session Ticket", func() {
|
||||
It("marshals and unmarshals a session ticket", func() {
|
||||
It("marshals and unmarshals a 0-RTT session ticket", func() {
|
||||
ticket := &sessionTicket{
|
||||
Parameters: &wire.TransportParameters{
|
||||
InitialMaxStreamDataBidiLocal: 1,
|
||||
|
@ -22,33 +22,65 @@ var _ = Describe("Session Ticket", func() {
|
|||
RTT: 1337 * time.Microsecond,
|
||||
}
|
||||
var t sessionTicket
|
||||
Expect(t.Unmarshal(ticket.Marshal())).To(Succeed())
|
||||
Expect(t.Unmarshal(ticket.Marshal(), true)).To(Succeed())
|
||||
Expect(t.Parameters.InitialMaxStreamDataBidiLocal).To(BeEquivalentTo(1))
|
||||
Expect(t.Parameters.InitialMaxStreamDataBidiRemote).To(BeEquivalentTo(2))
|
||||
Expect(t.Parameters.ActiveConnectionIDLimit).To(BeEquivalentTo(10))
|
||||
Expect(t.Parameters.MaxDatagramFrameSize).To(BeEquivalentTo(20))
|
||||
Expect(t.RTT).To(Equal(1337 * time.Microsecond))
|
||||
// fails to unmarshal the ticket as a non-0-RTT ticket
|
||||
Expect(t.Unmarshal(ticket.Marshal(), false)).To(MatchError("the session ticket has more bytes than expected"))
|
||||
})
|
||||
|
||||
It("marshals and unmarshals a non-0-RTT session ticket", func() {
|
||||
ticket := &sessionTicket{
|
||||
RTT: 1337 * time.Microsecond,
|
||||
}
|
||||
var t sessionTicket
|
||||
Expect(t.Unmarshal(ticket.Marshal(), false)).To(Succeed())
|
||||
Expect(t.Parameters).To(BeNil())
|
||||
Expect(t.RTT).To(Equal(1337 * time.Microsecond))
|
||||
// fails to unmarshal the ticket as a 0-RTT ticket
|
||||
Expect(t.Unmarshal(ticket.Marshal(), true)).To(MatchError(ContainSubstring("unmarshaling transport parameters from session ticket failed")))
|
||||
})
|
||||
|
||||
It("refuses to unmarshal if the ticket is too short for the revision", func() {
|
||||
Expect((&sessionTicket{}).Unmarshal([]byte{})).To(MatchError("failed to read session ticket revision"))
|
||||
Expect((&sessionTicket{}).Unmarshal([]byte{}, true)).To(MatchError("failed to read session ticket revision"))
|
||||
Expect((&sessionTicket{}).Unmarshal([]byte{}, false)).To(MatchError("failed to read session ticket revision"))
|
||||
})
|
||||
|
||||
It("refuses to unmarshal if the revision doesn't match", func() {
|
||||
b := quicvarint.Append(nil, 1337)
|
||||
Expect((&sessionTicket{}).Unmarshal(b)).To(MatchError("unknown session ticket revision: 1337"))
|
||||
Expect((&sessionTicket{}).Unmarshal(b, true)).To(MatchError("unknown session ticket revision: 1337"))
|
||||
Expect((&sessionTicket{}).Unmarshal(b, false)).To(MatchError("unknown session ticket revision: 1337"))
|
||||
})
|
||||
|
||||
It("refuses to unmarshal if the RTT cannot be read", func() {
|
||||
b := quicvarint.Append(nil, sessionTicketRevision)
|
||||
Expect((&sessionTicket{}).Unmarshal(b)).To(MatchError("failed to read RTT"))
|
||||
Expect((&sessionTicket{}).Unmarshal(b, true)).To(MatchError("failed to read RTT"))
|
||||
Expect((&sessionTicket{}).Unmarshal(b, false)).To(MatchError("failed to read RTT"))
|
||||
})
|
||||
|
||||
It("refuses to unmarshal if unmarshaling the transport parameters fails", func() {
|
||||
It("refuses to unmarshal a 0-RTT session ticket if unmarshaling the transport parameters fails", func() {
|
||||
b := quicvarint.Append(nil, sessionTicketRevision)
|
||||
b = append(b, []byte("foobar")...)
|
||||
err := (&sessionTicket{}).Unmarshal(b)
|
||||
err := (&sessionTicket{}).Unmarshal(b, true)
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("unmarshaling transport parameters from session ticket failed"))
|
||||
})
|
||||
|
||||
It("refuses to unmarshal if the non-0-RTT session ticket has more bytes than expected", func() {
|
||||
ticket := &sessionTicket{
|
||||
Parameters: &wire.TransportParameters{
|
||||
InitialMaxStreamDataBidiLocal: 1,
|
||||
InitialMaxStreamDataBidiRemote: 2,
|
||||
ActiveConnectionIDLimit: 10,
|
||||
MaxDatagramFrameSize: 20,
|
||||
},
|
||||
RTT: 1234 * time.Microsecond,
|
||||
}
|
||||
err := (&sessionTicket{}).Unmarshal(ticket.Marshal(), false)
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("the session ticket has more bytes than expected"))
|
||||
})
|
||||
})
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bytes"
|
||||
"encoding/asn1"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
|
@ -45,15 +44,9 @@ type TokenGenerator struct {
|
|||
tokenProtector tokenProtector
|
||||
}
|
||||
|
||||
// NewTokenGenerator initializes a new TookenGenerator
|
||||
func NewTokenGenerator(rand io.Reader) (*TokenGenerator, error) {
|
||||
tokenProtector, err := newTokenProtector(rand)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &TokenGenerator{
|
||||
tokenProtector: tokenProtector,
|
||||
}, nil
|
||||
// NewTokenGenerator initializes a new TokenGenerator
|
||||
func NewTokenGenerator(key TokenProtectorKey) *TokenGenerator {
|
||||
return &TokenGenerator{tokenProtector: newTokenProtector(key)}
|
||||
}
|
||||
|
||||
// NewRetryToken generates a new token for a Retry for a given source address
|
||||
|
|
|
@ -16,9 +16,9 @@ var _ = Describe("Token Generator", func() {
|
|||
var tokenGen *TokenGenerator
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
tokenGen, err = NewTokenGenerator(rand.Reader)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
var key TokenProtectorKey
|
||||
rand.Read(key[:])
|
||||
tokenGen = NewTokenGenerator(key)
|
||||
})
|
||||
|
||||
It("generates a token", func() {
|
||||
|
|
|
@ -3,6 +3,7 @@ package handshake
|
|||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -10,6 +11,9 @@ import (
|
|||
"golang.org/x/crypto/hkdf"
|
||||
)
|
||||
|
||||
// TokenProtectorKey is the key used to encrypt both Retry and session resumption tokens.
|
||||
type TokenProtectorKey [32]byte
|
||||
|
||||
// TokenProtector is used to create and verify a token
|
||||
type tokenProtector interface {
|
||||
// NewToken creates a new token
|
||||
|
@ -18,40 +22,29 @@ type tokenProtector interface {
|
|||
DecodeToken([]byte) ([]byte, error)
|
||||
}
|
||||
|
||||
const (
|
||||
tokenSecretSize = 32
|
||||
tokenNonceSize = 32
|
||||
)
|
||||
const tokenNonceSize = 32
|
||||
|
||||
// tokenProtector is used to create and verify a token
|
||||
type tokenProtectorImpl struct {
|
||||
rand io.Reader
|
||||
secret []byte
|
||||
key TokenProtectorKey
|
||||
}
|
||||
|
||||
// newTokenProtector creates a source for source address tokens
|
||||
func newTokenProtector(rand io.Reader) (tokenProtector, error) {
|
||||
secret := make([]byte, tokenSecretSize)
|
||||
if _, err := rand.Read(secret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &tokenProtectorImpl{
|
||||
rand: rand,
|
||||
secret: secret,
|
||||
}, nil
|
||||
func newTokenProtector(key TokenProtectorKey) tokenProtector {
|
||||
return &tokenProtectorImpl{key: key}
|
||||
}
|
||||
|
||||
// NewToken encodes data into a new token.
|
||||
func (s *tokenProtectorImpl) NewToken(data []byte) ([]byte, error) {
|
||||
nonce := make([]byte, tokenNonceSize)
|
||||
if _, err := s.rand.Read(nonce); err != nil {
|
||||
var nonce [tokenNonceSize]byte
|
||||
if _, err := rand.Read(nonce[:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aead, aeadNonce, err := s.createAEAD(nonce)
|
||||
aead, aeadNonce, err := s.createAEAD(nonce[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append(nonce, aead.Seal(nil, aeadNonce, data, nil)...), nil
|
||||
return append(nonce[:], aead.Seal(nil, aeadNonce, data, nil)...), nil
|
||||
}
|
||||
|
||||
// DecodeToken decodes a token.
|
||||
|
@ -68,7 +61,7 @@ func (s *tokenProtectorImpl) DecodeToken(p []byte) ([]byte, error) {
|
|||
}
|
||||
|
||||
func (s *tokenProtectorImpl) createAEAD(nonce []byte) (cipher.AEAD, []byte, error) {
|
||||
h := hkdf.New(sha256.New, s.secret, nonce, []byte("quic-go token source"))
|
||||
h := hkdf.New(sha256.New, s.key[:], nonce, []byte("quic-go token source"))
|
||||
key := make([]byte, 32) // use a 32 byte key, in order to select AES-256
|
||||
if _, err := io.ReadFull(h, key); err != nil {
|
||||
return nil, nil, err
|
||||
|
|
|
@ -7,41 +7,17 @@ import (
|
|||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
type zeroReader struct{}
|
||||
|
||||
func (r *zeroReader) Read(b []byte) (int, error) {
|
||||
for i := range b {
|
||||
b[i] = 0
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
var _ = Describe("Token Protector", func() {
|
||||
var tp tokenProtector
|
||||
|
||||
BeforeEach(func() {
|
||||
var key TokenProtectorKey
|
||||
rand.Read(key[:])
|
||||
var err error
|
||||
tp, err = newTokenProtector(rand.Reader)
|
||||
tp = newTokenProtector(key)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("uses the random source", func() {
|
||||
tp1, err := newTokenProtector(&zeroReader{})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
tp2, err := newTokenProtector(&zeroReader{})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
t1, err := tp1.NewToken([]byte("foo"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
t2, err := tp2.NewToken([]byte("foo"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(t1).To(Equal(t2))
|
||||
tp3, err := newTokenProtector(rand.Reader)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
t3, err := tp3.NewToken([]byte("foo"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(t3).ToNot(Equal(t1))
|
||||
})
|
||||
|
||||
It("encodes and decodes tokens", func() {
|
||||
token, err := tp.NewToken([]byte("foobar"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -51,11 +27,34 @@ var _ = Describe("Token Protector", func() {
|
|||
Expect(decoded).To(Equal([]byte("foobar")))
|
||||
})
|
||||
|
||||
It("fails deconding invalid tokens", func() {
|
||||
It("uses the different keys", func() {
|
||||
var key1, key2 TokenProtectorKey
|
||||
rand.Read(key1[:])
|
||||
rand.Read(key2[:])
|
||||
tp1 := newTokenProtector(key1)
|
||||
tp2 := newTokenProtector(key2)
|
||||
t1, err := tp1.NewToken([]byte("foo"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
t2, err := tp2.NewToken([]byte("foo"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
_, err = tp1.DecodeToken(t1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = tp1.DecodeToken(t2)
|
||||
Expect(err).To(HaveOccurred())
|
||||
|
||||
// now create another token protector, reusing key1
|
||||
tp3 := newTokenProtector(key1)
|
||||
_, err = tp3.DecodeToken(t1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = tp3.DecodeToken(t2)
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("doesn't decode invalid tokens", func() {
|
||||
token, err := tp.NewToken([]byte("foobar"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
token = token[1:] // remove the first byte
|
||||
_, err = tp.DecodeToken(token)
|
||||
_, err = tp.DecodeToken(token[1:]) // the token is invalid without the first byte
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("message authentication failed"))
|
||||
})
|
||||
|
|
|
@ -58,7 +58,7 @@ type updatableAEAD struct {
|
|||
|
||||
rttStats *utils.RTTStats
|
||||
|
||||
tracer logging.ConnectionTracer
|
||||
tracer *logging.ConnectionTracer
|
||||
logger utils.Logger
|
||||
version protocol.VersionNumber
|
||||
|
||||
|
@ -71,7 +71,7 @@ var (
|
|||
_ ShortHeaderSealer = &updatableAEAD{}
|
||||
)
|
||||
|
||||
func newUpdatableAEAD(rttStats *utils.RTTStats, tracer logging.ConnectionTracer, logger utils.Logger, version protocol.VersionNumber) *updatableAEAD {
|
||||
func newUpdatableAEAD(rttStats *utils.RTTStats, tracer *logging.ConnectionTracer, logger utils.Logger, version protocol.VersionNumber) *updatableAEAD {
|
||||
return &updatableAEAD{
|
||||
firstPacketNumber: protocol.InvalidPacketNumber,
|
||||
largestAcked: protocol.InvalidPacketNumber,
|
||||
|
@ -87,7 +87,7 @@ func newUpdatableAEAD(rttStats *utils.RTTStats, tracer logging.ConnectionTracer,
|
|||
func (a *updatableAEAD) rollKeys() {
|
||||
if a.prevRcvAEAD != nil {
|
||||
a.logger.Debugf("Dropping key phase %d ahead of scheduled time. Drop time was: %s", a.keyPhase-1, a.prevRcvAEADExpiry)
|
||||
if a.tracer != nil {
|
||||
if a.tracer != nil && a.tracer.DroppedKey != nil {
|
||||
a.tracer.DroppedKey(a.keyPhase - 1)
|
||||
}
|
||||
a.prevRcvAEADExpiry = time.Time{}
|
||||
|
@ -183,7 +183,7 @@ func (a *updatableAEAD) open(dst, src []byte, rcvTime time.Time, pn protocol.Pac
|
|||
a.prevRcvAEAD = nil
|
||||
a.logger.Debugf("Dropping key phase %d", a.keyPhase-1)
|
||||
a.prevRcvAEADExpiry = time.Time{}
|
||||
if a.tracer != nil {
|
||||
if a.tracer != nil && a.tracer.DroppedKey != nil {
|
||||
a.tracer.DroppedKey(a.keyPhase - 1)
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ func (a *updatableAEAD) open(dst, src []byte, rcvTime time.Time, pn protocol.Pac
|
|||
// The peer initiated this key update. It's safe to drop the keys for the previous generation now.
|
||||
// Start a timer to drop the previous key generation.
|
||||
a.startKeyDropTimer(rcvTime)
|
||||
if a.tracer != nil {
|
||||
if a.tracer != nil && a.tracer.UpdatedKey != nil {
|
||||
a.tracer.UpdatedKey(a.keyPhase, true)
|
||||
}
|
||||
a.firstRcvdWithCurrentKey = pn
|
||||
|
@ -309,7 +309,7 @@ func (a *updatableAEAD) KeyPhase() protocol.KeyPhaseBit {
|
|||
if a.shouldInitiateKeyUpdate() {
|
||||
a.rollKeys()
|
||||
a.logger.Debugf("Initiating key update to key phase %d", a.keyPhase)
|
||||
if a.tracer != nil {
|
||||
if a.tracer != nil && a.tracer.UpdatedKey != nil {
|
||||
a.tracer.UpdatedKey(a.keyPhase, false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/refraction-networking/uquic/internal/protocol"
|
||||
"github.com/refraction-networking/uquic/internal/qerr"
|
||||
"github.com/refraction-networking/uquic/internal/utils"
|
||||
"github.com/refraction-networking/uquic/logging"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
@ -63,7 +64,8 @@ var _ = Describe("Updatable AEAD", func() {
|
|||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
serverTracer = mocklogging.NewMockConnectionTracer(mockCtrl)
|
||||
var tr *logging.ConnectionTracer
|
||||
tr, serverTracer = mocklogging.NewMockConnectionTracer(mockCtrl)
|
||||
trafficSecret1 := make([]byte, 16)
|
||||
trafficSecret2 := make([]byte, 16)
|
||||
rand.Read(trafficSecret1)
|
||||
|
@ -71,7 +73,7 @@ var _ = Describe("Updatable AEAD", func() {
|
|||
|
||||
rttStats = utils.NewRTTStats()
|
||||
client = newUpdatableAEAD(rttStats, nil, utils.DefaultLogger, v)
|
||||
server = newUpdatableAEAD(rttStats, serverTracer, utils.DefaultLogger, v)
|
||||
server = newUpdatableAEAD(rttStats, tr, utils.DefaultLogger, v)
|
||||
client.SetReadKey(cs, trafficSecret2)
|
||||
client.SetWriteKey(cs, trafficSecret1)
|
||||
server.SetReadKey(cs, trafficSecret1)
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/internal/ackhandler (interfaces: ReceivedPacketHandler)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mockackhandler -destination ackhandler/received_packet_handler.go github.com/refraction-networking/uquic/internal/ackhandler ReceivedPacketHandler
|
||||
//
|
||||
// Package mockackhandler is a generated GoMock package.
|
||||
package mockackhandler
|
||||
|
||||
|
@ -43,7 +47,7 @@ func (m *MockReceivedPacketHandler) DropPackets(arg0 protocol.EncryptionLevel) {
|
|||
}
|
||||
|
||||
// DropPackets indicates an expected call of DropPackets.
|
||||
func (mr *MockReceivedPacketHandlerMockRecorder) DropPackets(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockReceivedPacketHandlerMockRecorder) DropPackets(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropPackets", reflect.TypeOf((*MockReceivedPacketHandler)(nil).DropPackets), arg0)
|
||||
}
|
||||
|
@ -57,7 +61,7 @@ func (m *MockReceivedPacketHandler) GetAckFrame(arg0 protocol.EncryptionLevel, a
|
|||
}
|
||||
|
||||
// GetAckFrame indicates an expected call of GetAckFrame.
|
||||
func (mr *MockReceivedPacketHandlerMockRecorder) GetAckFrame(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockReceivedPacketHandlerMockRecorder) GetAckFrame(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAckFrame", reflect.TypeOf((*MockReceivedPacketHandler)(nil).GetAckFrame), arg0, arg1)
|
||||
}
|
||||
|
@ -85,7 +89,7 @@ func (m *MockReceivedPacketHandler) IsPotentiallyDuplicate(arg0 protocol.PacketN
|
|||
}
|
||||
|
||||
// IsPotentiallyDuplicate indicates an expected call of IsPotentiallyDuplicate.
|
||||
func (mr *MockReceivedPacketHandlerMockRecorder) IsPotentiallyDuplicate(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockReceivedPacketHandlerMockRecorder) IsPotentiallyDuplicate(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsPotentiallyDuplicate", reflect.TypeOf((*MockReceivedPacketHandler)(nil).IsPotentiallyDuplicate), arg0, arg1)
|
||||
}
|
||||
|
@ -99,7 +103,7 @@ func (m *MockReceivedPacketHandler) ReceivedPacket(arg0 protocol.PacketNumber, a
|
|||
}
|
||||
|
||||
// ReceivedPacket indicates an expected call of ReceivedPacket.
|
||||
func (mr *MockReceivedPacketHandlerMockRecorder) ReceivedPacket(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
|
||||
func (mr *MockReceivedPacketHandlerMockRecorder) ReceivedPacket(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedPacket", reflect.TypeOf((*MockReceivedPacketHandler)(nil).ReceivedPacket), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/internal/ackhandler (interfaces: SentPacketHandler)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mockackhandler -destination ackhandler/sent_packet_handler.go github.com/refraction-networking/uquic/internal/ackhandler SentPacketHandler
|
||||
//
|
||||
// Package mockackhandler is a generated GoMock package.
|
||||
package mockackhandler
|
||||
|
||||
|
@ -44,11 +48,25 @@ func (m *MockSentPacketHandler) DropPackets(arg0 protocol.EncryptionLevel) {
|
|||
}
|
||||
|
||||
// DropPackets indicates an expected call of DropPackets.
|
||||
func (mr *MockSentPacketHandlerMockRecorder) DropPackets(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSentPacketHandlerMockRecorder) DropPackets(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropPackets", reflect.TypeOf((*MockSentPacketHandler)(nil).DropPackets), arg0)
|
||||
}
|
||||
|
||||
// ECNMode mocks base method.
|
||||
func (m *MockSentPacketHandler) ECNMode(arg0 bool) protocol.ECN {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ECNMode", arg0)
|
||||
ret0, _ := ret[0].(protocol.ECN)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ECNMode indicates an expected call of ECNMode.
|
||||
func (mr *MockSentPacketHandlerMockRecorder) ECNMode(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNMode", reflect.TypeOf((*MockSentPacketHandler)(nil).ECNMode), arg0)
|
||||
}
|
||||
|
||||
// GetLossDetectionTimeout mocks base method.
|
||||
func (m *MockSentPacketHandler) GetLossDetectionTimeout() time.Time {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -87,7 +105,7 @@ func (m *MockSentPacketHandler) PeekPacketNumber(arg0 protocol.EncryptionLevel)
|
|||
}
|
||||
|
||||
// PeekPacketNumber indicates an expected call of PeekPacketNumber.
|
||||
func (mr *MockSentPacketHandlerMockRecorder) PeekPacketNumber(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSentPacketHandlerMockRecorder) PeekPacketNumber(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeekPacketNumber", reflect.TypeOf((*MockSentPacketHandler)(nil).PeekPacketNumber), arg0)
|
||||
}
|
||||
|
@ -101,7 +119,7 @@ func (m *MockSentPacketHandler) PopPacketNumber(arg0 protocol.EncryptionLevel) p
|
|||
}
|
||||
|
||||
// PopPacketNumber indicates an expected call of PopPacketNumber.
|
||||
func (mr *MockSentPacketHandlerMockRecorder) PopPacketNumber(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSentPacketHandlerMockRecorder) PopPacketNumber(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PopPacketNumber", reflect.TypeOf((*MockSentPacketHandler)(nil).PopPacketNumber), arg0)
|
||||
}
|
||||
|
@ -115,7 +133,7 @@ func (m *MockSentPacketHandler) QueueProbePacket(arg0 protocol.EncryptionLevel)
|
|||
}
|
||||
|
||||
// QueueProbePacket indicates an expected call of QueueProbePacket.
|
||||
func (mr *MockSentPacketHandlerMockRecorder) QueueProbePacket(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSentPacketHandlerMockRecorder) QueueProbePacket(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueueProbePacket", reflect.TypeOf((*MockSentPacketHandler)(nil).QueueProbePacket), arg0)
|
||||
}
|
||||
|
@ -130,7 +148,7 @@ func (m *MockSentPacketHandler) ReceivedAck(arg0 *wire.AckFrame, arg1 protocol.E
|
|||
}
|
||||
|
||||
// ReceivedAck indicates an expected call of ReceivedAck.
|
||||
func (mr *MockSentPacketHandlerMockRecorder) ReceivedAck(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockSentPacketHandlerMockRecorder) ReceivedAck(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedAck", reflect.TypeOf((*MockSentPacketHandler)(nil).ReceivedAck), arg0, arg1, arg2)
|
||||
}
|
||||
|
@ -142,23 +160,23 @@ func (m *MockSentPacketHandler) ReceivedBytes(arg0 protocol.ByteCount) {
|
|||
}
|
||||
|
||||
// ReceivedBytes indicates an expected call of ReceivedBytes.
|
||||
func (mr *MockSentPacketHandlerMockRecorder) ReceivedBytes(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSentPacketHandlerMockRecorder) ReceivedBytes(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedBytes", reflect.TypeOf((*MockSentPacketHandler)(nil).ReceivedBytes), arg0)
|
||||
}
|
||||
|
||||
// ResetForRetry mocks base method.
|
||||
func (m *MockSentPacketHandler) ResetForRetry() error {
|
||||
func (m *MockSentPacketHandler) ResetForRetry(arg0 time.Time) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ResetForRetry")
|
||||
ret := m.ctrl.Call(m, "ResetForRetry", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ResetForRetry indicates an expected call of ResetForRetry.
|
||||
func (mr *MockSentPacketHandlerMockRecorder) ResetForRetry() *gomock.Call {
|
||||
func (mr *MockSentPacketHandlerMockRecorder) ResetForRetry(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetForRetry", reflect.TypeOf((*MockSentPacketHandler)(nil).ResetForRetry))
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetForRetry", reflect.TypeOf((*MockSentPacketHandler)(nil).ResetForRetry), arg0)
|
||||
}
|
||||
|
||||
// SendMode mocks base method.
|
||||
|
@ -170,21 +188,21 @@ func (m *MockSentPacketHandler) SendMode(arg0 time.Time) ackhandler.SendMode {
|
|||
}
|
||||
|
||||
// SendMode indicates an expected call of SendMode.
|
||||
func (mr *MockSentPacketHandlerMockRecorder) SendMode(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSentPacketHandlerMockRecorder) SendMode(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMode", reflect.TypeOf((*MockSentPacketHandler)(nil).SendMode), arg0)
|
||||
}
|
||||
|
||||
// SentPacket mocks base method.
|
||||
func (m *MockSentPacketHandler) SentPacket(arg0 time.Time, arg1, arg2 protocol.PacketNumber, arg3 []ackhandler.StreamFrame, arg4 []ackhandler.Frame, arg5 protocol.EncryptionLevel, arg6 protocol.ByteCount, arg7 bool) {
|
||||
func (m *MockSentPacketHandler) SentPacket(arg0 time.Time, arg1, arg2 protocol.PacketNumber, arg3 []ackhandler.StreamFrame, arg4 []ackhandler.Frame, arg5 protocol.EncryptionLevel, arg6 protocol.ECN, arg7 protocol.ByteCount, arg8 bool) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentPacket", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||
m.ctrl.Call(m, "SentPacket", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||
}
|
||||
|
||||
// SentPacket indicates an expected call of SentPacket.
|
||||
func (mr *MockSentPacketHandlerMockRecorder) SentPacket(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call {
|
||||
func (mr *MockSentPacketHandlerMockRecorder) SentPacket(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockSentPacketHandler)(nil).SentPacket), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockSentPacketHandler)(nil).SentPacket), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||
}
|
||||
|
||||
// SetHandshakeConfirmed mocks base method.
|
||||
|
@ -206,7 +224,7 @@ func (m *MockSentPacketHandler) SetMaxDatagramSize(arg0 protocol.ByteCount) {
|
|||
}
|
||||
|
||||
// SetMaxDatagramSize indicates an expected call of SetMaxDatagramSize.
|
||||
func (mr *MockSentPacketHandlerMockRecorder) SetMaxDatagramSize(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSentPacketHandlerMockRecorder) SetMaxDatagramSize(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxDatagramSize", reflect.TypeOf((*MockSentPacketHandler)(nil).SetMaxDatagramSize), arg0)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/internal/congestion (interfaces: SendAlgorithmWithDebugInfos)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mocks -destination congestion.go github.com/refraction-networking/uquic/internal/congestion SendAlgorithmWithDebugInfos
|
||||
//
|
||||
// Package mocks is a generated GoMock package.
|
||||
package mocks
|
||||
|
||||
|
@ -44,7 +48,7 @@ func (m *MockSendAlgorithmWithDebugInfos) CanSend(arg0 protocol.ByteCount) bool
|
|||
}
|
||||
|
||||
// CanSend indicates an expected call of CanSend.
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) CanSend(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) CanSend(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CanSend", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).CanSend), arg0)
|
||||
}
|
||||
|
@ -72,7 +76,7 @@ func (m *MockSendAlgorithmWithDebugInfos) HasPacingBudget(arg0 time.Time) bool {
|
|||
}
|
||||
|
||||
// HasPacingBudget indicates an expected call of HasPacingBudget.
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) HasPacingBudget(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) HasPacingBudget(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasPacingBudget", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).HasPacingBudget), arg0)
|
||||
}
|
||||
|
@ -117,6 +121,18 @@ func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) MaybeExitSlowStart() *gom
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaybeExitSlowStart", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).MaybeExitSlowStart))
|
||||
}
|
||||
|
||||
// OnCongestionEvent mocks base method.
|
||||
func (m *MockSendAlgorithmWithDebugInfos) OnCongestionEvent(arg0 protocol.PacketNumber, arg1, arg2 protocol.ByteCount) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "OnCongestionEvent", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// OnCongestionEvent indicates an expected call of OnCongestionEvent.
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnCongestionEvent(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnCongestionEvent", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnCongestionEvent), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// OnPacketAcked mocks base method.
|
||||
func (m *MockSendAlgorithmWithDebugInfos) OnPacketAcked(arg0 protocol.PacketNumber, arg1, arg2 protocol.ByteCount, arg3 time.Time) {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -124,23 +140,11 @@ func (m *MockSendAlgorithmWithDebugInfos) OnPacketAcked(arg0 protocol.PacketNumb
|
|||
}
|
||||
|
||||
// OnPacketAcked indicates an expected call of OnPacketAcked.
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketAcked(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketAcked(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketAcked", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketAcked), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// OnPacketLost mocks base method.
|
||||
func (m *MockSendAlgorithmWithDebugInfos) OnPacketLost(arg0 protocol.PacketNumber, arg1, arg2 protocol.ByteCount) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "OnPacketLost", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// OnPacketLost indicates an expected call of OnPacketLost.
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketLost(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketLost", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketLost), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// OnPacketSent mocks base method.
|
||||
func (m *MockSendAlgorithmWithDebugInfos) OnPacketSent(arg0 time.Time, arg1 protocol.ByteCount, arg2 protocol.PacketNumber, arg3 protocol.ByteCount, arg4 bool) {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -148,7 +152,7 @@ func (m *MockSendAlgorithmWithDebugInfos) OnPacketSent(arg0 time.Time, arg1 prot
|
|||
}
|
||||
|
||||
// OnPacketSent indicates an expected call of OnPacketSent.
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketSent(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketSent(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketSent", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketSent), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
@ -160,7 +164,7 @@ func (m *MockSendAlgorithmWithDebugInfos) OnRetransmissionTimeout(arg0 bool) {
|
|||
}
|
||||
|
||||
// OnRetransmissionTimeout indicates an expected call of OnRetransmissionTimeout.
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnRetransmissionTimeout(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnRetransmissionTimeout(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnRetransmissionTimeout", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnRetransmissionTimeout), arg0)
|
||||
}
|
||||
|
@ -172,7 +176,7 @@ func (m *MockSendAlgorithmWithDebugInfos) SetMaxDatagramSize(arg0 protocol.ByteC
|
|||
}
|
||||
|
||||
// SetMaxDatagramSize indicates an expected call of SetMaxDatagramSize.
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) SetMaxDatagramSize(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) SetMaxDatagramSize(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxDatagramSize", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).SetMaxDatagramSize), arg0)
|
||||
}
|
||||
|
@ -186,7 +190,7 @@ func (m *MockSendAlgorithmWithDebugInfos) TimeUntilSend(arg0 protocol.ByteCount)
|
|||
}
|
||||
|
||||
// TimeUntilSend indicates an expected call of TimeUntilSend.
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) TimeUntilSend(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) TimeUntilSend(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TimeUntilSend", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).TimeUntilSend), arg0)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/internal/flowcontrol (interfaces: ConnectionFlowController)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mocks -destination connection_flow_controller.go github.com/refraction-networking/uquic/internal/flowcontrol ConnectionFlowController
|
||||
//
|
||||
// Package mocks is a generated GoMock package.
|
||||
package mocks
|
||||
|
||||
|
@ -41,7 +45,7 @@ func (m *MockConnectionFlowController) AddBytesRead(arg0 protocol.ByteCount) {
|
|||
}
|
||||
|
||||
// AddBytesRead indicates an expected call of AddBytesRead.
|
||||
func (mr *MockConnectionFlowControllerMockRecorder) AddBytesRead(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionFlowControllerMockRecorder) AddBytesRead(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesRead", reflect.TypeOf((*MockConnectionFlowController)(nil).AddBytesRead), arg0)
|
||||
}
|
||||
|
@ -53,7 +57,7 @@ func (m *MockConnectionFlowController) AddBytesSent(arg0 protocol.ByteCount) {
|
|||
}
|
||||
|
||||
// AddBytesSent indicates an expected call of AddBytesSent.
|
||||
func (mr *MockConnectionFlowControllerMockRecorder) AddBytesSent(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionFlowControllerMockRecorder) AddBytesSent(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesSent", reflect.TypeOf((*MockConnectionFlowController)(nil).AddBytesSent), arg0)
|
||||
}
|
||||
|
@ -122,7 +126,7 @@ func (m *MockConnectionFlowController) UpdateSendWindow(arg0 protocol.ByteCount)
|
|||
}
|
||||
|
||||
// UpdateSendWindow indicates an expected call of UpdateSendWindow.
|
||||
func (mr *MockConnectionFlowControllerMockRecorder) UpdateSendWindow(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionFlowControllerMockRecorder) UpdateSendWindow(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSendWindow", reflect.TypeOf((*MockConnectionFlowController)(nil).UpdateSendWindow), arg0)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/internal/handshake (interfaces: CryptoSetup)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mocks -destination crypto_setup_tmp.go github.com/refraction-networking/uquic/internal/handshake CryptoSetup
|
||||
//
|
||||
// Package mocks is a generated GoMock package.
|
||||
package mocks
|
||||
|
||||
|
@ -42,7 +46,7 @@ func (m *MockCryptoSetup) ChangeConnectionID(arg0 protocol.ConnectionID) {
|
|||
}
|
||||
|
||||
// ChangeConnectionID indicates an expected call of ChangeConnectionID.
|
||||
func (mr *MockCryptoSetupMockRecorder) ChangeConnectionID(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockCryptoSetupMockRecorder) ChangeConnectionID(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangeConnectionID", reflect.TypeOf((*MockCryptoSetup)(nil).ChangeConnectionID), arg0)
|
||||
}
|
||||
|
@ -231,7 +235,7 @@ func (m *MockCryptoSetup) HandleMessage(arg0 []byte, arg1 protocol.EncryptionLev
|
|||
}
|
||||
|
||||
// HandleMessage indicates an expected call of HandleMessage.
|
||||
func (mr *MockCryptoSetupMockRecorder) HandleMessage(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockCryptoSetupMockRecorder) HandleMessage(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMessage", reflect.TypeOf((*MockCryptoSetup)(nil).HandleMessage), arg0, arg1)
|
||||
}
|
||||
|
@ -271,7 +275,7 @@ func (m *MockCryptoSetup) SetLargest1RTTAcked(arg0 protocol.PacketNumber) error
|
|||
}
|
||||
|
||||
// SetLargest1RTTAcked indicates an expected call of SetLargest1RTTAcked.
|
||||
func (mr *MockCryptoSetupMockRecorder) SetLargest1RTTAcked(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockCryptoSetupMockRecorder) SetLargest1RTTAcked(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLargest1RTTAcked", reflect.TypeOf((*MockCryptoSetup)(nil).SetLargest1RTTAcked), arg0)
|
||||
}
|
||||
|
|
|
@ -1,377 +1,108 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/logging (interfaces: ConnectionTracer)
|
||||
//go:build !gomock && !generate
|
||||
|
||||
// Package mocklogging is a generated GoMock package.
|
||||
package mocklogging
|
||||
|
||||
import (
|
||||
net "net"
|
||||
reflect "reflect"
|
||||
time "time"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
protocol "github.com/refraction-networking/uquic/internal/protocol"
|
||||
utils "github.com/refraction-networking/uquic/internal/utils"
|
||||
wire "github.com/refraction-networking/uquic/internal/wire"
|
||||
logging "github.com/refraction-networking/uquic/logging"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
"github.com/refraction-networking/uquic/internal/mocks/logging/internal"
|
||||
"github.com/refraction-networking/uquic/logging"
|
||||
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockConnectionTracer is a mock of ConnectionTracer interface.
|
||||
type MockConnectionTracer struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockConnectionTracerMockRecorder
|
||||
}
|
||||
type MockConnectionTracer = internal.MockConnectionTracer
|
||||
|
||||
// MockConnectionTracerMockRecorder is the mock recorder for MockConnectionTracer.
|
||||
type MockConnectionTracerMockRecorder struct {
|
||||
mock *MockConnectionTracer
|
||||
}
|
||||
|
||||
// NewMockConnectionTracer creates a new mock instance.
|
||||
func NewMockConnectionTracer(ctrl *gomock.Controller) *MockConnectionTracer {
|
||||
mock := &MockConnectionTracer{ctrl: ctrl}
|
||||
mock.recorder = &MockConnectionTracerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockConnectionTracer) EXPECT() *MockConnectionTracerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// AcknowledgedPacket mocks base method.
|
||||
func (m *MockConnectionTracer) AcknowledgedPacket(arg0 protocol.EncryptionLevel, arg1 protocol.PacketNumber) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "AcknowledgedPacket", arg0, arg1)
|
||||
}
|
||||
|
||||
// AcknowledgedPacket indicates an expected call of AcknowledgedPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) AcknowledgedPacket(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcknowledgedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).AcknowledgedPacket), arg0, arg1)
|
||||
}
|
||||
|
||||
// BufferedPacket mocks base method.
|
||||
func (m *MockConnectionTracer) BufferedPacket(arg0 logging.PacketType, arg1 protocol.ByteCount) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "BufferedPacket", arg0, arg1)
|
||||
}
|
||||
|
||||
// BufferedPacket indicates an expected call of BufferedPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) BufferedPacket(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BufferedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).BufferedPacket), arg0, arg1)
|
||||
}
|
||||
|
||||
// Close mocks base method.
|
||||
func (m *MockConnectionTracer) Close() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Close")
|
||||
}
|
||||
|
||||
// Close indicates an expected call of Close.
|
||||
func (mr *MockConnectionTracerMockRecorder) Close() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockConnectionTracer)(nil).Close))
|
||||
}
|
||||
|
||||
// ClosedConnection mocks base method.
|
||||
func (m *MockConnectionTracer) ClosedConnection(arg0 error) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "ClosedConnection", arg0)
|
||||
}
|
||||
|
||||
// ClosedConnection indicates an expected call of ClosedConnection.
|
||||
func (mr *MockConnectionTracerMockRecorder) ClosedConnection(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClosedConnection", reflect.TypeOf((*MockConnectionTracer)(nil).ClosedConnection), arg0)
|
||||
}
|
||||
|
||||
// Debug mocks base method.
|
||||
func (m *MockConnectionTracer) Debug(arg0, arg1 string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Debug", arg0, arg1)
|
||||
}
|
||||
|
||||
// Debug indicates an expected call of Debug.
|
||||
func (mr *MockConnectionTracerMockRecorder) Debug(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockConnectionTracer)(nil).Debug), arg0, arg1)
|
||||
}
|
||||
|
||||
// DroppedEncryptionLevel mocks base method.
|
||||
func (m *MockConnectionTracer) DroppedEncryptionLevel(arg0 protocol.EncryptionLevel) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "DroppedEncryptionLevel", arg0)
|
||||
}
|
||||
|
||||
// DroppedEncryptionLevel indicates an expected call of DroppedEncryptionLevel.
|
||||
func (mr *MockConnectionTracerMockRecorder) DroppedEncryptionLevel(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedEncryptionLevel", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedEncryptionLevel), arg0)
|
||||
}
|
||||
|
||||
// DroppedKey mocks base method.
|
||||
func (m *MockConnectionTracer) DroppedKey(arg0 protocol.KeyPhase) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "DroppedKey", arg0)
|
||||
}
|
||||
|
||||
// DroppedKey indicates an expected call of DroppedKey.
|
||||
func (mr *MockConnectionTracerMockRecorder) DroppedKey(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedKey", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedKey), arg0)
|
||||
}
|
||||
|
||||
// DroppedPacket mocks base method.
|
||||
func (m *MockConnectionTracer) DroppedPacket(arg0 logging.PacketType, arg1 protocol.ByteCount, arg2 logging.PacketDropReason) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "DroppedPacket", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// DroppedPacket indicates an expected call of DroppedPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) DroppedPacket(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedPacket), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// LossTimerCanceled mocks base method.
|
||||
func (m *MockConnectionTracer) LossTimerCanceled() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "LossTimerCanceled")
|
||||
}
|
||||
|
||||
// LossTimerCanceled indicates an expected call of LossTimerCanceled.
|
||||
func (mr *MockConnectionTracerMockRecorder) LossTimerCanceled() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LossTimerCanceled", reflect.TypeOf((*MockConnectionTracer)(nil).LossTimerCanceled))
|
||||
}
|
||||
|
||||
// LossTimerExpired mocks base method.
|
||||
func (m *MockConnectionTracer) LossTimerExpired(arg0 logging.TimerType, arg1 protocol.EncryptionLevel) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "LossTimerExpired", arg0, arg1)
|
||||
}
|
||||
|
||||
// LossTimerExpired indicates an expected call of LossTimerExpired.
|
||||
func (mr *MockConnectionTracerMockRecorder) LossTimerExpired(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LossTimerExpired", reflect.TypeOf((*MockConnectionTracer)(nil).LossTimerExpired), arg0, arg1)
|
||||
}
|
||||
|
||||
// LostPacket mocks base method.
|
||||
func (m *MockConnectionTracer) LostPacket(arg0 protocol.EncryptionLevel, arg1 protocol.PacketNumber, arg2 logging.PacketLossReason) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "LostPacket", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// LostPacket indicates an expected call of LostPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) LostPacket(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LostPacket", reflect.TypeOf((*MockConnectionTracer)(nil).LostPacket), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// NegotiatedVersion mocks base method.
|
||||
func (m *MockConnectionTracer) NegotiatedVersion(arg0 protocol.VersionNumber, arg1, arg2 []protocol.VersionNumber) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "NegotiatedVersion", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// NegotiatedVersion indicates an expected call of NegotiatedVersion.
|
||||
func (mr *MockConnectionTracerMockRecorder) NegotiatedVersion(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NegotiatedVersion", reflect.TypeOf((*MockConnectionTracer)(nil).NegotiatedVersion), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// ReceivedLongHeaderPacket mocks base method.
|
||||
func (m *MockConnectionTracer) ReceivedLongHeaderPacket(arg0 *wire.ExtendedHeader, arg1 protocol.ByteCount, arg2 []logging.Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "ReceivedLongHeaderPacket", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// ReceivedLongHeaderPacket indicates an expected call of ReceivedLongHeaderPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedLongHeaderPacket(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedLongHeaderPacket), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// ReceivedRetry mocks base method.
|
||||
func (m *MockConnectionTracer) ReceivedRetry(arg0 *wire.Header) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "ReceivedRetry", arg0)
|
||||
}
|
||||
|
||||
// ReceivedRetry indicates an expected call of ReceivedRetry.
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedRetry(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedRetry", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedRetry), arg0)
|
||||
}
|
||||
|
||||
// ReceivedShortHeaderPacket mocks base method.
|
||||
func (m *MockConnectionTracer) ReceivedShortHeaderPacket(arg0 *logging.ShortHeader, arg1 protocol.ByteCount, arg2 []logging.Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "ReceivedShortHeaderPacket", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// ReceivedShortHeaderPacket indicates an expected call of ReceivedShortHeaderPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedShortHeaderPacket(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedShortHeaderPacket), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// ReceivedTransportParameters mocks base method.
|
||||
func (m *MockConnectionTracer) ReceivedTransportParameters(arg0 *wire.TransportParameters) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "ReceivedTransportParameters", arg0)
|
||||
}
|
||||
|
||||
// ReceivedTransportParameters indicates an expected call of ReceivedTransportParameters.
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedTransportParameters(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedTransportParameters), arg0)
|
||||
}
|
||||
|
||||
// ReceivedVersionNegotiationPacket mocks base method.
|
||||
func (m *MockConnectionTracer) ReceivedVersionNegotiationPacket(arg0, arg1 protocol.ArbitraryLenConnectionID, arg2 []protocol.VersionNumber) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "ReceivedVersionNegotiationPacket", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// ReceivedVersionNegotiationPacket indicates an expected call of ReceivedVersionNegotiationPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedVersionNegotiationPacket(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedVersionNegotiationPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedVersionNegotiationPacket), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// RestoredTransportParameters mocks base method.
|
||||
func (m *MockConnectionTracer) RestoredTransportParameters(arg0 *wire.TransportParameters) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "RestoredTransportParameters", arg0)
|
||||
}
|
||||
|
||||
// RestoredTransportParameters indicates an expected call of RestoredTransportParameters.
|
||||
func (mr *MockConnectionTracerMockRecorder) RestoredTransportParameters(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestoredTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).RestoredTransportParameters), arg0)
|
||||
}
|
||||
|
||||
// SentLongHeaderPacket mocks base method.
|
||||
func (m *MockConnectionTracer) SentLongHeaderPacket(arg0 *wire.ExtendedHeader, arg1 protocol.ByteCount, arg2 *wire.AckFrame, arg3 []logging.Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentLongHeaderPacket", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentLongHeaderPacket indicates an expected call of SentLongHeaderPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) SentLongHeaderPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentLongHeaderPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentShortHeaderPacket mocks base method.
|
||||
func (m *MockConnectionTracer) SentShortHeaderPacket(arg0 *logging.ShortHeader, arg1 protocol.ByteCount, arg2 *wire.AckFrame, arg3 []logging.Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentShortHeaderPacket", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentShortHeaderPacket indicates an expected call of SentShortHeaderPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) SentShortHeaderPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentShortHeaderPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentTransportParameters mocks base method.
|
||||
func (m *MockConnectionTracer) SentTransportParameters(arg0 *wire.TransportParameters) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentTransportParameters", arg0)
|
||||
}
|
||||
|
||||
// SentTransportParameters indicates an expected call of SentTransportParameters.
|
||||
func (mr *MockConnectionTracerMockRecorder) SentTransportParameters(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).SentTransportParameters), arg0)
|
||||
}
|
||||
|
||||
// SetLossTimer mocks base method.
|
||||
func (m *MockConnectionTracer) SetLossTimer(arg0 logging.TimerType, arg1 protocol.EncryptionLevel, arg2 time.Time) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetLossTimer", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// SetLossTimer indicates an expected call of SetLossTimer.
|
||||
func (mr *MockConnectionTracerMockRecorder) SetLossTimer(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLossTimer", reflect.TypeOf((*MockConnectionTracer)(nil).SetLossTimer), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// StartedConnection mocks base method.
|
||||
func (m *MockConnectionTracer) StartedConnection(arg0, arg1 net.Addr, arg2, arg3 protocol.ConnectionID) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "StartedConnection", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// StartedConnection indicates an expected call of StartedConnection.
|
||||
func (mr *MockConnectionTracerMockRecorder) StartedConnection(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartedConnection", reflect.TypeOf((*MockConnectionTracer)(nil).StartedConnection), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// UpdatedCongestionState mocks base method.
|
||||
func (m *MockConnectionTracer) UpdatedCongestionState(arg0 logging.CongestionState) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "UpdatedCongestionState", arg0)
|
||||
}
|
||||
|
||||
// UpdatedCongestionState indicates an expected call of UpdatedCongestionState.
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedCongestionState(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedCongestionState", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedCongestionState), arg0)
|
||||
}
|
||||
|
||||
// UpdatedKey mocks base method.
|
||||
func (m *MockConnectionTracer) UpdatedKey(arg0 protocol.KeyPhase, arg1 bool) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "UpdatedKey", arg0, arg1)
|
||||
}
|
||||
|
||||
// UpdatedKey indicates an expected call of UpdatedKey.
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedKey(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedKey", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedKey), arg0, arg1)
|
||||
}
|
||||
|
||||
// UpdatedKeyFromTLS mocks base method.
|
||||
func (m *MockConnectionTracer) UpdatedKeyFromTLS(arg0 protocol.EncryptionLevel, arg1 protocol.Perspective) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "UpdatedKeyFromTLS", arg0, arg1)
|
||||
}
|
||||
|
||||
// UpdatedKeyFromTLS indicates an expected call of UpdatedKeyFromTLS.
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedKeyFromTLS(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedKeyFromTLS", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedKeyFromTLS), arg0, arg1)
|
||||
}
|
||||
|
||||
// UpdatedMetrics mocks base method.
|
||||
func (m *MockConnectionTracer) UpdatedMetrics(arg0 *utils.RTTStats, arg1, arg2 protocol.ByteCount, arg3 int) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "UpdatedMetrics", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// UpdatedMetrics indicates an expected call of UpdatedMetrics.
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedMetrics(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedMetrics", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedMetrics), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// UpdatedPTOCount mocks base method.
|
||||
func (m *MockConnectionTracer) UpdatedPTOCount(arg0 uint32) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "UpdatedPTOCount", arg0)
|
||||
}
|
||||
|
||||
// UpdatedPTOCount indicates an expected call of UpdatedPTOCount.
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedPTOCount(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedPTOCount", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedPTOCount), arg0)
|
||||
func NewMockConnectionTracer(ctrl *gomock.Controller) (*logging.ConnectionTracer, *MockConnectionTracer) {
|
||||
t := internal.NewMockConnectionTracer(ctrl)
|
||||
return &logging.ConnectionTracer{
|
||||
StartedConnection: func(local, remote net.Addr, srcConnID, destConnID logging.ConnectionID) {
|
||||
t.StartedConnection(local, remote, srcConnID, destConnID)
|
||||
},
|
||||
NegotiatedVersion: func(chosen logging.VersionNumber, clientVersions, serverVersions []logging.VersionNumber) {
|
||||
t.NegotiatedVersion(chosen, clientVersions, serverVersions)
|
||||
},
|
||||
ClosedConnection: func(e error) {
|
||||
t.ClosedConnection(e)
|
||||
},
|
||||
SentTransportParameters: func(tp *logging.TransportParameters) {
|
||||
t.SentTransportParameters(tp)
|
||||
},
|
||||
ReceivedTransportParameters: func(tp *logging.TransportParameters) {
|
||||
t.ReceivedTransportParameters(tp)
|
||||
},
|
||||
RestoredTransportParameters: func(tp *logging.TransportParameters) {
|
||||
t.RestoredTransportParameters(tp)
|
||||
},
|
||||
SentLongHeaderPacket: func(hdr *logging.ExtendedHeader, size logging.ByteCount, ecn logging.ECN, ack *logging.AckFrame, frames []logging.Frame) {
|
||||
t.SentLongHeaderPacket(hdr, size, ecn, ack, frames)
|
||||
},
|
||||
SentShortHeaderPacket: func(hdr *logging.ShortHeader, size logging.ByteCount, ecn logging.ECN, ack *logging.AckFrame, frames []logging.Frame) {
|
||||
t.SentShortHeaderPacket(hdr, size, ecn, ack, frames)
|
||||
},
|
||||
ReceivedVersionNegotiationPacket: func(dest, src logging.ArbitraryLenConnectionID, versions []logging.VersionNumber) {
|
||||
t.ReceivedVersionNegotiationPacket(dest, src, versions)
|
||||
},
|
||||
ReceivedRetry: func(hdr *logging.Header) {
|
||||
t.ReceivedRetry(hdr)
|
||||
},
|
||||
ReceivedLongHeaderPacket: func(hdr *logging.ExtendedHeader, size logging.ByteCount, ecn logging.ECN, frames []logging.Frame) {
|
||||
t.ReceivedLongHeaderPacket(hdr, size, ecn, frames)
|
||||
},
|
||||
ReceivedShortHeaderPacket: func(hdr *logging.ShortHeader, size logging.ByteCount, ecn logging.ECN, frames []logging.Frame) {
|
||||
t.ReceivedShortHeaderPacket(hdr, size, ecn, frames)
|
||||
},
|
||||
BufferedPacket: func(typ logging.PacketType, size logging.ByteCount) {
|
||||
t.BufferedPacket(typ, size)
|
||||
},
|
||||
DroppedPacket: func(typ logging.PacketType, size logging.ByteCount, reason logging.PacketDropReason) {
|
||||
t.DroppedPacket(typ, size, reason)
|
||||
},
|
||||
UpdatedMetrics: func(rttStats *logging.RTTStats, cwnd, bytesInFlight logging.ByteCount, packetsInFlight int) {
|
||||
t.UpdatedMetrics(rttStats, cwnd, bytesInFlight, packetsInFlight)
|
||||
},
|
||||
AcknowledgedPacket: func(encLevel logging.EncryptionLevel, pn logging.PacketNumber) {
|
||||
t.AcknowledgedPacket(encLevel, pn)
|
||||
},
|
||||
LostPacket: func(encLevel logging.EncryptionLevel, pn logging.PacketNumber, reason logging.PacketLossReason) {
|
||||
t.LostPacket(encLevel, pn, reason)
|
||||
},
|
||||
UpdatedCongestionState: func(state logging.CongestionState) {
|
||||
t.UpdatedCongestionState(state)
|
||||
},
|
||||
UpdatedPTOCount: func(value uint32) {
|
||||
t.UpdatedPTOCount(value)
|
||||
},
|
||||
UpdatedKeyFromTLS: func(encLevel logging.EncryptionLevel, perspective logging.Perspective) {
|
||||
t.UpdatedKeyFromTLS(encLevel, perspective)
|
||||
},
|
||||
UpdatedKey: func(generation logging.KeyPhase, remote bool) {
|
||||
t.UpdatedKey(generation, remote)
|
||||
},
|
||||
DroppedEncryptionLevel: func(encLevel logging.EncryptionLevel) {
|
||||
t.DroppedEncryptionLevel(encLevel)
|
||||
},
|
||||
DroppedKey: func(generation logging.KeyPhase) {
|
||||
t.DroppedKey(generation)
|
||||
},
|
||||
SetLossTimer: func(typ logging.TimerType, encLevel logging.EncryptionLevel, exp time.Time) {
|
||||
t.SetLossTimer(typ, encLevel, exp)
|
||||
},
|
||||
LossTimerExpired: func(typ logging.TimerType, encLevel logging.EncryptionLevel) {
|
||||
t.LossTimerExpired(typ, encLevel)
|
||||
},
|
||||
LossTimerCanceled: func() {
|
||||
t.LossTimerCanceled()
|
||||
},
|
||||
ECNStateUpdated: func(state logging.ECNState, trigger logging.ECNStateTrigger) {
|
||||
t.ECNStateUpdated(state, trigger)
|
||||
},
|
||||
Close: func() {
|
||||
t.Close()
|
||||
},
|
||||
Debug: func(name, msg string) {
|
||||
t.Debug(name, msg)
|
||||
},
|
||||
}, t
|
||||
}
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/logging (interfaces: ConnectionTracer)
|
||||
|
||||
// Package logging is a generated GoMock package.
|
||||
package logging
|
||||
// Source: github.com/refraction-networking/uquic/internal/mocks/logging (interfaces: ConnectionTracer)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package internal -destination internal/connection_tracer.go github.com/refraction-networking/uquic/internal/mocks/logging ConnectionTracer
|
||||
//
|
||||
// Package internal is a generated GoMock package.
|
||||
package internal
|
||||
|
||||
import (
|
||||
net "net"
|
||||
reflect "reflect"
|
||||
time "time"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
protocol "github.com/refraction-networking/uquic/internal/protocol"
|
||||
utils "github.com/refraction-networking/uquic/internal/utils"
|
||||
wire "github.com/refraction-networking/uquic/internal/wire"
|
||||
logging "github.com/refraction-networking/uquic/logging"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockConnectionTracer is a mock of ConnectionTracer interface.
|
||||
|
@ -45,19 +50,19 @@ func (m *MockConnectionTracer) AcknowledgedPacket(arg0 protocol.EncryptionLevel,
|
|||
}
|
||||
|
||||
// AcknowledgedPacket indicates an expected call of AcknowledgedPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) AcknowledgedPacket(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) AcknowledgedPacket(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcknowledgedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).AcknowledgedPacket), arg0, arg1)
|
||||
}
|
||||
|
||||
// BufferedPacket mocks base method.
|
||||
func (m *MockConnectionTracer) BufferedPacket(arg0 PacketType, arg1 protocol.ByteCount) {
|
||||
func (m *MockConnectionTracer) BufferedPacket(arg0 logging.PacketType, arg1 protocol.ByteCount) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "BufferedPacket", arg0, arg1)
|
||||
}
|
||||
|
||||
// BufferedPacket indicates an expected call of BufferedPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) BufferedPacket(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) BufferedPacket(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BufferedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).BufferedPacket), arg0, arg1)
|
||||
}
|
||||
|
@ -81,7 +86,7 @@ func (m *MockConnectionTracer) ClosedConnection(arg0 error) {
|
|||
}
|
||||
|
||||
// ClosedConnection indicates an expected call of ClosedConnection.
|
||||
func (mr *MockConnectionTracerMockRecorder) ClosedConnection(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) ClosedConnection(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClosedConnection", reflect.TypeOf((*MockConnectionTracer)(nil).ClosedConnection), arg0)
|
||||
}
|
||||
|
@ -93,7 +98,7 @@ func (m *MockConnectionTracer) Debug(arg0, arg1 string) {
|
|||
}
|
||||
|
||||
// Debug indicates an expected call of Debug.
|
||||
func (mr *MockConnectionTracerMockRecorder) Debug(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) Debug(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockConnectionTracer)(nil).Debug), arg0, arg1)
|
||||
}
|
||||
|
@ -105,7 +110,7 @@ func (m *MockConnectionTracer) DroppedEncryptionLevel(arg0 protocol.EncryptionLe
|
|||
}
|
||||
|
||||
// DroppedEncryptionLevel indicates an expected call of DroppedEncryptionLevel.
|
||||
func (mr *MockConnectionTracerMockRecorder) DroppedEncryptionLevel(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) DroppedEncryptionLevel(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedEncryptionLevel", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedEncryptionLevel), arg0)
|
||||
}
|
||||
|
@ -117,23 +122,35 @@ func (m *MockConnectionTracer) DroppedKey(arg0 protocol.KeyPhase) {
|
|||
}
|
||||
|
||||
// DroppedKey indicates an expected call of DroppedKey.
|
||||
func (mr *MockConnectionTracerMockRecorder) DroppedKey(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) DroppedKey(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedKey", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedKey), arg0)
|
||||
}
|
||||
|
||||
// DroppedPacket mocks base method.
|
||||
func (m *MockConnectionTracer) DroppedPacket(arg0 PacketType, arg1 protocol.ByteCount, arg2 PacketDropReason) {
|
||||
func (m *MockConnectionTracer) DroppedPacket(arg0 logging.PacketType, arg1 protocol.ByteCount, arg2 logging.PacketDropReason) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "DroppedPacket", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// DroppedPacket indicates an expected call of DroppedPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) DroppedPacket(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) DroppedPacket(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedPacket), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// ECNStateUpdated mocks base method.
|
||||
func (m *MockConnectionTracer) ECNStateUpdated(arg0 logging.ECNState, arg1 logging.ECNStateTrigger) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "ECNStateUpdated", arg0, arg1)
|
||||
}
|
||||
|
||||
// ECNStateUpdated indicates an expected call of ECNStateUpdated.
|
||||
func (mr *MockConnectionTracerMockRecorder) ECNStateUpdated(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNStateUpdated", reflect.TypeOf((*MockConnectionTracer)(nil).ECNStateUpdated), arg0, arg1)
|
||||
}
|
||||
|
||||
// LossTimerCanceled mocks base method.
|
||||
func (m *MockConnectionTracer) LossTimerCanceled() {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -147,25 +164,25 @@ func (mr *MockConnectionTracerMockRecorder) LossTimerCanceled() *gomock.Call {
|
|||
}
|
||||
|
||||
// LossTimerExpired mocks base method.
|
||||
func (m *MockConnectionTracer) LossTimerExpired(arg0 TimerType, arg1 protocol.EncryptionLevel) {
|
||||
func (m *MockConnectionTracer) LossTimerExpired(arg0 logging.TimerType, arg1 protocol.EncryptionLevel) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "LossTimerExpired", arg0, arg1)
|
||||
}
|
||||
|
||||
// LossTimerExpired indicates an expected call of LossTimerExpired.
|
||||
func (mr *MockConnectionTracerMockRecorder) LossTimerExpired(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) LossTimerExpired(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LossTimerExpired", reflect.TypeOf((*MockConnectionTracer)(nil).LossTimerExpired), arg0, arg1)
|
||||
}
|
||||
|
||||
// LostPacket mocks base method.
|
||||
func (m *MockConnectionTracer) LostPacket(arg0 protocol.EncryptionLevel, arg1 protocol.PacketNumber, arg2 PacketLossReason) {
|
||||
func (m *MockConnectionTracer) LostPacket(arg0 protocol.EncryptionLevel, arg1 protocol.PacketNumber, arg2 logging.PacketLossReason) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "LostPacket", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// LostPacket indicates an expected call of LostPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) LostPacket(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) LostPacket(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LostPacket", reflect.TypeOf((*MockConnectionTracer)(nil).LostPacket), arg0, arg1, arg2)
|
||||
}
|
||||
|
@ -177,21 +194,21 @@ func (m *MockConnectionTracer) NegotiatedVersion(arg0 protocol.VersionNumber, ar
|
|||
}
|
||||
|
||||
// NegotiatedVersion indicates an expected call of NegotiatedVersion.
|
||||
func (mr *MockConnectionTracerMockRecorder) NegotiatedVersion(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) NegotiatedVersion(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NegotiatedVersion", reflect.TypeOf((*MockConnectionTracer)(nil).NegotiatedVersion), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// ReceivedLongHeaderPacket mocks base method.
|
||||
func (m *MockConnectionTracer) ReceivedLongHeaderPacket(arg0 *wire.ExtendedHeader, arg1 protocol.ByteCount, arg2 []Frame) {
|
||||
func (m *MockConnectionTracer) ReceivedLongHeaderPacket(arg0 *wire.ExtendedHeader, arg1 protocol.ByteCount, arg2 protocol.ECN, arg3 []logging.Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "ReceivedLongHeaderPacket", arg0, arg1, arg2)
|
||||
m.ctrl.Call(m, "ReceivedLongHeaderPacket", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// ReceivedLongHeaderPacket indicates an expected call of ReceivedLongHeaderPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedLongHeaderPacket(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedLongHeaderPacket(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedLongHeaderPacket), arg0, arg1, arg2)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedLongHeaderPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// ReceivedRetry mocks base method.
|
||||
|
@ -201,21 +218,21 @@ func (m *MockConnectionTracer) ReceivedRetry(arg0 *wire.Header) {
|
|||
}
|
||||
|
||||
// ReceivedRetry indicates an expected call of ReceivedRetry.
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedRetry(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedRetry(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedRetry", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedRetry), arg0)
|
||||
}
|
||||
|
||||
// ReceivedShortHeaderPacket mocks base method.
|
||||
func (m *MockConnectionTracer) ReceivedShortHeaderPacket(arg0 *ShortHeader, arg1 protocol.ByteCount, arg2 []Frame) {
|
||||
func (m *MockConnectionTracer) ReceivedShortHeaderPacket(arg0 *logging.ShortHeader, arg1 protocol.ByteCount, arg2 protocol.ECN, arg3 []logging.Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "ReceivedShortHeaderPacket", arg0, arg1, arg2)
|
||||
m.ctrl.Call(m, "ReceivedShortHeaderPacket", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// ReceivedShortHeaderPacket indicates an expected call of ReceivedShortHeaderPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedShortHeaderPacket(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedShortHeaderPacket(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedShortHeaderPacket), arg0, arg1, arg2)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedShortHeaderPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// ReceivedTransportParameters mocks base method.
|
||||
|
@ -225,7 +242,7 @@ func (m *MockConnectionTracer) ReceivedTransportParameters(arg0 *wire.TransportP
|
|||
}
|
||||
|
||||
// ReceivedTransportParameters indicates an expected call of ReceivedTransportParameters.
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedTransportParameters(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedTransportParameters(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedTransportParameters), arg0)
|
||||
}
|
||||
|
@ -237,7 +254,7 @@ func (m *MockConnectionTracer) ReceivedVersionNegotiationPacket(arg0, arg1 proto
|
|||
}
|
||||
|
||||
// ReceivedVersionNegotiationPacket indicates an expected call of ReceivedVersionNegotiationPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedVersionNegotiationPacket(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) ReceivedVersionNegotiationPacket(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedVersionNegotiationPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedVersionNegotiationPacket), arg0, arg1, arg2)
|
||||
}
|
||||
|
@ -249,33 +266,33 @@ func (m *MockConnectionTracer) RestoredTransportParameters(arg0 *wire.TransportP
|
|||
}
|
||||
|
||||
// RestoredTransportParameters indicates an expected call of RestoredTransportParameters.
|
||||
func (mr *MockConnectionTracerMockRecorder) RestoredTransportParameters(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) RestoredTransportParameters(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestoredTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).RestoredTransportParameters), arg0)
|
||||
}
|
||||
|
||||
// SentLongHeaderPacket mocks base method.
|
||||
func (m *MockConnectionTracer) SentLongHeaderPacket(arg0 *wire.ExtendedHeader, arg1 protocol.ByteCount, arg2 *wire.AckFrame, arg3 []Frame) {
|
||||
func (m *MockConnectionTracer) SentLongHeaderPacket(arg0 *wire.ExtendedHeader, arg1 protocol.ByteCount, arg2 protocol.ECN, arg3 *wire.AckFrame, arg4 []logging.Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentLongHeaderPacket", arg0, arg1, arg2, arg3)
|
||||
m.ctrl.Call(m, "SentLongHeaderPacket", arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// SentLongHeaderPacket indicates an expected call of SentLongHeaderPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) SentLongHeaderPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) SentLongHeaderPacket(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentLongHeaderPacket), arg0, arg1, arg2, arg3)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentLongHeaderPacket), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// SentShortHeaderPacket mocks base method.
|
||||
func (m *MockConnectionTracer) SentShortHeaderPacket(arg0 *ShortHeader, arg1 protocol.ByteCount, arg2 *wire.AckFrame, arg3 []Frame) {
|
||||
func (m *MockConnectionTracer) SentShortHeaderPacket(arg0 *logging.ShortHeader, arg1 protocol.ByteCount, arg2 protocol.ECN, arg3 *wire.AckFrame, arg4 []logging.Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentShortHeaderPacket", arg0, arg1, arg2, arg3)
|
||||
m.ctrl.Call(m, "SentShortHeaderPacket", arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// SentShortHeaderPacket indicates an expected call of SentShortHeaderPacket.
|
||||
func (mr *MockConnectionTracerMockRecorder) SentShortHeaderPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) SentShortHeaderPacket(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentShortHeaderPacket), arg0, arg1, arg2, arg3)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentShortHeaderPacket), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// SentTransportParameters mocks base method.
|
||||
|
@ -285,19 +302,19 @@ func (m *MockConnectionTracer) SentTransportParameters(arg0 *wire.TransportParam
|
|||
}
|
||||
|
||||
// SentTransportParameters indicates an expected call of SentTransportParameters.
|
||||
func (mr *MockConnectionTracerMockRecorder) SentTransportParameters(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) SentTransportParameters(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).SentTransportParameters), arg0)
|
||||
}
|
||||
|
||||
// SetLossTimer mocks base method.
|
||||
func (m *MockConnectionTracer) SetLossTimer(arg0 TimerType, arg1 protocol.EncryptionLevel, arg2 time.Time) {
|
||||
func (m *MockConnectionTracer) SetLossTimer(arg0 logging.TimerType, arg1 protocol.EncryptionLevel, arg2 time.Time) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetLossTimer", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// SetLossTimer indicates an expected call of SetLossTimer.
|
||||
func (mr *MockConnectionTracerMockRecorder) SetLossTimer(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) SetLossTimer(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLossTimer", reflect.TypeOf((*MockConnectionTracer)(nil).SetLossTimer), arg0, arg1, arg2)
|
||||
}
|
||||
|
@ -309,19 +326,19 @@ func (m *MockConnectionTracer) StartedConnection(arg0, arg1 net.Addr, arg2, arg3
|
|||
}
|
||||
|
||||
// StartedConnection indicates an expected call of StartedConnection.
|
||||
func (mr *MockConnectionTracerMockRecorder) StartedConnection(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) StartedConnection(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartedConnection", reflect.TypeOf((*MockConnectionTracer)(nil).StartedConnection), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// UpdatedCongestionState mocks base method.
|
||||
func (m *MockConnectionTracer) UpdatedCongestionState(arg0 CongestionState) {
|
||||
func (m *MockConnectionTracer) UpdatedCongestionState(arg0 logging.CongestionState) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "UpdatedCongestionState", arg0)
|
||||
}
|
||||
|
||||
// UpdatedCongestionState indicates an expected call of UpdatedCongestionState.
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedCongestionState(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedCongestionState(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedCongestionState", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedCongestionState), arg0)
|
||||
}
|
||||
|
@ -333,7 +350,7 @@ func (m *MockConnectionTracer) UpdatedKey(arg0 protocol.KeyPhase, arg1 bool) {
|
|||
}
|
||||
|
||||
// UpdatedKey indicates an expected call of UpdatedKey.
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedKey(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedKey(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedKey", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedKey), arg0, arg1)
|
||||
}
|
||||
|
@ -345,7 +362,7 @@ func (m *MockConnectionTracer) UpdatedKeyFromTLS(arg0 protocol.EncryptionLevel,
|
|||
}
|
||||
|
||||
// UpdatedKeyFromTLS indicates an expected call of UpdatedKeyFromTLS.
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedKeyFromTLS(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedKeyFromTLS(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedKeyFromTLS", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedKeyFromTLS), arg0, arg1)
|
||||
}
|
||||
|
@ -357,7 +374,7 @@ func (m *MockConnectionTracer) UpdatedMetrics(arg0 *utils.RTTStats, arg1, arg2 p
|
|||
}
|
||||
|
||||
// UpdatedMetrics indicates an expected call of UpdatedMetrics.
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedMetrics(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedMetrics(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedMetrics", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedMetrics), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
@ -369,7 +386,7 @@ func (m *MockConnectionTracer) UpdatedPTOCount(arg0 uint32) {
|
|||
}
|
||||
|
||||
// UpdatedPTOCount indicates an expected call of UpdatedPTOCount.
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedPTOCount(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnectionTracerMockRecorder) UpdatedPTOCount(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedPTOCount", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedPTOCount), arg0)
|
||||
}
|
|
@ -1,13 +1,18 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/logging (interfaces: Tracer)
|
||||
|
||||
// Package logging is a generated GoMock package.
|
||||
package logging
|
||||
// Source: github.com/refraction-networking/uquic/internal/mocks/logging (interfaces: Tracer)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package internal -destination internal/tracer.go github.com/refraction-networking/uquic/internal/mocks/logging Tracer
|
||||
//
|
||||
// Package internal is a generated GoMock package.
|
||||
package internal
|
||||
|
||||
import (
|
||||
net "net"
|
||||
reflect "reflect"
|
||||
|
||||
logging "github.com/refraction-networking/uquic/logging"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
protocol "github.com/refraction-networking/uquic/internal/protocol"
|
||||
wire "github.com/refraction-networking/uquic/internal/wire"
|
||||
|
@ -37,25 +42,25 @@ func (m *MockTracer) EXPECT() *MockTracerMockRecorder {
|
|||
}
|
||||
|
||||
// DroppedPacket mocks base method.
|
||||
func (m *MockTracer) DroppedPacket(arg0 net.Addr, arg1 PacketType, arg2 protocol.ByteCount, arg3 PacketDropReason) {
|
||||
func (m *MockTracer) DroppedPacket(arg0 net.Addr, arg1 logging.PacketType, arg2 protocol.ByteCount, arg3 logging.PacketDropReason) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "DroppedPacket", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// DroppedPacket indicates an expected call of DroppedPacket.
|
||||
func (mr *MockTracerMockRecorder) DroppedPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
func (mr *MockTracerMockRecorder) DroppedPacket(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockTracer)(nil).DroppedPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentPacket mocks base method.
|
||||
func (m *MockTracer) SentPacket(arg0 net.Addr, arg1 *wire.Header, arg2 protocol.ByteCount, arg3 []Frame) {
|
||||
func (m *MockTracer) SentPacket(arg0 net.Addr, arg1 *wire.Header, arg2 protocol.ByteCount, arg3 []logging.Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentPacket", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentPacket indicates an expected call of SentPacket.
|
||||
func (mr *MockTracerMockRecorder) SentPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
func (mr *MockTracerMockRecorder) SentPacket(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockTracer)(nil).SentPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
@ -67,7 +72,7 @@ func (m *MockTracer) SentVersionNegotiationPacket(arg0 net.Addr, arg1, arg2 prot
|
|||
}
|
||||
|
||||
// SentVersionNegotiationPacket indicates an expected call of SentVersionNegotiationPacket.
|
||||
func (mr *MockTracerMockRecorder) SentVersionNegotiationPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
func (mr *MockTracerMockRecorder) SentVersionNegotiationPacket(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentVersionNegotiationPacket", reflect.TypeOf((*MockTracer)(nil).SentVersionNegotiationPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
51
internal/mocks/logging/mockgen.go
Normal file
51
internal/mocks/logging/mockgen.go
Normal file
|
@ -0,0 +1,51 @@
|
|||
//go:build gomock || generate
|
||||
|
||||
package mocklogging
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/quic-go/quic-go/logging"
|
||||
)
|
||||
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package internal -destination internal/tracer.go github.com/quic-go/quic-go/internal/mocks/logging Tracer"
|
||||
type Tracer interface {
|
||||
SentPacket(net.Addr, *logging.Header, logging.ByteCount, []logging.Frame)
|
||||
SentVersionNegotiationPacket(_ net.Addr, dest, src logging.ArbitraryLenConnectionID, _ []logging.VersionNumber)
|
||||
DroppedPacket(net.Addr, logging.PacketType, logging.ByteCount, logging.PacketDropReason)
|
||||
}
|
||||
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package internal -destination internal/connection_tracer.go github.com/quic-go/quic-go/internal/mocks/logging ConnectionTracer"
|
||||
type ConnectionTracer interface {
|
||||
StartedConnection(local, remote net.Addr, srcConnID, destConnID logging.ConnectionID)
|
||||
NegotiatedVersion(chosen logging.VersionNumber, clientVersions, serverVersions []logging.VersionNumber)
|
||||
ClosedConnection(error)
|
||||
SentTransportParameters(*logging.TransportParameters)
|
||||
ReceivedTransportParameters(*logging.TransportParameters)
|
||||
RestoredTransportParameters(parameters *logging.TransportParameters) // for 0-RTT
|
||||
SentLongHeaderPacket(*logging.ExtendedHeader, logging.ByteCount, logging.ECN, *logging.AckFrame, []logging.Frame)
|
||||
SentShortHeaderPacket(*logging.ShortHeader, logging.ByteCount, logging.ECN, *logging.AckFrame, []logging.Frame)
|
||||
ReceivedVersionNegotiationPacket(dest, src logging.ArbitraryLenConnectionID, _ []logging.VersionNumber)
|
||||
ReceivedRetry(*logging.Header)
|
||||
ReceivedLongHeaderPacket(*logging.ExtendedHeader, logging.ByteCount, logging.ECN, []logging.Frame)
|
||||
ReceivedShortHeaderPacket(*logging.ShortHeader, logging.ByteCount, logging.ECN, []logging.Frame)
|
||||
BufferedPacket(logging.PacketType, logging.ByteCount)
|
||||
DroppedPacket(logging.PacketType, logging.ByteCount, logging.PacketDropReason)
|
||||
UpdatedMetrics(rttStats *logging.RTTStats, cwnd, bytesInFlight logging.ByteCount, packetsInFlight int)
|
||||
AcknowledgedPacket(logging.EncryptionLevel, logging.PacketNumber)
|
||||
LostPacket(logging.EncryptionLevel, logging.PacketNumber, logging.PacketLossReason)
|
||||
UpdatedCongestionState(logging.CongestionState)
|
||||
UpdatedPTOCount(value uint32)
|
||||
UpdatedKeyFromTLS(logging.EncryptionLevel, logging.Perspective)
|
||||
UpdatedKey(generation logging.KeyPhase, remote bool)
|
||||
DroppedEncryptionLevel(logging.EncryptionLevel)
|
||||
DroppedKey(generation logging.KeyPhase)
|
||||
SetLossTimer(logging.TimerType, logging.EncryptionLevel, time.Time)
|
||||
LossTimerExpired(logging.TimerType, logging.EncryptionLevel)
|
||||
LossTimerCanceled()
|
||||
ECNStateUpdated(state logging.ECNState, trigger logging.ECNStateTrigger)
|
||||
// Close is called when the connection is closed.
|
||||
Close()
|
||||
Debug(name, msg string)
|
||||
}
|
|
@ -1,74 +1,29 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/logging (interfaces: Tracer)
|
||||
//go:build !gomock && !generate
|
||||
|
||||
// Package mocklogging is a generated GoMock package.
|
||||
package mocklogging
|
||||
|
||||
import (
|
||||
net "net"
|
||||
reflect "reflect"
|
||||
"net"
|
||||
|
||||
protocol "github.com/refraction-networking/uquic/internal/protocol"
|
||||
wire "github.com/refraction-networking/uquic/internal/wire"
|
||||
logging "github.com/refraction-networking/uquic/logging"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
"github.com/refraction-networking/uquic/internal/mocks/logging/internal"
|
||||
"github.com/refraction-networking/uquic/logging"
|
||||
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockTracer is a mock of Tracer interface.
|
||||
type MockTracer struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockTracerMockRecorder
|
||||
}
|
||||
type MockTracer = internal.MockTracer
|
||||
|
||||
// MockTracerMockRecorder is the mock recorder for MockTracer.
|
||||
type MockTracerMockRecorder struct {
|
||||
mock *MockTracer
|
||||
}
|
||||
|
||||
// NewMockTracer creates a new mock instance.
|
||||
func NewMockTracer(ctrl *gomock.Controller) *MockTracer {
|
||||
mock := &MockTracer{ctrl: ctrl}
|
||||
mock.recorder = &MockTracerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockTracer) EXPECT() *MockTracerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// DroppedPacket mocks base method.
|
||||
func (m *MockTracer) DroppedPacket(arg0 net.Addr, arg1 logging.PacketType, arg2 protocol.ByteCount, arg3 logging.PacketDropReason) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "DroppedPacket", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// DroppedPacket indicates an expected call of DroppedPacket.
|
||||
func (mr *MockTracerMockRecorder) DroppedPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockTracer)(nil).DroppedPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentPacket mocks base method.
|
||||
func (m *MockTracer) SentPacket(arg0 net.Addr, arg1 *wire.Header, arg2 protocol.ByteCount, arg3 []logging.Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentPacket", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentPacket indicates an expected call of SentPacket.
|
||||
func (mr *MockTracerMockRecorder) SentPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockTracer)(nil).SentPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentVersionNegotiationPacket mocks base method.
|
||||
func (m *MockTracer) SentVersionNegotiationPacket(arg0 net.Addr, arg1, arg2 protocol.ArbitraryLenConnectionID, arg3 []protocol.VersionNumber) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentVersionNegotiationPacket", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentVersionNegotiationPacket indicates an expected call of SentVersionNegotiationPacket.
|
||||
func (mr *MockTracerMockRecorder) SentVersionNegotiationPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentVersionNegotiationPacket", reflect.TypeOf((*MockTracer)(nil).SentVersionNegotiationPacket), arg0, arg1, arg2, arg3)
|
||||
func NewMockTracer(ctrl *gomock.Controller) (*logging.Tracer, *MockTracer) {
|
||||
t := internal.NewMockTracer(ctrl)
|
||||
return &logging.Tracer{
|
||||
SentPacket: func(remote net.Addr, hdr *logging.Header, size logging.ByteCount, frames []logging.Frame) {
|
||||
t.SentPacket(remote, hdr, size, frames)
|
||||
},
|
||||
SentVersionNegotiationPacket: func(remote net.Addr, dest, src logging.ArbitraryLenConnectionID, versions []logging.VersionNumber) {
|
||||
t.SentVersionNegotiationPacket(remote, dest, src, versions)
|
||||
},
|
||||
DroppedPacket: func(remote net.Addr, typ logging.PacketType, size logging.ByteCount, reason logging.PacketDropReason) {
|
||||
t.DroppedPacket(remote, typ, size, reason)
|
||||
},
|
||||
}, t
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/internal/handshake (interfaces: LongHeaderOpener)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mocks -destination long_header_opener.go github.com/refraction-networking/uquic/internal/handshake LongHeaderOpener
|
||||
//
|
||||
// Package mocks is a generated GoMock package.
|
||||
package mocks
|
||||
|
||||
|
@ -43,7 +47,7 @@ func (m *MockLongHeaderOpener) DecodePacketNumber(arg0 protocol.PacketNumber, ar
|
|||
}
|
||||
|
||||
// DecodePacketNumber indicates an expected call of DecodePacketNumber.
|
||||
func (mr *MockLongHeaderOpenerMockRecorder) DecodePacketNumber(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockLongHeaderOpenerMockRecorder) DecodePacketNumber(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodePacketNumber", reflect.TypeOf((*MockLongHeaderOpener)(nil).DecodePacketNumber), arg0, arg1)
|
||||
}
|
||||
|
@ -55,7 +59,7 @@ func (m *MockLongHeaderOpener) DecryptHeader(arg0 []byte, arg1 *byte, arg2 []byt
|
|||
}
|
||||
|
||||
// DecryptHeader indicates an expected call of DecryptHeader.
|
||||
func (mr *MockLongHeaderOpenerMockRecorder) DecryptHeader(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockLongHeaderOpenerMockRecorder) DecryptHeader(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptHeader", reflect.TypeOf((*MockLongHeaderOpener)(nil).DecryptHeader), arg0, arg1, arg2)
|
||||
}
|
||||
|
@ -70,7 +74,7 @@ func (m *MockLongHeaderOpener) Open(arg0, arg1 []byte, arg2 protocol.PacketNumbe
|
|||
}
|
||||
|
||||
// Open indicates an expected call of Open.
|
||||
func (mr *MockLongHeaderOpenerMockRecorder) Open(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
func (mr *MockLongHeaderOpenerMockRecorder) Open(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockLongHeaderOpener)(nil).Open), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
//go:build gomock || generate
|
||||
|
||||
package mocks
|
||||
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mockquic -destination quic/stream.go github.com/refraction-networking/uquic Stream"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mockquic -destination quic/early_conn_tmp.go github.com/refraction-networking/uquic EarlyConnection && sed 's/qtls.ConnectionState/quic.ConnectionState/g' quic/early_conn_tmp.go > quic/early_conn.go && rm quic/early_conn_tmp.go && go run golang.org/x/tools/cmd/goimports -w quic/early_conn.go"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocklogging -destination logging/tracer.go github.com/refraction-networking/uquic/logging Tracer"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocklogging -destination logging/connection_tracer.go github.com/refraction-networking/uquic/logging ConnectionTracer"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination short_header_sealer.go github.com/refraction-networking/uquic/internal/handshake ShortHeaderSealer"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination short_header_opener.go github.com/refraction-networking/uquic/internal/handshake ShortHeaderOpener"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination long_header_opener.go github.com/refraction-networking/uquic/internal/handshake LongHeaderOpener"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination crypto_setup_tmp.go github.com/refraction-networking/uquic/internal/handshake CryptoSetup && sed -E 's~github.com/quic-go/qtls[[:alnum:]_-]*~github.com/refraction-networking/uquic/internal/qtls~g; s~qtls.ConnectionStateWith0RTT~qtls.ConnectionState~g' crypto_setup_tmp.go > crypto_setup.go && rm crypto_setup_tmp.go && go run golang.org/x/tools/cmd/goimports -w crypto_setup.go"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination stream_flow_controller.go github.com/refraction-networking/uquic/internal/flowcontrol StreamFlowController"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination congestion.go github.com/refraction-networking/uquic/internal/congestion SendAlgorithmWithDebugInfos"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination connection_flow_controller.go github.com/refraction-networking/uquic/internal/flowcontrol ConnectionFlowController"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mockackhandler -destination ackhandler/sent_packet_handler.go github.com/refraction-networking/uquic/internal/ackhandler SentPacketHandler"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mockackhandler -destination ackhandler/received_packet_handler.go github.com/refraction-networking/uquic/internal/ackhandler ReceivedPacketHandler"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mockquic -destination quic/stream.go github.com/refraction-networking/uquic Stream"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mockquic -destination quic/early_conn_tmp.go github.com/refraction-networking/uquic EarlyConnection && sed 's/qtls.ConnectionState/quic.ConnectionState/g' quic/early_conn_tmp.go > quic/early_conn.go && rm quic/early_conn_tmp.go && go run golang.org/x/tools/cmd/goimports -w quic/early_conn.go"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mocks -destination short_header_sealer.go github.com/refraction-networking/uquic/internal/handshake ShortHeaderSealer"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mocks -destination short_header_opener.go github.com/refraction-networking/uquic/internal/handshake ShortHeaderOpener"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mocks -destination long_header_opener.go github.com/refraction-networking/uquic/internal/handshake LongHeaderOpener"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mocks -destination crypto_setup_tmp.go github.com/refraction-networking/uquic/internal/handshake CryptoSetup && sed -E 's~github.com/quic-go/qtls[[:alnum:]_-]*~github.com/refraction-networking/uquic/internal/qtls~g; s~qtls.ConnectionStateWith0RTT~qtls.ConnectionState~g' crypto_setup_tmp.go > crypto_setup.go && rm crypto_setup_tmp.go && go run golang.org/x/tools/cmd/goimports -w crypto_setup.go"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mocks -destination stream_flow_controller.go github.com/refraction-networking/uquic/internal/flowcontrol StreamFlowController"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mocks -destination congestion.go github.com/refraction-networking/uquic/internal/congestion SendAlgorithmWithDebugInfos"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mocks -destination connection_flow_controller.go github.com/refraction-networking/uquic/internal/flowcontrol ConnectionFlowController"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mockackhandler -destination ackhandler/sent_packet_handler.go github.com/refraction-networking/uquic/internal/ackhandler SentPacketHandler"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mockackhandler -destination ackhandler/received_packet_handler.go github.com/refraction-networking/uquic/internal/ackhandler ReceivedPacketHandler"
|
||||
|
||||
// The following command produces a warning message on OSX, however, it still generates the correct mock file.
|
||||
// See https://github.com/golang/mock/issues/339 for details.
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocktls -destination tls/client_session_cache.go crypto/tls ClientSessionCache"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mocktls -destination tls/client_session_cache.go crypto/tls ClientSessionCache"
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic (interfaces: EarlyConnection)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mockquic -destination quic/early_conn_tmp.go github.com/refraction-networking/uquic EarlyConnection
|
||||
//
|
||||
// Package mockquic is a generated GoMock package.
|
||||
package mockquic
|
||||
|
||||
|
@ -47,7 +51,7 @@ func (m *MockEarlyConnection) AcceptStream(arg0 context.Context) (quic.Stream, e
|
|||
}
|
||||
|
||||
// AcceptStream indicates an expected call of AcceptStream.
|
||||
func (mr *MockEarlyConnectionMockRecorder) AcceptStream(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockEarlyConnectionMockRecorder) AcceptStream(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptStream", reflect.TypeOf((*MockEarlyConnection)(nil).AcceptStream), arg0)
|
||||
}
|
||||
|
@ -62,7 +66,7 @@ func (m *MockEarlyConnection) AcceptUniStream(arg0 context.Context) (quic.Receiv
|
|||
}
|
||||
|
||||
// AcceptUniStream indicates an expected call of AcceptUniStream.
|
||||
func (mr *MockEarlyConnectionMockRecorder) AcceptUniStream(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockEarlyConnectionMockRecorder) AcceptUniStream(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptUniStream", reflect.TypeOf((*MockEarlyConnection)(nil).AcceptUniStream), arg0)
|
||||
}
|
||||
|
@ -76,7 +80,7 @@ func (m *MockEarlyConnection) CloseWithError(arg0 qerr.ApplicationErrorCode, arg
|
|||
}
|
||||
|
||||
// CloseWithError indicates an expected call of CloseWithError.
|
||||
func (mr *MockEarlyConnectionMockRecorder) CloseWithError(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockEarlyConnectionMockRecorder) CloseWithError(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseWithError", reflect.TypeOf((*MockEarlyConnection)(nil).CloseWithError), arg0, arg1)
|
||||
}
|
||||
|
@ -176,7 +180,7 @@ func (m *MockEarlyConnection) OpenStreamSync(arg0 context.Context) (quic.Stream,
|
|||
}
|
||||
|
||||
// OpenStreamSync indicates an expected call of OpenStreamSync.
|
||||
func (mr *MockEarlyConnectionMockRecorder) OpenStreamSync(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockEarlyConnectionMockRecorder) OpenStreamSync(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStreamSync", reflect.TypeOf((*MockEarlyConnection)(nil).OpenStreamSync), arg0)
|
||||
}
|
||||
|
@ -206,7 +210,7 @@ func (m *MockEarlyConnection) OpenUniStreamSync(arg0 context.Context) (quic.Send
|
|||
}
|
||||
|
||||
// OpenUniStreamSync indicates an expected call of OpenUniStreamSync.
|
||||
func (mr *MockEarlyConnectionMockRecorder) OpenUniStreamSync(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockEarlyConnectionMockRecorder) OpenUniStreamSync(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStreamSync", reflect.TypeOf((*MockEarlyConnection)(nil).OpenUniStreamSync), arg0)
|
||||
}
|
||||
|
@ -221,7 +225,7 @@ func (m *MockEarlyConnection) ReceiveMessage(arg0 context.Context) ([]byte, erro
|
|||
}
|
||||
|
||||
// ReceiveMessage indicates an expected call of ReceiveMessage.
|
||||
func (mr *MockEarlyConnectionMockRecorder) ReceiveMessage(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockEarlyConnectionMockRecorder) ReceiveMessage(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveMessage", reflect.TypeOf((*MockEarlyConnection)(nil).ReceiveMessage), arg0)
|
||||
}
|
||||
|
@ -249,7 +253,7 @@ func (m *MockEarlyConnection) SendMessage(arg0 []byte) error {
|
|||
}
|
||||
|
||||
// SendMessage indicates an expected call of SendMessage.
|
||||
func (mr *MockEarlyConnectionMockRecorder) SendMessage(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockEarlyConnectionMockRecorder) SendMessage(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockEarlyConnection)(nil).SendMessage), arg0)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic (interfaces: Stream)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mockquic -destination quic/stream.go github.com/refraction-networking/uquic Stream
|
||||
//
|
||||
// Package mockquic is a generated GoMock package.
|
||||
package mockquic
|
||||
|
||||
|
@ -44,7 +48,7 @@ func (m *MockStream) CancelRead(arg0 qerr.StreamErrorCode) {
|
|||
}
|
||||
|
||||
// CancelRead indicates an expected call of CancelRead.
|
||||
func (mr *MockStreamMockRecorder) CancelRead(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamMockRecorder) CancelRead(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRead", reflect.TypeOf((*MockStream)(nil).CancelRead), arg0)
|
||||
}
|
||||
|
@ -56,7 +60,7 @@ func (m *MockStream) CancelWrite(arg0 qerr.StreamErrorCode) {
|
|||
}
|
||||
|
||||
// CancelWrite indicates an expected call of CancelWrite.
|
||||
func (mr *MockStreamMockRecorder) CancelWrite(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamMockRecorder) CancelWrite(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelWrite", reflect.TypeOf((*MockStream)(nil).CancelWrite), arg0)
|
||||
}
|
||||
|
@ -99,7 +103,7 @@ func (m *MockStream) Read(arg0 []byte) (int, error) {
|
|||
}
|
||||
|
||||
// Read indicates an expected call of Read.
|
||||
func (mr *MockStreamMockRecorder) Read(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamMockRecorder) Read(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStream)(nil).Read), arg0)
|
||||
}
|
||||
|
@ -113,7 +117,7 @@ func (m *MockStream) SetDeadline(arg0 time.Time) error {
|
|||
}
|
||||
|
||||
// SetDeadline indicates an expected call of SetDeadline.
|
||||
func (mr *MockStreamMockRecorder) SetDeadline(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamMockRecorder) SetDeadline(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStream)(nil).SetDeadline), arg0)
|
||||
}
|
||||
|
@ -127,7 +131,7 @@ func (m *MockStream) SetReadDeadline(arg0 time.Time) error {
|
|||
}
|
||||
|
||||
// SetReadDeadline indicates an expected call of SetReadDeadline.
|
||||
func (mr *MockStreamMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamMockRecorder) SetReadDeadline(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStream)(nil).SetReadDeadline), arg0)
|
||||
}
|
||||
|
@ -141,7 +145,7 @@ func (m *MockStream) SetWriteDeadline(arg0 time.Time) error {
|
|||
}
|
||||
|
||||
// SetWriteDeadline indicates an expected call of SetWriteDeadline.
|
||||
func (mr *MockStreamMockRecorder) SetWriteDeadline(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamMockRecorder) SetWriteDeadline(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStream)(nil).SetWriteDeadline), arg0)
|
||||
}
|
||||
|
@ -170,7 +174,7 @@ func (m *MockStream) Write(arg0 []byte) (int, error) {
|
|||
}
|
||||
|
||||
// Write indicates an expected call of Write.
|
||||
func (mr *MockStreamMockRecorder) Write(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamMockRecorder) Write(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStream)(nil).Write), arg0)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/internal/handshake (interfaces: ShortHeaderOpener)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mocks -destination short_header_opener.go github.com/refraction-networking/uquic/internal/handshake ShortHeaderOpener
|
||||
//
|
||||
// Package mocks is a generated GoMock package.
|
||||
package mocks
|
||||
|
||||
|
@ -44,7 +48,7 @@ func (m *MockShortHeaderOpener) DecodePacketNumber(arg0 protocol.PacketNumber, a
|
|||
}
|
||||
|
||||
// DecodePacketNumber indicates an expected call of DecodePacketNumber.
|
||||
func (mr *MockShortHeaderOpenerMockRecorder) DecodePacketNumber(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockShortHeaderOpenerMockRecorder) DecodePacketNumber(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodePacketNumber", reflect.TypeOf((*MockShortHeaderOpener)(nil).DecodePacketNumber), arg0, arg1)
|
||||
}
|
||||
|
@ -56,7 +60,7 @@ func (m *MockShortHeaderOpener) DecryptHeader(arg0 []byte, arg1 *byte, arg2 []by
|
|||
}
|
||||
|
||||
// DecryptHeader indicates an expected call of DecryptHeader.
|
||||
func (mr *MockShortHeaderOpenerMockRecorder) DecryptHeader(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockShortHeaderOpenerMockRecorder) DecryptHeader(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptHeader", reflect.TypeOf((*MockShortHeaderOpener)(nil).DecryptHeader), arg0, arg1, arg2)
|
||||
}
|
||||
|
@ -71,7 +75,7 @@ func (m *MockShortHeaderOpener) Open(arg0, arg1 []byte, arg2 time.Time, arg3 pro
|
|||
}
|
||||
|
||||
// Open indicates an expected call of Open.
|
||||
func (mr *MockShortHeaderOpenerMockRecorder) Open(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
|
||||
func (mr *MockShortHeaderOpenerMockRecorder) Open(arg0, arg1, arg2, arg3, arg4, arg5 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockShortHeaderOpener)(nil).Open), arg0, arg1, arg2, arg3, arg4, arg5)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/internal/handshake (interfaces: ShortHeaderSealer)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mocks -destination short_header_sealer.go github.com/refraction-networking/uquic/internal/handshake ShortHeaderSealer
|
||||
//
|
||||
// Package mocks is a generated GoMock package.
|
||||
package mocks
|
||||
|
||||
|
@ -41,7 +45,7 @@ func (m *MockShortHeaderSealer) EncryptHeader(arg0 []byte, arg1 *byte, arg2 []by
|
|||
}
|
||||
|
||||
// EncryptHeader indicates an expected call of EncryptHeader.
|
||||
func (mr *MockShortHeaderSealerMockRecorder) EncryptHeader(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockShortHeaderSealerMockRecorder) EncryptHeader(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EncryptHeader", reflect.TypeOf((*MockShortHeaderSealer)(nil).EncryptHeader), arg0, arg1, arg2)
|
||||
}
|
||||
|
@ -83,7 +87,7 @@ func (m *MockShortHeaderSealer) Seal(arg0, arg1 []byte, arg2 protocol.PacketNumb
|
|||
}
|
||||
|
||||
// Seal indicates an expected call of Seal.
|
||||
func (mr *MockShortHeaderSealerMockRecorder) Seal(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
func (mr *MockShortHeaderSealerMockRecorder) Seal(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Seal", reflect.TypeOf((*MockShortHeaderSealer)(nil).Seal), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic/internal/flowcontrol (interfaces: StreamFlowController)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mocks -destination stream_flow_controller.go github.com/refraction-networking/uquic/internal/flowcontrol StreamFlowController
|
||||
//
|
||||
// Package mocks is a generated GoMock package.
|
||||
package mocks
|
||||
|
||||
|
@ -53,7 +57,7 @@ func (m *MockStreamFlowController) AddBytesRead(arg0 protocol.ByteCount) {
|
|||
}
|
||||
|
||||
// AddBytesRead indicates an expected call of AddBytesRead.
|
||||
func (mr *MockStreamFlowControllerMockRecorder) AddBytesRead(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamFlowControllerMockRecorder) AddBytesRead(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesRead", reflect.TypeOf((*MockStreamFlowController)(nil).AddBytesRead), arg0)
|
||||
}
|
||||
|
@ -65,7 +69,7 @@ func (m *MockStreamFlowController) AddBytesSent(arg0 protocol.ByteCount) {
|
|||
}
|
||||
|
||||
// AddBytesSent indicates an expected call of AddBytesSent.
|
||||
func (mr *MockStreamFlowControllerMockRecorder) AddBytesSent(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamFlowControllerMockRecorder) AddBytesSent(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesSent", reflect.TypeOf((*MockStreamFlowController)(nil).AddBytesSent), arg0)
|
||||
}
|
||||
|
@ -122,7 +126,7 @@ func (m *MockStreamFlowController) UpdateHighestReceived(arg0 protocol.ByteCount
|
|||
}
|
||||
|
||||
// UpdateHighestReceived indicates an expected call of UpdateHighestReceived.
|
||||
func (mr *MockStreamFlowControllerMockRecorder) UpdateHighestReceived(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamFlowControllerMockRecorder) UpdateHighestReceived(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateHighestReceived", reflect.TypeOf((*MockStreamFlowController)(nil).UpdateHighestReceived), arg0, arg1)
|
||||
}
|
||||
|
@ -134,7 +138,7 @@ func (m *MockStreamFlowController) UpdateSendWindow(arg0 protocol.ByteCount) {
|
|||
}
|
||||
|
||||
// UpdateSendWindow indicates an expected call of UpdateSendWindow.
|
||||
func (mr *MockStreamFlowControllerMockRecorder) UpdateSendWindow(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamFlowControllerMockRecorder) UpdateSendWindow(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSendWindow", reflect.TypeOf((*MockStreamFlowController)(nil).UpdateSendWindow), arg0)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: crypto/tls (interfaces: ClientSessionCache)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package mocktls -destination tls/client_session_cache.go crypto/tls ClientSessionCache
|
||||
//
|
||||
// Package mocktls is a generated GoMock package.
|
||||
package mocktls
|
||||
|
||||
|
@ -44,7 +48,7 @@ func (m *MockClientSessionCache) Get(arg0 string) (*tls.ClientSessionState, bool
|
|||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockClientSessionCacheMockRecorder) Get(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockClientSessionCacheMockRecorder) Get(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClientSessionCache)(nil).Get), arg0)
|
||||
}
|
||||
|
@ -56,7 +60,7 @@ func (m *MockClientSessionCache) Put(arg0 string, arg1 *tls.ClientSessionState)
|
|||
}
|
||||
|
||||
// Put indicates an expected call of Put.
|
||||
func (mr *MockClientSessionCacheMockRecorder) Put(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockClientSessionCacheMockRecorder) Put(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockClientSessionCache)(nil).Put), arg0, arg1)
|
||||
}
|
||||
|
|
|
@ -65,9 +65,6 @@ const MaxAcceptQueueSize = 32
|
|||
// TokenValidity is the duration that a (non-retry) token is considered valid
|
||||
const TokenValidity = 24 * time.Hour
|
||||
|
||||
// RetryTokenValidity is the duration that a retry token is considered valid
|
||||
const RetryTokenValidity = 10 * time.Second
|
||||
|
||||
// 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.
|
||||
|
@ -108,9 +105,6 @@ const DefaultIdleTimeout = 30 * time.Second
|
|||
// DefaultHandshakeIdleTimeout is the default idle timeout used before handshake completion.
|
||||
const DefaultHandshakeIdleTimeout = 5 * time.Second
|
||||
|
||||
// DefaultHandshakeTimeout is the default timeout for a connection until the crypto handshake succeeds.
|
||||
const DefaultHandshakeTimeout = 10 * time.Second
|
||||
|
||||
// MaxKeepAliveInterval is the maximum time until we send a packet to keep a connection alive.
|
||||
// It should be shorter than the time that NATs clear their mapping.
|
||||
const MaxKeepAliveInterval = 20 * time.Second
|
||||
|
|
|
@ -37,14 +37,48 @@ func (t PacketType) String() string {
|
|||
type ECN uint8
|
||||
|
||||
const (
|
||||
ECNNon ECN = iota // 00
|
||||
ECT1 // 01
|
||||
ECT0 // 10
|
||||
ECNCE // 11
|
||||
ECNUnsupported ECN = iota
|
||||
ECNNon // 00
|
||||
ECT1 // 01
|
||||
ECT0 // 10
|
||||
ECNCE // 11
|
||||
)
|
||||
|
||||
func ParseECNHeaderBits(bits byte) ECN {
|
||||
switch bits {
|
||||
case 0:
|
||||
return ECNNon
|
||||
case 0b00000010:
|
||||
return ECT0
|
||||
case 0b00000001:
|
||||
return ECT1
|
||||
case 0b00000011:
|
||||
return ECNCE
|
||||
default:
|
||||
panic("invalid ECN bits")
|
||||
}
|
||||
}
|
||||
|
||||
func (e ECN) ToHeaderBits() byte {
|
||||
//nolint:exhaustive // There are only 4 values.
|
||||
switch e {
|
||||
case ECNNon:
|
||||
return 0
|
||||
case ECT0:
|
||||
return 0b00000010
|
||||
case ECT1:
|
||||
return 0b00000001
|
||||
case ECNCE:
|
||||
return 0b00000011
|
||||
default:
|
||||
panic("ECN unsupported")
|
||||
}
|
||||
}
|
||||
|
||||
func (e ECN) String() string {
|
||||
switch e {
|
||||
case ECNUnsupported:
|
||||
return "ECN unsupported"
|
||||
case ECNNon:
|
||||
return "Not-ECT"
|
||||
case ECT1:
|
||||
|
|
|
@ -17,13 +17,22 @@ var _ = Describe("Protocol", func() {
|
|||
})
|
||||
|
||||
It("converts ECN bits from the IP header wire to the correct types", func() {
|
||||
Expect(ECN(0)).To(Equal(ECNNon))
|
||||
Expect(ECN(0b00000010)).To(Equal(ECT0))
|
||||
Expect(ECN(0b00000001)).To(Equal(ECT1))
|
||||
Expect(ECN(0b00000011)).To(Equal(ECNCE))
|
||||
Expect(ParseECNHeaderBits(0)).To(Equal(ECNNon))
|
||||
Expect(ParseECNHeaderBits(0b00000010)).To(Equal(ECT0))
|
||||
Expect(ParseECNHeaderBits(0b00000001)).To(Equal(ECT1))
|
||||
Expect(ParseECNHeaderBits(0b00000011)).To(Equal(ECNCE))
|
||||
Expect(func() { ParseECNHeaderBits(0b1010101) }).To(Panic())
|
||||
})
|
||||
|
||||
It("converts to IP header bits", func() {
|
||||
for _, v := range [...]ECN{ECNNon, ECT0, ECT1, ECNCE} {
|
||||
Expect(ParseECNHeaderBits(v.ToHeaderBits())).To(Equal(v))
|
||||
}
|
||||
Expect(func() { ECN(42).ToHeaderBits() }).To(Panic())
|
||||
})
|
||||
|
||||
It("has a string representation for ECN", func() {
|
||||
Expect(ECNUnsupported.String()).To(Equal("ECN unsupported"))
|
||||
Expect(ECNNon.String()).To(Equal("Not-ECT"))
|
||||
Expect(ECT0.String()).To(Equal("ECT(0)"))
|
||||
Expect(ECT1.String()).To(Equal("ECT(1)"))
|
||||
|
|
|
@ -55,7 +55,7 @@ func UQUICClient(config *QUICConfig, clientHelloSpec *tls.ClientHelloSpec) *UQUI
|
|||
return uqc
|
||||
}
|
||||
|
||||
func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, accept0RTT func([]byte) bool) {
|
||||
func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, handleSessionTicket func([]byte, bool) bool) {
|
||||
conf := qconf.TLSConfig
|
||||
|
||||
// Workaround for https://github.com/golang/go/issues/60506.
|
||||
|
@ -69,11 +69,9 @@ func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, acce
|
|||
// add callbacks to save transport parameters into the session ticket
|
||||
origWrapSession := conf.WrapSession
|
||||
conf.WrapSession = func(cs tls.ConnectionState, state *tls.SessionState) ([]byte, error) {
|
||||
// Add QUIC transport parameters if this is a 0-RTT packet.
|
||||
// TODO(#3853): also save the RTT for non-0-RTT tickets
|
||||
if state.EarlyData {
|
||||
state.Extra = append(state.Extra, addExtraPrefix(getData()))
|
||||
}
|
||||
// Add QUIC session ticket
|
||||
state.Extra = append(state.Extra, addExtraPrefix(getData()))
|
||||
|
||||
if origWrapSession != nil {
|
||||
return origWrapSession(cs, state)
|
||||
}
|
||||
|
@ -97,14 +95,14 @@ func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, acce
|
|||
if err != nil || state == nil {
|
||||
return nil, err
|
||||
}
|
||||
if state.EarlyData {
|
||||
extra := findExtraData(state.Extra)
|
||||
if unwrapCount == 1 && extra != nil { // first session ticket
|
||||
state.EarlyData = accept0RTT(extra)
|
||||
} else { // subsequent session ticket, can't be used for 0-RTT
|
||||
state.EarlyData = false
|
||||
}
|
||||
|
||||
extra := findExtraData(state.Extra)
|
||||
if extra != nil {
|
||||
state.EarlyData = handleSessionTicket(extra, state.EarlyData && unwrapCount == 1)
|
||||
} else {
|
||||
state.EarlyData = false
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
||||
}
|
||||
|
|
255
logging/connection_tracer.go
Normal file
255
logging/connection_tracer.go
Normal file
|
@ -0,0 +1,255 @@
|
|||
package logging
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// A ConnectionTracer records events.
|
||||
type ConnectionTracer struct {
|
||||
StartedConnection func(local, remote net.Addr, srcConnID, destConnID ConnectionID)
|
||||
NegotiatedVersion func(chosen VersionNumber, clientVersions, serverVersions []VersionNumber)
|
||||
ClosedConnection func(error)
|
||||
SentTransportParameters func(*TransportParameters)
|
||||
ReceivedTransportParameters func(*TransportParameters)
|
||||
RestoredTransportParameters func(parameters *TransportParameters) // for 0-RTT
|
||||
SentLongHeaderPacket func(*ExtendedHeader, ByteCount, ECN, *AckFrame, []Frame)
|
||||
SentShortHeaderPacket func(*ShortHeader, ByteCount, ECN, *AckFrame, []Frame)
|
||||
ReceivedVersionNegotiationPacket func(dest, src ArbitraryLenConnectionID, _ []VersionNumber)
|
||||
ReceivedRetry func(*Header)
|
||||
ReceivedLongHeaderPacket func(*ExtendedHeader, ByteCount, ECN, []Frame)
|
||||
ReceivedShortHeaderPacket func(*ShortHeader, ByteCount, ECN, []Frame)
|
||||
BufferedPacket func(PacketType, ByteCount)
|
||||
DroppedPacket func(PacketType, ByteCount, PacketDropReason)
|
||||
UpdatedMetrics func(rttStats *RTTStats, cwnd, bytesInFlight ByteCount, packetsInFlight int)
|
||||
AcknowledgedPacket func(EncryptionLevel, PacketNumber)
|
||||
LostPacket func(EncryptionLevel, PacketNumber, PacketLossReason)
|
||||
UpdatedCongestionState func(CongestionState)
|
||||
UpdatedPTOCount func(value uint32)
|
||||
UpdatedKeyFromTLS func(EncryptionLevel, Perspective)
|
||||
UpdatedKey func(generation KeyPhase, remote bool)
|
||||
DroppedEncryptionLevel func(EncryptionLevel)
|
||||
DroppedKey func(generation KeyPhase)
|
||||
SetLossTimer func(TimerType, EncryptionLevel, time.Time)
|
||||
LossTimerExpired func(TimerType, EncryptionLevel)
|
||||
LossTimerCanceled func()
|
||||
ECNStateUpdated func(state ECNState, trigger ECNStateTrigger)
|
||||
// Close is called when the connection is closed.
|
||||
Close func()
|
||||
Debug func(name, msg string)
|
||||
}
|
||||
|
||||
// NewMultiplexedConnectionTracer creates a new connection tracer that multiplexes events to multiple tracers.
|
||||
func NewMultiplexedConnectionTracer(tracers ...*ConnectionTracer) *ConnectionTracer {
|
||||
if len(tracers) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(tracers) == 1 {
|
||||
return tracers[0]
|
||||
}
|
||||
return &ConnectionTracer{
|
||||
StartedConnection: func(local, remote net.Addr, srcConnID, destConnID ConnectionID) {
|
||||
for _, t := range tracers {
|
||||
if t.StartedConnection != nil {
|
||||
t.StartedConnection(local, remote, srcConnID, destConnID)
|
||||
}
|
||||
}
|
||||
},
|
||||
NegotiatedVersion: func(chosen VersionNumber, clientVersions, serverVersions []VersionNumber) {
|
||||
for _, t := range tracers {
|
||||
if t.NegotiatedVersion != nil {
|
||||
t.NegotiatedVersion(chosen, clientVersions, serverVersions)
|
||||
}
|
||||
}
|
||||
},
|
||||
ClosedConnection: func(e error) {
|
||||
for _, t := range tracers {
|
||||
if t.ClosedConnection != nil {
|
||||
t.ClosedConnection(e)
|
||||
}
|
||||
}
|
||||
},
|
||||
SentTransportParameters: func(tp *TransportParameters) {
|
||||
for _, t := range tracers {
|
||||
if t.SentTransportParameters != nil {
|
||||
t.SentTransportParameters(tp)
|
||||
}
|
||||
}
|
||||
},
|
||||
ReceivedTransportParameters: func(tp *TransportParameters) {
|
||||
for _, t := range tracers {
|
||||
if t.ReceivedTransportParameters != nil {
|
||||
t.ReceivedTransportParameters(tp)
|
||||
}
|
||||
}
|
||||
},
|
||||
RestoredTransportParameters: func(tp *TransportParameters) {
|
||||
for _, t := range tracers {
|
||||
if t.RestoredTransportParameters != nil {
|
||||
t.RestoredTransportParameters(tp)
|
||||
}
|
||||
}
|
||||
},
|
||||
SentLongHeaderPacket: func(hdr *ExtendedHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame) {
|
||||
for _, t := range tracers {
|
||||
if t.SentLongHeaderPacket != nil {
|
||||
t.SentLongHeaderPacket(hdr, size, ecn, ack, frames)
|
||||
}
|
||||
}
|
||||
},
|
||||
SentShortHeaderPacket: func(hdr *ShortHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame) {
|
||||
for _, t := range tracers {
|
||||
if t.SentShortHeaderPacket != nil {
|
||||
t.SentShortHeaderPacket(hdr, size, ecn, ack, frames)
|
||||
}
|
||||
}
|
||||
},
|
||||
ReceivedVersionNegotiationPacket: func(dest, src ArbitraryLenConnectionID, versions []VersionNumber) {
|
||||
for _, t := range tracers {
|
||||
if t.ReceivedVersionNegotiationPacket != nil {
|
||||
t.ReceivedVersionNegotiationPacket(dest, src, versions)
|
||||
}
|
||||
}
|
||||
},
|
||||
ReceivedRetry: func(hdr *Header) {
|
||||
for _, t := range tracers {
|
||||
if t.ReceivedRetry != nil {
|
||||
t.ReceivedRetry(hdr)
|
||||
}
|
||||
}
|
||||
},
|
||||
ReceivedLongHeaderPacket: func(hdr *ExtendedHeader, size ByteCount, ecn ECN, frames []Frame) {
|
||||
for _, t := range tracers {
|
||||
if t.ReceivedLongHeaderPacket != nil {
|
||||
t.ReceivedLongHeaderPacket(hdr, size, ecn, frames)
|
||||
}
|
||||
}
|
||||
},
|
||||
ReceivedShortHeaderPacket: func(hdr *ShortHeader, size ByteCount, ecn ECN, frames []Frame) {
|
||||
for _, t := range tracers {
|
||||
if t.ReceivedShortHeaderPacket != nil {
|
||||
t.ReceivedShortHeaderPacket(hdr, size, ecn, frames)
|
||||
}
|
||||
}
|
||||
},
|
||||
BufferedPacket: func(typ PacketType, size ByteCount) {
|
||||
for _, t := range tracers {
|
||||
if t.BufferedPacket != nil {
|
||||
t.BufferedPacket(typ, size)
|
||||
}
|
||||
}
|
||||
},
|
||||
DroppedPacket: func(typ PacketType, size ByteCount, reason PacketDropReason) {
|
||||
for _, t := range tracers {
|
||||
if t.DroppedPacket != nil {
|
||||
t.DroppedPacket(typ, size, reason)
|
||||
}
|
||||
}
|
||||
},
|
||||
UpdatedMetrics: func(rttStats *RTTStats, cwnd, bytesInFlight ByteCount, packetsInFlight int) {
|
||||
for _, t := range tracers {
|
||||
if t.UpdatedMetrics != nil {
|
||||
t.UpdatedMetrics(rttStats, cwnd, bytesInFlight, packetsInFlight)
|
||||
}
|
||||
}
|
||||
},
|
||||
AcknowledgedPacket: func(encLevel EncryptionLevel, pn PacketNumber) {
|
||||
for _, t := range tracers {
|
||||
if t.AcknowledgedPacket != nil {
|
||||
t.AcknowledgedPacket(encLevel, pn)
|
||||
}
|
||||
}
|
||||
},
|
||||
LostPacket: func(encLevel EncryptionLevel, pn PacketNumber, reason PacketLossReason) {
|
||||
for _, t := range tracers {
|
||||
if t.LostPacket != nil {
|
||||
t.LostPacket(encLevel, pn, reason)
|
||||
}
|
||||
}
|
||||
},
|
||||
UpdatedCongestionState: func(state CongestionState) {
|
||||
for _, t := range tracers {
|
||||
if t.UpdatedCongestionState != nil {
|
||||
t.UpdatedCongestionState(state)
|
||||
}
|
||||
}
|
||||
},
|
||||
UpdatedPTOCount: func(value uint32) {
|
||||
for _, t := range tracers {
|
||||
if t.UpdatedPTOCount != nil {
|
||||
t.UpdatedPTOCount(value)
|
||||
}
|
||||
}
|
||||
},
|
||||
UpdatedKeyFromTLS: func(encLevel EncryptionLevel, perspective Perspective) {
|
||||
for _, t := range tracers {
|
||||
if t.UpdatedKeyFromTLS != nil {
|
||||
t.UpdatedKeyFromTLS(encLevel, perspective)
|
||||
}
|
||||
}
|
||||
},
|
||||
UpdatedKey: func(generation KeyPhase, remote bool) {
|
||||
for _, t := range tracers {
|
||||
if t.UpdatedKey != nil {
|
||||
t.UpdatedKey(generation, remote)
|
||||
}
|
||||
}
|
||||
},
|
||||
DroppedEncryptionLevel: func(encLevel EncryptionLevel) {
|
||||
for _, t := range tracers {
|
||||
if t.DroppedEncryptionLevel != nil {
|
||||
t.DroppedEncryptionLevel(encLevel)
|
||||
}
|
||||
}
|
||||
},
|
||||
DroppedKey: func(generation KeyPhase) {
|
||||
for _, t := range tracers {
|
||||
if t.DroppedKey != nil {
|
||||
t.DroppedKey(generation)
|
||||
}
|
||||
}
|
||||
},
|
||||
SetLossTimer: func(typ TimerType, encLevel EncryptionLevel, exp time.Time) {
|
||||
for _, t := range tracers {
|
||||
if t.SetLossTimer != nil {
|
||||
t.SetLossTimer(typ, encLevel, exp)
|
||||
}
|
||||
}
|
||||
},
|
||||
LossTimerExpired: func(typ TimerType, encLevel EncryptionLevel) {
|
||||
for _, t := range tracers {
|
||||
if t.LossTimerExpired != nil {
|
||||
t.LossTimerExpired(typ, encLevel)
|
||||
}
|
||||
}
|
||||
},
|
||||
LossTimerCanceled: func() {
|
||||
for _, t := range tracers {
|
||||
if t.LossTimerCanceled != nil {
|
||||
t.LossTimerCanceled()
|
||||
}
|
||||
}
|
||||
},
|
||||
ECNStateUpdated: func(state ECNState, trigger ECNStateTrigger) {
|
||||
for _, t := range tracers {
|
||||
if t.ECNStateUpdated != nil {
|
||||
t.ECNStateUpdated(state, trigger)
|
||||
}
|
||||
}
|
||||
},
|
||||
Close: func() {
|
||||
for _, t := range tracers {
|
||||
if t.Close != nil {
|
||||
t.Close()
|
||||
}
|
||||
}
|
||||
},
|
||||
Debug: func(name, msg string) {
|
||||
for _, t := range tracers {
|
||||
if t.Debug != nil {
|
||||
t.Debug(name, msg)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
|
@ -3,9 +3,6 @@
|
|||
package logging
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/refraction-networking/uquic/internal/protocol"
|
||||
"github.com/refraction-networking/uquic/internal/qerr"
|
||||
"github.com/refraction-networking/uquic/internal/utils"
|
||||
|
@ -15,6 +12,8 @@ import (
|
|||
type (
|
||||
// A ByteCount is used to count bytes.
|
||||
ByteCount = protocol.ByteCount
|
||||
// ECN is the ECN value
|
||||
ECN = protocol.ECN
|
||||
// A ConnectionID is a QUIC Connection ID.
|
||||
ConnectionID = protocol.ConnectionID
|
||||
// An ArbitraryLenConnectionID is a QUIC Connection ID that can be up to 255 bytes long.
|
||||
|
@ -58,6 +57,19 @@ type (
|
|||
RTTStats = utils.RTTStats
|
||||
)
|
||||
|
||||
const (
|
||||
// ECNUnsupported means that no ECN value was set / received
|
||||
ECNUnsupported = protocol.ECNUnsupported
|
||||
// ECTNot is Not-ECT
|
||||
ECTNot = protocol.ECNNon
|
||||
// ECT0 is ECT(0)
|
||||
ECT0 = protocol.ECT0
|
||||
// ECT1 is ECT(1)
|
||||
ECT1 = protocol.ECT1
|
||||
// ECNCE is CE
|
||||
ECNCE = protocol.ECNCE
|
||||
)
|
||||
|
||||
const (
|
||||
// KeyPhaseZero is key phase bit 0
|
||||
KeyPhaseZero KeyPhaseBit = protocol.KeyPhaseZero
|
||||
|
@ -97,43 +109,3 @@ type ShortHeader struct {
|
|||
PacketNumberLen protocol.PacketNumberLen
|
||||
KeyPhase KeyPhaseBit
|
||||
}
|
||||
|
||||
// A Tracer traces events.
|
||||
type Tracer interface {
|
||||
SentPacket(net.Addr, *Header, ByteCount, []Frame)
|
||||
SentVersionNegotiationPacket(_ net.Addr, dest, src ArbitraryLenConnectionID, _ []VersionNumber)
|
||||
DroppedPacket(net.Addr, PacketType, ByteCount, PacketDropReason)
|
||||
}
|
||||
|
||||
// A ConnectionTracer records events.
|
||||
type ConnectionTracer interface {
|
||||
StartedConnection(local, remote net.Addr, srcConnID, destConnID ConnectionID)
|
||||
NegotiatedVersion(chosen VersionNumber, clientVersions, serverVersions []VersionNumber)
|
||||
ClosedConnection(error)
|
||||
SentTransportParameters(*TransportParameters)
|
||||
ReceivedTransportParameters(*TransportParameters)
|
||||
RestoredTransportParameters(parameters *TransportParameters) // for 0-RTT
|
||||
SentLongHeaderPacket(hdr *ExtendedHeader, size ByteCount, ack *AckFrame, frames []Frame)
|
||||
SentShortHeaderPacket(hdr *ShortHeader, size ByteCount, ack *AckFrame, frames []Frame)
|
||||
ReceivedVersionNegotiationPacket(dest, src ArbitraryLenConnectionID, _ []VersionNumber)
|
||||
ReceivedRetry(*Header)
|
||||
ReceivedLongHeaderPacket(hdr *ExtendedHeader, size ByteCount, frames []Frame)
|
||||
ReceivedShortHeaderPacket(hdr *ShortHeader, size ByteCount, frames []Frame)
|
||||
BufferedPacket(PacketType, ByteCount)
|
||||
DroppedPacket(PacketType, ByteCount, PacketDropReason)
|
||||
UpdatedMetrics(rttStats *RTTStats, cwnd, bytesInFlight ByteCount, packetsInFlight int)
|
||||
AcknowledgedPacket(EncryptionLevel, PacketNumber)
|
||||
LostPacket(EncryptionLevel, PacketNumber, PacketLossReason)
|
||||
UpdatedCongestionState(CongestionState)
|
||||
UpdatedPTOCount(value uint32)
|
||||
UpdatedKeyFromTLS(EncryptionLevel, Perspective)
|
||||
UpdatedKey(generation KeyPhase, remote bool)
|
||||
DroppedEncryptionLevel(EncryptionLevel)
|
||||
DroppedKey(generation KeyPhase)
|
||||
SetLossTimer(TimerType, EncryptionLevel, time.Time)
|
||||
LossTimerExpired(TimerType, EncryptionLevel)
|
||||
LossTimerCanceled()
|
||||
// Close is called when the connection is closed.
|
||||
Close()
|
||||
Debug(name, msg string)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package logging
|
||||
package logging_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
package logging
|
||||
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package logging -self_package github.com/refraction-networking/uquic/logging -destination mock_connection_tracer_test.go github.com/refraction-networking/uquic/logging ConnectionTracer"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package logging -self_package github.com/refraction-networking/uquic/logging -destination mock_tracer_test.go github.com/refraction-networking/uquic/logging Tracer"
|
|
@ -1,226 +0,0 @@
|
|||
package logging
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
type tracerMultiplexer struct {
|
||||
tracers []Tracer
|
||||
}
|
||||
|
||||
var _ Tracer = &tracerMultiplexer{}
|
||||
|
||||
// NewMultiplexedTracer creates a new tracer that multiplexes events to multiple tracers.
|
||||
func NewMultiplexedTracer(tracers ...Tracer) Tracer {
|
||||
if len(tracers) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(tracers) == 1 {
|
||||
return tracers[0]
|
||||
}
|
||||
return &tracerMultiplexer{tracers}
|
||||
}
|
||||
|
||||
func (m *tracerMultiplexer) SentPacket(remote net.Addr, hdr *Header, size ByteCount, frames []Frame) {
|
||||
for _, t := range m.tracers {
|
||||
t.SentPacket(remote, hdr, size, frames)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *tracerMultiplexer) SentVersionNegotiationPacket(remote net.Addr, dest, src ArbitraryLenConnectionID, versions []VersionNumber) {
|
||||
for _, t := range m.tracers {
|
||||
t.SentVersionNegotiationPacket(remote, dest, src, versions)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *tracerMultiplexer) DroppedPacket(remote net.Addr, typ PacketType, size ByteCount, reason PacketDropReason) {
|
||||
for _, t := range m.tracers {
|
||||
t.DroppedPacket(remote, typ, size, reason)
|
||||
}
|
||||
}
|
||||
|
||||
type connTracerMultiplexer struct {
|
||||
tracers []ConnectionTracer
|
||||
}
|
||||
|
||||
var _ ConnectionTracer = &connTracerMultiplexer{}
|
||||
|
||||
// NewMultiplexedConnectionTracer creates a new connection tracer that multiplexes events to multiple tracers.
|
||||
func NewMultiplexedConnectionTracer(tracers ...ConnectionTracer) ConnectionTracer {
|
||||
if len(tracers) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(tracers) == 1 {
|
||||
return tracers[0]
|
||||
}
|
||||
return &connTracerMultiplexer{tracers: tracers}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) StartedConnection(local, remote net.Addr, srcConnID, destConnID ConnectionID) {
|
||||
for _, t := range m.tracers {
|
||||
t.StartedConnection(local, remote, srcConnID, destConnID)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) NegotiatedVersion(chosen VersionNumber, clientVersions, serverVersions []VersionNumber) {
|
||||
for _, t := range m.tracers {
|
||||
t.NegotiatedVersion(chosen, clientVersions, serverVersions)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) ClosedConnection(e error) {
|
||||
for _, t := range m.tracers {
|
||||
t.ClosedConnection(e)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) SentTransportParameters(tp *TransportParameters) {
|
||||
for _, t := range m.tracers {
|
||||
t.SentTransportParameters(tp)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) ReceivedTransportParameters(tp *TransportParameters) {
|
||||
for _, t := range m.tracers {
|
||||
t.ReceivedTransportParameters(tp)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) RestoredTransportParameters(tp *TransportParameters) {
|
||||
for _, t := range m.tracers {
|
||||
t.RestoredTransportParameters(tp)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) SentLongHeaderPacket(hdr *ExtendedHeader, size ByteCount, ack *AckFrame, frames []Frame) {
|
||||
for _, t := range m.tracers {
|
||||
t.SentLongHeaderPacket(hdr, size, ack, frames)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) SentShortHeaderPacket(hdr *ShortHeader, size ByteCount, ack *AckFrame, frames []Frame) {
|
||||
for _, t := range m.tracers {
|
||||
t.SentShortHeaderPacket(hdr, size, ack, frames)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) ReceivedVersionNegotiationPacket(dest, src ArbitraryLenConnectionID, versions []VersionNumber) {
|
||||
for _, t := range m.tracers {
|
||||
t.ReceivedVersionNegotiationPacket(dest, src, versions)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) ReceivedRetry(hdr *Header) {
|
||||
for _, t := range m.tracers {
|
||||
t.ReceivedRetry(hdr)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) ReceivedLongHeaderPacket(hdr *ExtendedHeader, size ByteCount, frames []Frame) {
|
||||
for _, t := range m.tracers {
|
||||
t.ReceivedLongHeaderPacket(hdr, size, frames)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) ReceivedShortHeaderPacket(hdr *ShortHeader, size ByteCount, frames []Frame) {
|
||||
for _, t := range m.tracers {
|
||||
t.ReceivedShortHeaderPacket(hdr, size, frames)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) BufferedPacket(typ PacketType, size ByteCount) {
|
||||
for _, t := range m.tracers {
|
||||
t.BufferedPacket(typ, size)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) DroppedPacket(typ PacketType, size ByteCount, reason PacketDropReason) {
|
||||
for _, t := range m.tracers {
|
||||
t.DroppedPacket(typ, size, reason)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) UpdatedCongestionState(state CongestionState) {
|
||||
for _, t := range m.tracers {
|
||||
t.UpdatedCongestionState(state)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) UpdatedMetrics(rttStats *RTTStats, cwnd, bytesInFLight ByteCount, packetsInFlight int) {
|
||||
for _, t := range m.tracers {
|
||||
t.UpdatedMetrics(rttStats, cwnd, bytesInFLight, packetsInFlight)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) AcknowledgedPacket(encLevel EncryptionLevel, pn PacketNumber) {
|
||||
for _, t := range m.tracers {
|
||||
t.AcknowledgedPacket(encLevel, pn)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) LostPacket(encLevel EncryptionLevel, pn PacketNumber, reason PacketLossReason) {
|
||||
for _, t := range m.tracers {
|
||||
t.LostPacket(encLevel, pn, reason)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) UpdatedPTOCount(value uint32) {
|
||||
for _, t := range m.tracers {
|
||||
t.UpdatedPTOCount(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) UpdatedKeyFromTLS(encLevel EncryptionLevel, perspective Perspective) {
|
||||
for _, t := range m.tracers {
|
||||
t.UpdatedKeyFromTLS(encLevel, perspective)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) UpdatedKey(generation KeyPhase, remote bool) {
|
||||
for _, t := range m.tracers {
|
||||
t.UpdatedKey(generation, remote)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) DroppedEncryptionLevel(encLevel EncryptionLevel) {
|
||||
for _, t := range m.tracers {
|
||||
t.DroppedEncryptionLevel(encLevel)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) DroppedKey(generation KeyPhase) {
|
||||
for _, t := range m.tracers {
|
||||
t.DroppedKey(generation)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) SetLossTimer(typ TimerType, encLevel EncryptionLevel, exp time.Time) {
|
||||
for _, t := range m.tracers {
|
||||
t.SetLossTimer(typ, encLevel, exp)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) LossTimerExpired(typ TimerType, encLevel EncryptionLevel) {
|
||||
for _, t := range m.tracers {
|
||||
t.LossTimerExpired(typ, encLevel)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) LossTimerCanceled() {
|
||||
for _, t := range m.tracers {
|
||||
t.LossTimerCanceled()
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) Debug(name, msg string) {
|
||||
for _, t := range m.tracers {
|
||||
t.Debug(name, msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *connTracerMultiplexer) Close() {
|
||||
for _, t := range m.tracers {
|
||||
t.Close()
|
||||
}
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
package logging
|
||||
package logging_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
mocklogging "github.com/refraction-networking/uquic/internal/mocks/logging"
|
||||
"github.com/refraction-networking/uquic/internal/protocol"
|
||||
"github.com/refraction-networking/uquic/internal/wire"
|
||||
. "github.com/refraction-networking/uquic/logging"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
@ -19,21 +21,22 @@ var _ = Describe("Tracing", func() {
|
|||
})
|
||||
|
||||
It("returns the raw tracer if only one tracer is passed in", func() {
|
||||
tr := NewMockTracer(mockCtrl)
|
||||
tr := &Tracer{}
|
||||
tracer := NewMultiplexedTracer(tr)
|
||||
Expect(tracer).To(BeAssignableToTypeOf(&MockTracer{}))
|
||||
Expect(tracer).To(Equal(tr))
|
||||
})
|
||||
|
||||
Context("tracing events", func() {
|
||||
var (
|
||||
tracer Tracer
|
||||
tr1, tr2 *MockTracer
|
||||
tracer *Tracer
|
||||
tr1, tr2 *mocklogging.MockTracer
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
tr1 = NewMockTracer(mockCtrl)
|
||||
tr2 = NewMockTracer(mockCtrl)
|
||||
tracer = NewMultiplexedTracer(tr1, tr2)
|
||||
var t1, t2 *Tracer
|
||||
t1, tr1 = mocklogging.NewMockTracer(mockCtrl)
|
||||
t2, tr2 = mocklogging.NewMockTracer(mockCtrl)
|
||||
tracer = NewMultiplexedTracer(t1, t2, &Tracer{})
|
||||
})
|
||||
|
||||
It("traces the PacketSent event", func() {
|
||||
|
@ -66,18 +69,19 @@ var _ = Describe("Tracing", func() {
|
|||
|
||||
Context("Connection Tracer", func() {
|
||||
var (
|
||||
tracer ConnectionTracer
|
||||
tr1 *MockConnectionTracer
|
||||
tr2 *MockConnectionTracer
|
||||
tracer *ConnectionTracer
|
||||
tr1 *mocklogging.MockConnectionTracer
|
||||
tr2 *mocklogging.MockConnectionTracer
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
tr1 = NewMockConnectionTracer(mockCtrl)
|
||||
tr2 = NewMockConnectionTracer(mockCtrl)
|
||||
tracer = NewMultiplexedConnectionTracer(tr1, tr2)
|
||||
var t1, t2 *ConnectionTracer
|
||||
t1, tr1 = mocklogging.NewMockConnectionTracer(mockCtrl)
|
||||
t2, tr2 = mocklogging.NewMockConnectionTracer(mockCtrl)
|
||||
tracer = NewMultiplexedConnectionTracer(t1, t2)
|
||||
})
|
||||
|
||||
It("trace the ConnectionStarted event", func() {
|
||||
It("traces the StartedConnection event", func() {
|
||||
local := &net.UDPAddr{IP: net.IPv4(1, 2, 3, 4)}
|
||||
remote := &net.UDPAddr{IP: net.IPv4(4, 3, 2, 1)}
|
||||
dest := protocol.ParseConnectionID([]byte{1, 2, 3, 4})
|
||||
|
@ -87,6 +91,15 @@ var _ = Describe("Tracing", func() {
|
|||
tracer.StartedConnection(local, remote, src, dest)
|
||||
})
|
||||
|
||||
It("traces the NegotiatedVersion event", func() {
|
||||
chosen := protocol.Version2
|
||||
client := []protocol.VersionNumber{protocol.Version1}
|
||||
server := []protocol.VersionNumber{13, 37}
|
||||
tr1.EXPECT().NegotiatedVersion(chosen, client, server)
|
||||
tr2.EXPECT().NegotiatedVersion(chosen, client, server)
|
||||
tracer.NegotiatedVersion(chosen, client, server)
|
||||
})
|
||||
|
||||
It("traces the ClosedConnection event", func() {
|
||||
e := errors.New("test err")
|
||||
tr1.EXPECT().ClosedConnection(e)
|
||||
|
@ -119,18 +132,18 @@ var _ = Describe("Tracing", func() {
|
|||
hdr := &ExtendedHeader{Header: Header{DestConnectionID: protocol.ParseConnectionID([]byte{1, 2, 3})}}
|
||||
ack := &AckFrame{AckRanges: []AckRange{{Smallest: 1, Largest: 10}}}
|
||||
ping := &PingFrame{}
|
||||
tr1.EXPECT().SentLongHeaderPacket(hdr, ByteCount(1337), ack, []Frame{ping})
|
||||
tr2.EXPECT().SentLongHeaderPacket(hdr, ByteCount(1337), ack, []Frame{ping})
|
||||
tracer.SentLongHeaderPacket(hdr, 1337, ack, []Frame{ping})
|
||||
tr1.EXPECT().SentLongHeaderPacket(hdr, ByteCount(1337), ECTNot, ack, []Frame{ping})
|
||||
tr2.EXPECT().SentLongHeaderPacket(hdr, ByteCount(1337), ECTNot, ack, []Frame{ping})
|
||||
tracer.SentLongHeaderPacket(hdr, 1337, ECTNot, ack, []Frame{ping})
|
||||
})
|
||||
|
||||
It("traces the SentShortHeaderPacket event", func() {
|
||||
hdr := &ShortHeader{DestConnectionID: protocol.ParseConnectionID([]byte{1, 2, 3})}
|
||||
ack := &AckFrame{AckRanges: []AckRange{{Smallest: 1, Largest: 10}}}
|
||||
ping := &PingFrame{}
|
||||
tr1.EXPECT().SentShortHeaderPacket(hdr, ByteCount(1337), ack, []Frame{ping})
|
||||
tr2.EXPECT().SentShortHeaderPacket(hdr, ByteCount(1337), ack, []Frame{ping})
|
||||
tracer.SentShortHeaderPacket(hdr, 1337, ack, []Frame{ping})
|
||||
tr1.EXPECT().SentShortHeaderPacket(hdr, ByteCount(1337), ECNCE, ack, []Frame{ping})
|
||||
tr2.EXPECT().SentShortHeaderPacket(hdr, ByteCount(1337), ECNCE, ack, []Frame{ping})
|
||||
tracer.SentShortHeaderPacket(hdr, 1337, ECNCE, ack, []Frame{ping})
|
||||
})
|
||||
|
||||
It("traces the ReceivedVersionNegotiationPacket event", func() {
|
||||
|
@ -151,17 +164,17 @@ var _ = Describe("Tracing", func() {
|
|||
It("traces the ReceivedLongHeaderPacket event", func() {
|
||||
hdr := &ExtendedHeader{Header: Header{DestConnectionID: protocol.ParseConnectionID([]byte{1, 2, 3})}}
|
||||
ping := &PingFrame{}
|
||||
tr1.EXPECT().ReceivedLongHeaderPacket(hdr, ByteCount(1337), []Frame{ping})
|
||||
tr2.EXPECT().ReceivedLongHeaderPacket(hdr, ByteCount(1337), []Frame{ping})
|
||||
tracer.ReceivedLongHeaderPacket(hdr, 1337, []Frame{ping})
|
||||
tr1.EXPECT().ReceivedLongHeaderPacket(hdr, ByteCount(1337), ECT1, []Frame{ping})
|
||||
tr2.EXPECT().ReceivedLongHeaderPacket(hdr, ByteCount(1337), ECT1, []Frame{ping})
|
||||
tracer.ReceivedLongHeaderPacket(hdr, 1337, ECT1, []Frame{ping})
|
||||
})
|
||||
|
||||
It("traces the ReceivedShortHeaderPacket event", func() {
|
||||
hdr := &ShortHeader{DestConnectionID: protocol.ParseConnectionID([]byte{1, 2, 3})}
|
||||
ping := &PingFrame{}
|
||||
tr1.EXPECT().ReceivedShortHeaderPacket(hdr, ByteCount(1337), []Frame{ping})
|
||||
tr2.EXPECT().ReceivedShortHeaderPacket(hdr, ByteCount(1337), []Frame{ping})
|
||||
tracer.ReceivedShortHeaderPacket(hdr, 1337, []Frame{ping})
|
||||
tr1.EXPECT().ReceivedShortHeaderPacket(hdr, ByteCount(1337), ECT0, []Frame{ping})
|
||||
tr2.EXPECT().ReceivedShortHeaderPacket(hdr, ByteCount(1337), ECT0, []Frame{ping})
|
||||
tracer.ReceivedShortHeaderPacket(hdr, 1337, ECT0, []Frame{ping})
|
||||
})
|
||||
|
||||
It("traces the BufferedPacket event", func() {
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
package logging
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// The NullTracer is a Tracer that does nothing.
|
||||
// It is useful for embedding.
|
||||
type NullTracer struct{}
|
||||
|
||||
var _ Tracer = &NullTracer{}
|
||||
|
||||
func (n NullTracer) SentPacket(net.Addr, *Header, ByteCount, []Frame) {}
|
||||
func (n NullTracer) SentVersionNegotiationPacket(_ net.Addr, dest, src ArbitraryLenConnectionID, _ []VersionNumber) {
|
||||
}
|
||||
func (n NullTracer) DroppedPacket(net.Addr, PacketType, ByteCount, PacketDropReason) {}
|
||||
|
||||
// The NullConnectionTracer is a ConnectionTracer that does nothing.
|
||||
// It is useful for embedding.
|
||||
type NullConnectionTracer struct{}
|
||||
|
||||
var _ ConnectionTracer = &NullConnectionTracer{}
|
||||
|
||||
func (n NullConnectionTracer) StartedConnection(local, remote net.Addr, srcConnID, destConnID ConnectionID) {
|
||||
}
|
||||
|
||||
func (n NullConnectionTracer) NegotiatedVersion(chosen VersionNumber, clientVersions, serverVersions []VersionNumber) {
|
||||
}
|
||||
func (n NullConnectionTracer) ClosedConnection(err error) {}
|
||||
func (n NullConnectionTracer) SentTransportParameters(*TransportParameters) {}
|
||||
func (n NullConnectionTracer) ReceivedTransportParameters(*TransportParameters) {}
|
||||
func (n NullConnectionTracer) RestoredTransportParameters(*TransportParameters) {}
|
||||
func (n NullConnectionTracer) SentLongHeaderPacket(*ExtendedHeader, ByteCount, *AckFrame, []Frame) {}
|
||||
func (n NullConnectionTracer) SentShortHeaderPacket(*ShortHeader, ByteCount, *AckFrame, []Frame) {}
|
||||
func (n NullConnectionTracer) ReceivedVersionNegotiationPacket(dest, src ArbitraryLenConnectionID, _ []VersionNumber) {
|
||||
}
|
||||
func (n NullConnectionTracer) ReceivedRetry(*Header) {}
|
||||
func (n NullConnectionTracer) ReceivedLongHeaderPacket(*ExtendedHeader, ByteCount, []Frame) {}
|
||||
func (n NullConnectionTracer) ReceivedShortHeaderPacket(*ShortHeader, ByteCount, []Frame) {}
|
||||
func (n NullConnectionTracer) BufferedPacket(PacketType, ByteCount) {}
|
||||
func (n NullConnectionTracer) DroppedPacket(PacketType, ByteCount, PacketDropReason) {}
|
||||
|
||||
func (n NullConnectionTracer) UpdatedMetrics(rttStats *RTTStats, cwnd, bytesInFlight ByteCount, packetsInFlight int) {
|
||||
}
|
||||
func (n NullConnectionTracer) AcknowledgedPacket(EncryptionLevel, PacketNumber) {}
|
||||
func (n NullConnectionTracer) LostPacket(EncryptionLevel, PacketNumber, PacketLossReason) {}
|
||||
func (n NullConnectionTracer) UpdatedCongestionState(CongestionState) {}
|
||||
func (n NullConnectionTracer) UpdatedPTOCount(uint32) {}
|
||||
func (n NullConnectionTracer) UpdatedKeyFromTLS(EncryptionLevel, Perspective) {}
|
||||
func (n NullConnectionTracer) UpdatedKey(keyPhase KeyPhase, remote bool) {}
|
||||
func (n NullConnectionTracer) DroppedEncryptionLevel(EncryptionLevel) {}
|
||||
func (n NullConnectionTracer) DroppedKey(KeyPhase) {}
|
||||
func (n NullConnectionTracer) SetLossTimer(TimerType, EncryptionLevel, time.Time) {}
|
||||
func (n NullConnectionTracer) LossTimerExpired(timerType TimerType, level EncryptionLevel) {}
|
||||
func (n NullConnectionTracer) LossTimerCanceled() {}
|
||||
func (n NullConnectionTracer) Close() {}
|
||||
func (n NullConnectionTracer) Debug(name, msg string) {}
|
|
@ -1,8 +1,9 @@
|
|||
package logging
|
||||
package logging_test
|
||||
|
||||
import (
|
||||
"github.com/refraction-networking/uquic/internal/protocol"
|
||||
"github.com/refraction-networking/uquic/internal/wire"
|
||||
. "github.com/refraction-networking/uquic/logging"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
|
43
logging/tracer.go
Normal file
43
logging/tracer.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package logging
|
||||
|
||||
import "net"
|
||||
|
||||
// A Tracer traces events.
|
||||
type Tracer struct {
|
||||
SentPacket func(net.Addr, *Header, ByteCount, []Frame)
|
||||
SentVersionNegotiationPacket func(_ net.Addr, dest, src ArbitraryLenConnectionID, _ []VersionNumber)
|
||||
DroppedPacket func(net.Addr, PacketType, ByteCount, PacketDropReason)
|
||||
}
|
||||
|
||||
// NewMultiplexedTracer creates a new tracer that multiplexes events to multiple tracers.
|
||||
func NewMultiplexedTracer(tracers ...*Tracer) *Tracer {
|
||||
if len(tracers) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(tracers) == 1 {
|
||||
return tracers[0]
|
||||
}
|
||||
return &Tracer{
|
||||
SentPacket: func(remote net.Addr, hdr *Header, size ByteCount, frames []Frame) {
|
||||
for _, t := range tracers {
|
||||
if t.SentPacket != nil {
|
||||
t.SentPacket(remote, hdr, size, frames)
|
||||
}
|
||||
}
|
||||
},
|
||||
SentVersionNegotiationPacket: func(remote net.Addr, dest, src ArbitraryLenConnectionID, versions []VersionNumber) {
|
||||
for _, t := range tracers {
|
||||
if t.SentVersionNegotiationPacket != nil {
|
||||
t.SentVersionNegotiationPacket(remote, dest, src, versions)
|
||||
}
|
||||
}
|
||||
},
|
||||
DroppedPacket: func(remote net.Addr, typ PacketType, size ByteCount, reason PacketDropReason) {
|
||||
for _, t := range tracers {
|
||||
if t.DroppedPacket != nil {
|
||||
t.DroppedPacket(remote, typ, size, reason)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
|
@ -92,3 +92,37 @@ const (
|
|||
// CongestionStateApplicationLimited means that the congestion controller is application limited
|
||||
CongestionStateApplicationLimited
|
||||
)
|
||||
|
||||
// ECNState is the state of the ECN state machine (see Appendix A.4 of RFC 9000)
|
||||
type ECNState uint8
|
||||
|
||||
const (
|
||||
// ECNStateTesting is the testing state
|
||||
ECNStateTesting ECNState = 1 + iota
|
||||
// ECNStateUnknown is the unknown state
|
||||
ECNStateUnknown
|
||||
// ECNStateFailed is the failed state
|
||||
ECNStateFailed
|
||||
// ECNStateCapable is the capable state
|
||||
ECNStateCapable
|
||||
)
|
||||
|
||||
// ECNStateTrigger is a trigger for an ECN state transition.
|
||||
type ECNStateTrigger uint8
|
||||
|
||||
const (
|
||||
ECNTriggerNoTrigger ECNStateTrigger = iota
|
||||
// ECNFailedNoECNCounts is emitted when an ACK acknowledges ECN-marked packets,
|
||||
// but doesn't contain any ECN counts
|
||||
ECNFailedNoECNCounts
|
||||
// ECNFailedDecreasedECNCounts is emitted when an ACK frame decreases ECN counts
|
||||
ECNFailedDecreasedECNCounts
|
||||
// ECNFailedLostAllTestingPackets is emitted when all ECN testing packets are declared lost
|
||||
ECNFailedLostAllTestingPackets
|
||||
// ECNFailedMoreECNCountsThanSent is emitted when an ACK contains more ECN counts than ECN-marked packets were sent
|
||||
ECNFailedMoreECNCountsThanSent
|
||||
// ECNFailedTooFewECNCounts is emitted when an ACK contains fewer ECN counts than it acknowledges packets
|
||||
ECNFailedTooFewECNCounts
|
||||
// ECNFailedManglingDetected is emitted when the path marks all ECN-marked packets as CE
|
||||
ECNFailedManglingDetected
|
||||
)
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/refraction-networking/uquic (interfaces: AckFrameSource)
|
||||
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/refraction-networking/uquic -destination mock_ack_frame_source_test.go github.com/refraction-networking/uquic AckFrameSource
|
||||
//
|
||||
// Package quic is a generated GoMock package.
|
||||
package quic
|
||||
|
||||
|
@ -44,7 +48,7 @@ func (m *MockAckFrameSource) GetAckFrame(arg0 protocol.EncryptionLevel, arg1 boo
|
|||
}
|
||||
|
||||
// GetAckFrame indicates an expected call of GetAckFrame.
|
||||
func (mr *MockAckFrameSourceMockRecorder) GetAckFrame(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockAckFrameSourceMockRecorder) GetAckFrame(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAckFrame", reflect.TypeOf((*MockAckFrameSource)(nil).GetAckFrame), arg0, arg1)
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue