From 1c47ebefc0660eb82bada449a5365e2aedd1e686 Mon Sep 17 00:00:00 2001 From: Ameagari <47713057+tanghaowillow@users.noreply.github.com> Date: Wed, 2 Aug 2023 09:34:42 +0800 Subject: [PATCH 001/225] check transport parameters after 0-RTT resumption (#3985) * check new transport parameters do not contain redueced limits * redefine ValidForUpdate and add tests * fix test assertion and update comment --- connection.go | 8 +++ connection_test.go | 34 +++++++++ internal/wire/transport_parameter_test.go | 88 +++++++++++++++++++++++ internal/wire/transport_parameters.go | 12 ++++ 4 files changed, 142 insertions(+) diff --git a/connection.go b/connection.go index eede6929e02..fdf40d196ce 100644 --- a/connection.go +++ b/connection.go @@ -1665,6 +1665,14 @@ func (s *connection) handleTransportParameters(params *wire.TransportParameters) ErrorMessage: err.Error(), } } + + if s.perspective == protocol.PerspectiveClient && s.peerParams != nil && s.ConnectionState().Used0RTT && !params.ValidForUpdate(s.peerParams) { + return &qerr.TransportError{ + ErrorCode: qerr.ProtocolViolation, + ErrorMessage: "server sent reduced limits after accepting 0-RTT data", + } + } + s.peerParams = params // On the client side we have to wait for handshake completion. // During a 0-RTT connection, we are only allowed to use the new transport parameters for 1-RTT packets. diff --git a/connection_test.go b/connection_test.go index 20e9872b4bf..c3c5d2c5006 100644 --- a/connection_test.go +++ b/connection_test.go @@ -3035,6 +3035,40 @@ var _ = Describe("Client Connection", func() { ErrorMessage: "expected original_destination_connection_id to equal deadbeef, is decafbad", }))) }) + + It("errors if the transport parameters contain reduced limits after knowing 0-RTT data is accepted by the server", func() { + conn.perspective = protocol.PerspectiveClient + conn.peerParams = &wire.TransportParameters{ + ActiveConnectionIDLimit: 3, + InitialMaxData: 0x5000, + InitialMaxStreamDataBidiLocal: 0x5000, + InitialMaxStreamDataBidiRemote: 1000, + InitialMaxStreamDataUni: 1000, + MaxBidiStreamNum: 500, + MaxUniStreamNum: 500, + } + params := &wire.TransportParameters{ + OriginalDestinationConnectionID: destConnID, + InitialSourceConnectionID: destConnID, + ActiveConnectionIDLimit: 3, + InitialMaxData: 0x5000, + InitialMaxStreamDataBidiLocal: 0x5000, + InitialMaxStreamDataBidiRemote: 1000, + InitialMaxStreamDataUni: 1000, + MaxBidiStreamNum: 300, + MaxUniStreamNum: 300, + } + expectClose(false, true) + processed := make(chan struct{}) + tracer.EXPECT().ReceivedTransportParameters(params).Do(func(*wire.TransportParameters) { close(processed) }) + cryptoSetup.EXPECT().ConnectionState().Return(handshake.ConnectionState{Used0RTT: true}) + paramsChan <- params + Eventually(processed).Should(BeClosed()) + Eventually(errChan).Should(Receive(MatchError(&qerr.TransportError{ + ErrorCode: qerr.ProtocolViolation, + ErrorMessage: "server sent reduced limits after accepting 0-RTT data", + }))) + }) }) Context("handling potentially injected packets", func() { diff --git a/internal/wire/transport_parameter_test.go b/internal/wire/transport_parameter_test.go index 95bfbafc70b..9dd306b76ab 100644 --- a/internal/wire/transport_parameter_test.go +++ b/internal/wire/transport_parameter_test.go @@ -612,5 +612,93 @@ var _ = Describe("Transport Parameters", func() { Expect(p.ValidFor0RTT(saved)).To(BeFalse()) }) }) + + Context("client checks the parameters after successfully sending 0-RTT data", func() { + var p TransportParameters + saved := &TransportParameters{ + InitialMaxStreamDataBidiLocal: 1, + InitialMaxStreamDataBidiRemote: 2, + InitialMaxStreamDataUni: 3, + InitialMaxData: 4, + MaxBidiStreamNum: 5, + MaxUniStreamNum: 6, + ActiveConnectionIDLimit: 7, + } + + BeforeEach(func() { + p = *saved + Expect(p.ValidForUpdate(saved)).To(BeTrue()) + }) + + It("rejects the parameters if the InitialMaxStreamDataBidiLocal was reduced", func() { + p.InitialMaxStreamDataBidiLocal = saved.InitialMaxStreamDataBidiLocal - 1 + Expect(p.ValidForUpdate(saved)).To(BeFalse()) + }) + + It("doesn't reject the parameters if the InitialMaxStreamDataBidiLocal was increased", func() { + p.InitialMaxStreamDataBidiLocal = saved.InitialMaxStreamDataBidiLocal + 1 + Expect(p.ValidForUpdate(saved)).To(BeTrue()) + }) + + It("rejects the parameters if the InitialMaxStreamDataBidiRemote was reduced", func() { + p.InitialMaxStreamDataBidiRemote = saved.InitialMaxStreamDataBidiRemote - 1 + Expect(p.ValidForUpdate(saved)).To(BeFalse()) + }) + + It("doesn't reject the parameters if the InitialMaxStreamDataBidiRemote was increased", func() { + p.InitialMaxStreamDataBidiRemote = saved.InitialMaxStreamDataBidiRemote + 1 + Expect(p.ValidForUpdate(saved)).To(BeTrue()) + }) + + It("rejects the parameters if the InitialMaxStreamDataUni was reduced", func() { + p.InitialMaxStreamDataUni = saved.InitialMaxStreamDataUni - 1 + Expect(p.ValidForUpdate(saved)).To(BeFalse()) + }) + + It("doesn't reject the parameters if the InitialMaxStreamDataUni was increased", func() { + p.InitialMaxStreamDataUni = saved.InitialMaxStreamDataUni + 1 + Expect(p.ValidForUpdate(saved)).To(BeTrue()) + }) + + It("rejects the parameters if the InitialMaxData was reduced", func() { + p.InitialMaxData = saved.InitialMaxData - 1 + Expect(p.ValidForUpdate(saved)).To(BeFalse()) + }) + + It("doesn't reject the parameters if the InitialMaxData was increased", func() { + p.InitialMaxData = saved.InitialMaxData + 1 + Expect(p.ValidForUpdate(saved)).To(BeTrue()) + }) + + It("rejects the parameters if the MaxBidiStreamNum was reduced", func() { + p.MaxBidiStreamNum = saved.MaxBidiStreamNum - 1 + Expect(p.ValidForUpdate(saved)).To(BeFalse()) + }) + + It("doesn't reject the parameters if the MaxBidiStreamNum was increased", func() { + p.MaxBidiStreamNum = saved.MaxBidiStreamNum + 1 + Expect(p.ValidForUpdate(saved)).To(BeTrue()) + }) + + It("rejects the parameters if the MaxUniStreamNum reduced", func() { + p.MaxUniStreamNum = saved.MaxUniStreamNum - 1 + Expect(p.ValidForUpdate(saved)).To(BeFalse()) + }) + + It("doesn't reject the parameters if the MaxUniStreamNum was increased", func() { + p.MaxUniStreamNum = saved.MaxUniStreamNum + 1 + Expect(p.ValidForUpdate(saved)).To(BeTrue()) + }) + + It("rejects the parameters if the ActiveConnectionIDLimit reduced", func() { + p.ActiveConnectionIDLimit = saved.ActiveConnectionIDLimit - 1 + Expect(p.ValidForUpdate(saved)).To(BeFalse()) + }) + + It("doesn't reject the parameters if the ActiveConnectionIDLimit increased", func() { + p.ActiveConnectionIDLimit = saved.ActiveConnectionIDLimit + 1 + Expect(p.ValidForUpdate(saved)).To(BeTrue()) + }) + }) }) }) diff --git a/internal/wire/transport_parameters.go b/internal/wire/transport_parameters.go index 1ec1e59d3a3..dc0aa22f133 100644 --- a/internal/wire/transport_parameters.go +++ b/internal/wire/transport_parameters.go @@ -481,6 +481,18 @@ func (p *TransportParameters) ValidFor0RTT(saved *TransportParameters) bool { p.ActiveConnectionIDLimit == saved.ActiveConnectionIDLimit } +// ValidForUpdate checks that the new transport parameters don't reduce limits after resuming a 0-RTT connection. +// It is only used on the client side. +func (p *TransportParameters) ValidForUpdate(saved *TransportParameters) bool { + return p.ActiveConnectionIDLimit >= saved.ActiveConnectionIDLimit && + p.InitialMaxData >= saved.InitialMaxData && + p.InitialMaxStreamDataBidiLocal >= saved.InitialMaxStreamDataBidiLocal && + p.InitialMaxStreamDataBidiRemote >= saved.InitialMaxStreamDataBidiRemote && + p.InitialMaxStreamDataUni >= saved.InitialMaxStreamDataUni && + p.MaxBidiStreamNum >= saved.MaxBidiStreamNum && + p.MaxUniStreamNum >= saved.MaxUniStreamNum +} + // String returns a string representation, intended for logging. func (p *TransportParameters) String() string { logString := "&wire.TransportParameters{OriginalDestinationConnectionID: %s, InitialSourceConnectionID: %s, " From f9f6b9df6ec6769ec6bb7d4fd0b29177cbc2bf55 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 3 Aug 2023 11:20:32 -0400 Subject: [PATCH 002/225] update qtls to restrict RSA keys in certificates to <= 8192 bits (#4012) --- go.mod | 2 +- go.sum | 4 ++-- integrationtests/gomodvendor/go.sum | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 53612c67a9a..2f2a0ff0b62 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/onsi/ginkgo/v2 v2.9.5 github.com/onsi/gomega v1.27.6 github.com/quic-go/qpack v0.4.0 - github.com/quic-go/qtls-go1-20 v0.3.0 + github.com/quic-go/qtls-go1-20 v0.3.1 golang.org/x/crypto v0.4.0 golang.org/x/exp v0.0.0-20221205204356-47842c84f3db golang.org/x/net v0.10.0 diff --git a/go.sum b/go.sum index 4039bb0778e..c0ed9606da1 100644 --- a/go.sum +++ b/go.sum @@ -90,8 +90,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.0 h1:NrCXmDl8BddZwO67vlvEpBTwT89bJfKYygxv4HQvuDk= -github.com/quic-go/qtls-go1-20 v0.3.0/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= +github.com/quic-go/qtls-go1-20 v0.3.1/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= diff --git a/integrationtests/gomodvendor/go.sum b/integrationtests/gomodvendor/go.sum index 1336cd7c46a..ad9adb3117c 100644 --- a/integrationtests/gomodvendor/go.sum +++ b/integrationtests/gomodvendor/go.sum @@ -136,8 +136,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.0 h1:NrCXmDl8BddZwO67vlvEpBTwT89bJfKYygxv4HQvuDk= -github.com/quic-go/qtls-go1-20 v0.3.0/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= +github.com/quic-go/qtls-go1-20 v0.3.1/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= From 18d3846d4f96f24f62bd8af2339fb860bb420be6 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 3 Aug 2023 20:33:19 -0400 Subject: [PATCH 003/225] set a net.Conn for tls.ClientHelloInfo.Conn used by GetCertificate (#4014) --- integrationtests/self/handshake_test.go | 26 ++++++++++++++++++++++++- internal/handshake/crypto_setup.go | 7 +++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/integrationtests/self/handshake_test.go b/integrationtests/self/handshake_test.go index 9652cb0d369..f23ae77cc9e 100644 --- a/integrationtests/self/handshake_test.go +++ b/integrationtests/self/handshake_test.go @@ -140,7 +140,7 @@ var _ = Describe("Handshake tests", func() { Expect(err).ToNot(HaveOccurred()) }) - It("has the right local and remote address on the ClientHelloInfo.Conn", func() { + It("has the right local and remote address on the tls.Config.GetConfigForClient ClientHelloInfo.Conn", func() { var local, remote net.Addr done := make(chan struct{}) tlsConf := &tls.Config{ @@ -164,6 +164,30 @@ var _ = Describe("Handshake tests", func() { Expect(conn.LocalAddr().(*net.UDPAddr).Port).To(Equal(remote.(*net.UDPAddr).Port)) }) + It("has the right local and remote address on the tls.Config.GetCertificate ClientHelloInfo.Conn", func() { + var local, remote net.Addr + done := make(chan struct{}) + tlsConf := getTLSConfig() + tlsConf.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + defer close(done) + local = info.Conn.LocalAddr() + remote = info.Conn.RemoteAddr() + cert := tlsConf.Certificates[0] + return &cert, nil + } + runServer(tlsConf) + conn, err := quic.DialAddr( + context.Background(), + fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), + getTLSClientConfig(), + getQuicConfig(nil), + ) + Expect(err).ToNot(HaveOccurred()) + Eventually(done).Should(BeClosed()) + Expect(server.Addr()).To(Equal(local)) + Expect(conn.LocalAddr().(*net.UDPAddr).Port).To(Equal(remote.(*net.UDPAddr).Port)) + }) + It("works with a long certificate chain", func() { runServer(getTLSConfigWithLongCertChain()) _, err := quic.DialAddr( diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index b528f08ebf3..7011a6fce83 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -134,6 +134,13 @@ func NewCryptoSetupServer( return gcfc(info) } } + if quicConf.TLSConfig.GetCertificate != nil { + gc := quicConf.TLSConfig.GetCertificate + quicConf.TLSConfig.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + info.Conn = &conn{localAddr: localAddr, remoteAddr: remoteAddr} + return gc(info) + } + } cs.tlsConf = quicConf.TLSConfig cs.conn = qtls.QUICServer(quicConf) From 26c6fcc5495874f80ffebb04df9b318d748d4ebe Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 5 Aug 2023 10:02:24 -0400 Subject: [PATCH 004/225] add error handling when confirming handshake on HANDSHAKE_DONE frames (#4017) --- connection.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connection.go b/connection.go index fdf40d196ce..270bbbfe49c 100644 --- a/connection.go +++ b/connection.go @@ -1475,7 +1475,7 @@ func (s *connection) handleHandshakeDoneFrame() error { } } if !s.handshakeConfirmed { - s.handleHandshakeConfirmed() + return s.handleHandshakeConfirmed() } return nil } From 95ab7bdc9a392b0357598dd77caae66bd99a6b0b Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 5 Aug 2023 16:00:11 -0400 Subject: [PATCH 005/225] add tls.ClientHelloInfo.Conn for recursive GetConfigForClient calls (#4016) --- integrationtests/self/handshake_test.go | 37 +++------- internal/handshake/crypto_setup.go | 36 ++++++---- internal/handshake/crypto_setup_test.go | 92 +++++++++++++++++++++---- 3 files changed, 112 insertions(+), 53 deletions(-) diff --git a/integrationtests/self/handshake_test.go b/integrationtests/self/handshake_test.go index f23ae77cc9e..cccff8a6fe8 100644 --- a/integrationtests/self/handshake_test.go +++ b/integrationtests/self/handshake_test.go @@ -142,13 +142,20 @@ var _ = Describe("Handshake tests", func() { It("has the right local and remote address on the tls.Config.GetConfigForClient ClientHelloInfo.Conn", func() { var local, remote net.Addr + var local2, remote2 net.Addr done := make(chan struct{}) tlsConf := &tls.Config{ GetConfigForClient: func(info *tls.ClientHelloInfo) (*tls.Config, error) { - defer close(done) local = info.Conn.LocalAddr() remote = info.Conn.RemoteAddr() - return getTLSConfig(), nil + conf := getTLSConfig() + conf.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + defer close(done) + local2 = info.Conn.LocalAddr() + remote2 = info.Conn.RemoteAddr() + return &(conf.Certificates[0]), nil + } + return conf, nil }, } runServer(tlsConf) @@ -162,30 +169,8 @@ var _ = Describe("Handshake tests", func() { Eventually(done).Should(BeClosed()) Expect(server.Addr()).To(Equal(local)) Expect(conn.LocalAddr().(*net.UDPAddr).Port).To(Equal(remote.(*net.UDPAddr).Port)) - }) - - It("has the right local and remote address on the tls.Config.GetCertificate ClientHelloInfo.Conn", func() { - var local, remote net.Addr - done := make(chan struct{}) - tlsConf := getTLSConfig() - tlsConf.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { - defer close(done) - local = info.Conn.LocalAddr() - remote = info.Conn.RemoteAddr() - cert := tlsConf.Certificates[0] - return &cert, nil - } - runServer(tlsConf) - conn, err := quic.DialAddr( - context.Background(), - fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), - getTLSClientConfig(), - getQuicConfig(nil), - ) - Expect(err).ToNot(HaveOccurred()) - Eventually(done).Should(BeClosed()) - Expect(server.Addr()).To(Equal(local)) - Expect(conn.LocalAddr().(*net.UDPAddr).Port).To(Equal(remote.(*net.UDPAddr).Port)) + Expect(local).To(Equal(local2)) + Expect(remote).To(Equal(remote2)) }) It("works with a long certificate chain", func() { diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index 7011a6fce83..543e70e0f0b 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -127,25 +127,37 @@ func NewCryptoSetupServer( quicConf := &qtls.QUICConfig{TLSConfig: tlsConf} qtls.SetupConfigForServer(quicConf, cs.allow0RTT, cs.getDataForSessionTicket, cs.accept0RTT) - if quicConf.TLSConfig.GetConfigForClient != nil { - gcfc := quicConf.TLSConfig.GetConfigForClient - quicConf.TLSConfig.GetConfigForClient = func(info *tls.ClientHelloInfo) (*tls.Config, error) { + addConnToClientHelloInfo(quicConf.TLSConfig, localAddr, remoteAddr) + + cs.tlsConf = quicConf.TLSConfig + cs.conn = qtls.QUICServer(quicConf) + + return cs +} + +// The tls.Config contains two callbacks that pass in a tls.ClientHelloInfo. +// Since crypto/tls doesn't do it, we need to make sure to set the Conn field with a fake net.Conn +// that allows the caller to get the local and the remote address. +func addConnToClientHelloInfo(conf *tls.Config, localAddr, remoteAddr net.Addr) { + if conf.GetConfigForClient != nil { + gcfc := conf.GetConfigForClient + conf.GetConfigForClient = func(info *tls.ClientHelloInfo) (*tls.Config, error) { info.Conn = &conn{localAddr: localAddr, remoteAddr: remoteAddr} - return gcfc(info) + c, err := gcfc(info) + if c != nil { + // We're returning a tls.Config here, so we need to apply this recursively. + addConnToClientHelloInfo(c, localAddr, remoteAddr) + } + return c, err } } - if quicConf.TLSConfig.GetCertificate != nil { - gc := quicConf.TLSConfig.GetCertificate - quicConf.TLSConfig.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + if conf.GetCertificate != nil { + gc := conf.GetCertificate + conf.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { info.Conn = &conn{localAddr: localAddr, remoteAddr: remoteAddr} return gc(info) } } - - cs.tlsConf = quicConf.TLSConfig - cs.conn = qtls.QUICServer(quicConf) - - return cs } func newCryptoSetup( diff --git a/internal/handshake/crypto_setup_test.go b/internal/handshake/crypto_setup_test.go index 4b210d20747..8b2c5efe95b 100644 --- a/internal/handshake/crypto_setup_test.go +++ b/internal/handshake/crypto_setup_test.go @@ -29,6 +29,25 @@ const ( ) var _ = Describe("Crypto Setup TLS", func() { + generateCert := func() tls.Certificate { + priv, err := rsa.GenerateKey(rand.Reader, 2048) + Expect(err).ToNot(HaveOccurred()) + tmpl := &x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{}, + SignatureAlgorithm: x509.SHA256WithRSA, + NotBefore: time.Now(), + NotAfter: time.Now().Add(time.Hour), // valid for an hour + BasicConstraintsValid: true, + } + certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, priv.Public(), priv) + Expect(err).ToNot(HaveOccurred()) + return tls.Certificate{ + PrivateKey: priv, + Certificate: [][]byte{certDER}, + } + } + var clientConf, serverConf *tls.Config BeforeEach(func() { @@ -86,26 +105,69 @@ var _ = Describe("Crypto Setup TLS", func() { Expect(err.Error()).To(ContainSubstring("tls: handshake data received at wrong level")) }) - Context("doing the handshake", func() { - generateCert := func() tls.Certificate { - priv, err := rsa.GenerateKey(rand.Reader, 2048) + Context("filling in a net.Conn in tls.ClientHelloInfo", func() { + var ( + local = &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 42} + remote = &net.UDPAddr{IP: net.IPv4(192, 168, 0, 1), Port: 1337} + ) + + It("wraps GetCertificate", func() { + var localAddr, remoteAddr net.Addr + tlsConf := &tls.Config{ + GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + localAddr = info.Conn.LocalAddr() + remoteAddr = info.Conn.RemoteAddr() + cert := generateCert() + return &cert, nil + }, + } + addConnToClientHelloInfo(tlsConf, local, remote) + _, err := tlsConf.GetCertificate(&tls.ClientHelloInfo{}) Expect(err).ToNot(HaveOccurred()) - tmpl := &x509.Certificate{ - SerialNumber: big.NewInt(1), - Subject: pkix.Name{}, - SignatureAlgorithm: x509.SHA256WithRSA, - NotBefore: time.Now(), - NotAfter: time.Now().Add(time.Hour), // valid for an hour - BasicConstraintsValid: true, + Expect(localAddr).To(Equal(local)) + Expect(remoteAddr).To(Equal(remote)) + }) + + It("wraps GetConfigForClient", func() { + var localAddr, remoteAddr net.Addr + tlsConf := &tls.Config{ + GetConfigForClient: func(info *tls.ClientHelloInfo) (*tls.Config, error) { + localAddr = info.Conn.LocalAddr() + remoteAddr = info.Conn.RemoteAddr() + return &tls.Config{}, nil + }, } - certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, priv.Public(), priv) + addConnToClientHelloInfo(tlsConf, local, remote) + _, err := tlsConf.GetConfigForClient(&tls.ClientHelloInfo{}) Expect(err).ToNot(HaveOccurred()) - return tls.Certificate{ - PrivateKey: priv, - Certificate: [][]byte{certDER}, + Expect(localAddr).To(Equal(local)) + Expect(remoteAddr).To(Equal(remote)) + }) + + It("wraps GetConfigForClient, recursively", func() { + var localAddr, remoteAddr net.Addr + tlsConf := &tls.Config{} + tlsConf.GetConfigForClient = func(info *tls.ClientHelloInfo) (*tls.Config, error) { + conf := tlsConf.Clone() + conf.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + localAddr = info.Conn.LocalAddr() + remoteAddr = info.Conn.RemoteAddr() + cert := generateCert() + return &cert, nil + } + return conf, nil } - } + addConnToClientHelloInfo(tlsConf, local, remote) + conf, err := tlsConf.GetConfigForClient(&tls.ClientHelloInfo{}) + Expect(err).ToNot(HaveOccurred()) + _, err = conf.GetCertificate(&tls.ClientHelloInfo{}) + Expect(err).ToNot(HaveOccurred()) + Expect(localAddr).To(Equal(local)) + Expect(remoteAddr).To(Equal(remote)) + }) + }) + Context("doing the handshake", func() { newRTTStatsWithRTT := func(rtt time.Duration) *utils.RTTStats { rttStats := &utils.RTTStats{} rttStats.UpdateRTT(rtt, 0, time.Now()) From aab4d4e4108459e70711f4785a4ab10b3d4d918e Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 5 Aug 2023 18:25:04 -0400 Subject: [PATCH 006/225] fix handling of ACK frames serialized after CRYPTO frames (#4018) --- connection.go | 31 ++++++++++++++++++++----- connection_test.go | 57 ++++++++++------------------------------------ 2 files changed, 37 insertions(+), 51 deletions(-) diff --git a/connection.go b/connection.go index 270bbbfe49c..b17f3ce81a3 100644 --- a/connection.go +++ b/connection.go @@ -718,20 +718,22 @@ func (s *connection) idleTimeoutStartTime() time.Time { } func (s *connection) handleHandshakeComplete() error { - s.handshakeComplete = true defer s.handshakeCtxCancel() // Once the handshake completes, we have derived 1-RTT keys. - // There's no point in queueing undecryptable packets for later decryption any more. + // There's no point in queueing undecryptable packets for later decryption anymore. s.undecryptablePackets = nil s.connIDManager.SetHandshakeComplete() s.connIDGenerator.SetHandshakeComplete() + // The server applies transport parameters right away, but the client side has to wait for handshake completion. + // During a 0-RTT connection, the client is only allowed to use the new transport parameters for 1-RTT packets. if s.perspective == protocol.PerspectiveClient { s.applyTransportParameters() return nil } + // All these only apply to the server side. if err := s.handleHandshakeConfirmed(); err != nil { return err } @@ -1229,6 +1231,7 @@ func (s *connection) handleFrames( if log != nil { frames = make([]logging.Frame, 0, 4) } + handshakeWasComplete := s.handshakeComplete var handleErr error for len(data) > 0 { l, frame, err := s.frameParser.ParseNext(data, encLevel, s.version) @@ -1265,6 +1268,17 @@ func (s *connection) handleFrames( return false, handleErr } } + + // Handle completion of the handshake after processing all the frames. + // This ensures that we correctly handle the following case on the server side: + // We receive a Handshake packet that contains the CRYPTO frame that allows us to complete the handshake, + // and an ACK serialized after that CRYPTO frame. In this case, we still want to process the ACK frame. + if !handshakeWasComplete && s.handshakeComplete { + if err := s.handleHandshakeComplete(); err != nil { + return false, err + } + } + return } @@ -1360,7 +1374,9 @@ func (s *connection) handleHandshakeEvents() error { case handshake.EventNoEvent: return nil case handshake.EventHandshakeComplete: - err = s.handleHandshakeComplete() + // Don't call handleHandshakeComplete yet. + // It's advantageous to process ACK frames that might be serialized after the CRYPTO frame first. + s.handshakeComplete = true case handshake.EventReceivedTransportParameters: err = s.handleTransportParameters(ev.TransportParameters) case handshake.EventRestoredTransportParameters: @@ -1488,6 +1504,9 @@ func (s *connection) handleAckFrame(frame *wire.AckFrame, encLevel protocol.Encr if !acked1RTTPacket { return nil } + // On the client side: If the packet acknowledged a 1-RTT packet, this confirms the handshake. + // This is only possible if the ACK was sent in a 1-RTT packet. + // This is an optimization over simply waiting for a HANDSHAKE_DONE frame, see section 4.1.2 of RFC 9001. if s.perspective == protocol.PerspectiveClient && !s.handshakeConfirmed { if err := s.handleHandshakeConfirmed(); err != nil { return err @@ -1659,6 +1678,9 @@ func (s *connection) restoreTransportParameters(params *wire.TransportParameters } func (s *connection) handleTransportParameters(params *wire.TransportParameters) error { + if s.tracer != nil { + s.tracer.ReceivedTransportParameters(params) + } if err := s.checkTransportParameters(params); err != nil { return &qerr.TransportError{ ErrorCode: qerr.TransportParameterError, @@ -1693,9 +1715,6 @@ func (s *connection) checkTransportParameters(params *wire.TransportParameters) if s.logger.Debug() { s.logger.Debugf("Processed Transport Parameters: %s", params) } - if s.tracer != nil { - s.tracer.ReceivedTransportParameters(params) - } // check the initial_source_connection_id if params.InitialSourceConnectionID != s.handshakeDestConnID { diff --git a/connection_test.go b/connection_test.go index c3c5d2c5006..5c972733f54 100644 --- a/connection_test.go +++ b/connection_test.go @@ -1891,7 +1891,6 @@ var _ = Describe("Connection", func() { It("cancels the HandshakeComplete context when the handshake completes", func() { packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).AnyTimes() - finishHandshake := make(chan struct{}) sph := mockackhandler.NewMockSentPacketHandler(mockCtrl) conn.sentPacketHandler = sph tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionHandshake) @@ -1901,53 +1900,26 @@ var _ = Describe("Connection", func() { sph.EXPECT().DropPackets(protocol.EncryptionHandshake) sph.EXPECT().SetHandshakeConfirmed() connRunner.EXPECT().Retire(clientDestConnID) - go func() { - defer GinkgoRecover() - <-finishHandshake - cryptoSetup.EXPECT().StartHandshake() - cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventHandshakeComplete}) - cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}) - cryptoSetup.EXPECT().SetHandshakeConfirmed() - cryptoSetup.EXPECT().GetSessionTicket() - conn.run() - }() + cryptoSetup.EXPECT().SetHandshakeConfirmed() + cryptoSetup.EXPECT().GetSessionTicket() handshakeCtx := conn.HandshakeComplete() Consistently(handshakeCtx).ShouldNot(BeClosed()) - close(finishHandshake) + Expect(conn.handleHandshakeComplete()).To(Succeed()) Eventually(handshakeCtx).Should(BeClosed()) - // make sure the go routine returns - streamManager.EXPECT().CloseWithError(gomock.Any()) - 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()) - tracer.EXPECT().ClosedConnection(gomock.Any()) - tracer.EXPECT().Close() - conn.shutdown() - Eventually(conn.Context().Done()).Should(BeClosed()) }) It("sends a session ticket when the handshake completes", func() { const size = protocol.MaxPostHandshakeCryptoFrameSize * 3 / 2 packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).AnyTimes() - finishHandshake := make(chan struct{}) connRunner.EXPECT().Retire(clientDestConnID) conn.sentPacketHandler.DropPackets(protocol.EncryptionInitial) tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionHandshake) - go func() { - defer GinkgoRecover() - <-finishHandshake - cryptoSetup.EXPECT().StartHandshake() - cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventHandshakeComplete}) - cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}) - cryptoSetup.EXPECT().SetHandshakeConfirmed() - cryptoSetup.EXPECT().GetSessionTicket().Return(make([]byte, size), nil) - conn.run() - }() + cryptoSetup.EXPECT().SetHandshakeConfirmed() + cryptoSetup.EXPECT().GetSessionTicket().Return(make([]byte, size), nil) handshakeCtx := conn.HandshakeComplete() Consistently(handshakeCtx).ShouldNot(BeClosed()) - close(finishHandshake) + Expect(conn.handleHandshakeComplete()).To(Succeed()) var frames []ackhandler.Frame Eventually(func() []ackhandler.Frame { frames, _ = conn.framer.AppendControlFrames(nil, protocol.MaxByteCount, protocol.Version1) @@ -1963,16 +1935,6 @@ var _ = Describe("Connection", func() { } } Expect(size).To(BeEquivalentTo(s)) - // make sure the go routine returns - streamManager.EXPECT().CloseWithError(gomock.Any()) - 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()) - tracer.EXPECT().ClosedConnection(gomock.Any()) - tracer.EXPECT().Close() - conn.shutdown() - Eventually(conn.Context().Done()).Should(BeClosed()) }) It("doesn't cancel the HandshakeComplete context when the handshake fails", func() { @@ -2027,6 +1989,7 @@ var _ = Describe("Connection", func() { cryptoSetup.EXPECT().SetHandshakeConfirmed() cryptoSetup.EXPECT().GetSessionTicket() mconn.EXPECT().Write(gomock.Any(), gomock.Any()) + Expect(conn.handleHandshakeComplete()).To(Succeed()) conn.run() }() Eventually(done).Should(BeClosed()) @@ -2350,6 +2313,7 @@ var _ = Describe("Connection", func() { cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}) cryptoSetup.EXPECT().GetSessionTicket().MaxTimes(1) cryptoSetup.EXPECT().SetHandshakeConfirmed().MaxTimes(1) + Expect(conn.handleHandshakeComplete()).To(Succeed()) err := conn.run() nerr, ok := err.(net.Error) Expect(ok).To(BeTrue()) @@ -2867,7 +2831,10 @@ var _ = Describe("Client Connection", func() { TransportParameters: params, }) cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventHandshakeComplete}).MaxTimes(1) - cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}).MaxTimes(1) + cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}).MaxTimes(1).Do(func() { + defer GinkgoRecover() + Expect(conn.handleHandshakeComplete()).To(Succeed()) + }) errChan <- conn.run() close(errChan) }() From 571d3adef4266a7c08f8e10dda32d07444716f00 Mon Sep 17 00:00:00 2001 From: elagergren-spideroak <36516532+elagergren-spideroak@users.noreply.github.com> Date: Wed, 9 Aug 2023 05:22:30 -0700 Subject: [PATCH 007/225] fix compatibility with API breaking change in Go 1.21 (#4020) * add Go 1.21 compatibility Signed-off-by: Eric Lagergren * refactor for Go 1.20 Signed-off-by: Eric Lagergren --------- Signed-off-by: Eric Lagergren --- .github/workflows/cross-compile.yml | 2 +- .github/workflows/integration.yml | 2 +- .github/workflows/unit.yml | 2 +- internal/handshake/crypto_setup.go | 2 +- internal/qtls/go120.go | 4 ++++ internal/qtls/go121.go | 19 +++++++++++++------ 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cross-compile.yml b/.github/workflows/cross-compile.yml index 042953f8c50..46309b0ae7e 100644 --- a/.github/workflows/cross-compile.yml +++ b/.github/workflows/cross-compile.yml @@ -4,7 +4,7 @@ jobs: strategy: fail-fast: false matrix: - go: [ "1.20.x", "1.21.0-rc.3" ] + go: [ "1.20.x", "1.21.x" ] runs-on: ${{ fromJSON(vars['CROSS_COMPILE_RUNNER_UBUNTU'] || '"ubuntu-latest"') }} name: "Cross Compilation (Go ${{matrix.go}})" steps: diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 362a24ecb9c..7ad8f5bab7d 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -5,7 +5,7 @@ jobs: strategy: fail-fast: false matrix: - go: [ "1.20.x", "1.21.0-rc.3" ] + go: [ "1.20.x", "1.21.x" ] runs-on: ${{ fromJSON(vars['INTEGRATION_RUNNER_UBUNTU'] || '"ubuntu-latest"') }} env: DEBUG: false # set this to true to export qlogs and save them as artifacts diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index fb21749fc17..c9eff032476 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -7,7 +7,7 @@ jobs: fail-fast: false matrix: os: [ "ubuntu", "windows", "macos" ] - go: [ "1.20.x", "1.21.0-rc.3" ] + go: [ "1.20.x", "1.21.x" ] runs-on: ${{ fromJSON(vars[format('UNIT_RUNNER_{0}', matrix.os)] || format('"{0}-latest"', matrix.os)) }} name: Unit tests (${{ matrix.os}}, Go ${{ matrix.go }}) steps: diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index 543e70e0f0b..35d65b5eecb 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -359,7 +359,7 @@ func (h *cryptoSetup) GetSessionTicket() ([]byte, error) { if h.tlsConf.SessionTicketsDisabled { return nil, nil } - if err := h.conn.SendSessionTicket(h.allow0RTT); err != nil { + if err := qtls.SendSessionTicket(h.conn, h.allow0RTT); err != nil { return nil, err } ev := h.conn.NextEvent() diff --git a/internal/qtls/go120.go b/internal/qtls/go120.go index 595e6e663ba..3b50441c47c 100644 --- a/internal/qtls/go120.go +++ b/internal/qtls/go120.go @@ -139,3 +139,7 @@ func SetCipherSuite(id uint16) (reset func()) { cipherSuitesModified = false } } + +func SendSessionTicket(c *QUICConn, allow0RTT bool) error { + return c.SendSessionTicket(allow0RTT) +} diff --git a/internal/qtls/go121.go b/internal/qtls/go121.go index 1137556e6a4..4aebc4a14c3 100644 --- a/internal/qtls/go121.go +++ b/internal/qtls/go121.go @@ -11,12 +11,13 @@ import ( ) type ( - QUICConn = tls.QUICConn - QUICConfig = tls.QUICConfig - QUICEvent = tls.QUICEvent - QUICEventKind = tls.QUICEventKind - QUICEncryptionLevel = tls.QUICEncryptionLevel - AlertError = tls.AlertError + QUICConn = tls.QUICConn + QUICConfig = tls.QUICConfig + QUICEvent = tls.QUICEvent + QUICEventKind = tls.QUICEventKind + QUICEncryptionLevel = tls.QUICEncryptionLevel + QUICSessionTicketOptions = tls.QUICSessionTicketOptions + AlertError = tls.AlertError ) const ( @@ -152,3 +153,9 @@ func findExtraData(extras [][]byte) []byte { } return nil } + +func SendSessionTicket(c *QUICConn, allow0RTT bool) error { + return c.SendSessionTicket(tls.QUICSessionTicketOptions{ + EarlyData: allow0RTT, + }) +} From 10d11149625ab20c87ee6e4ef64f0c44b08e9205 Mon Sep 17 00:00:00 2001 From: Gokul PM Date: Wed, 9 Aug 2023 17:56:39 +0530 Subject: [PATCH 008/225] README: fix invocation of Go routine in example (#4019) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3eaf0583b3f..a19249b484e 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ go func() { // ... error handling // handle the connection, usually in a new Go routine } -} +}() ``` The listener `ln` can now be used to accept incoming QUIC connections by (repeatedly) calling the `Accept` method (see below for more information on the `quic.Connection`). From 05db808f72b9183653cfce97d6c235108bb18ee6 Mon Sep 17 00:00:00 2001 From: Ondrej Kokes Date: Wed, 9 Aug 2023 15:30:46 +0200 Subject: [PATCH 009/225] http3: change code point for HTTP datagrams to RFC 9297 (#3588) * HTTP/3 Datagrams are now RFC 9297 * Use datatracker htmlized docs rather than rfc-editor (to be consistent) --- http3/error_codes.go | 2 +- http3/frames.go | 2 +- http3/roundtrip.go | 2 +- http3/server.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http3/error_codes.go b/http3/error_codes.go index 67b215d8548..e8428d0a5b5 100644 --- a/http3/error_codes.go +++ b/http3/error_codes.go @@ -26,7 +26,7 @@ const ( ErrCodeMessageError ErrCode = 0x10e ErrCodeConnectError ErrCode = 0x10f ErrCodeVersionFallback ErrCode = 0x110 - ErrCodeDatagramError ErrCode = 0x4a1268 + ErrCodeDatagramError ErrCode = 0x33 ) func (e ErrCode) String() string { diff --git a/http3/frames.go b/http3/frames.go index cdd97bc5e5d..454e5f945dc 100644 --- a/http3/frames.go +++ b/http3/frames.go @@ -88,7 +88,7 @@ func (f *headersFrame) Append(b []byte) []byte { return quicvarint.Append(b, f.Length) } -const settingDatagram = 0xffd277 +const settingDatagram = 0x33 type settingsFrame struct { Datagram bool diff --git a/http3/roundtrip.go b/http3/roundtrip.go index 066b762b85c..bed42103009 100644 --- a/http3/roundtrip.go +++ b/http3/roundtrip.go @@ -52,7 +52,7 @@ type RoundTripper struct { // Enable support for HTTP/3 datagrams. // If set to true, QuicConfig.EnableDatagram will be set. - // See https://www.ietf.org/archive/id/draft-schinazi-masque-h3-datagram-02.html. + // See https://datatracker.ietf.org/doc/html/rfc9297. EnableDatagrams bool // Additional HTTP/3 settings. diff --git a/http3/server.go b/http3/server.go index b90c850c112..728811c06bd 100644 --- a/http3/server.go +++ b/http3/server.go @@ -176,7 +176,7 @@ type Server struct { // EnableDatagrams enables support for HTTP/3 datagrams. // If set to true, QuicConfig.EnableDatagram will be set. - // See https://datatracker.ietf.org/doc/html/draft-ietf-masque-h3-datagram-07. + // See https://datatracker.ietf.org/doc/html/rfc9297. EnableDatagrams bool // MaxHeaderBytes controls the maximum number of bytes the server will From b65ed61feac22f479eada7d54884ff8a7dadbe6d Mon Sep 17 00:00:00 2001 From: Egon Elbre Date: Sun, 13 Aug 2023 11:43:28 +0300 Subject: [PATCH 010/225] integrationtests: fix proxy test on Windows (#4023) --- integrationtests/tools/proxy/proxy_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/integrationtests/tools/proxy/proxy_test.go b/integrationtests/tools/proxy/proxy_test.go index 81e13b23346..c9b80be5cc4 100644 --- a/integrationtests/tools/proxy/proxy_test.go +++ b/integrationtests/tools/proxy/proxy_test.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "net" + "runtime" "runtime/pprof" "strconv" "strings" @@ -68,7 +69,11 @@ var _ = Describe("QUIC Proxy", func() { addr, err := net.ResolveUDPAddr("udp", "localhost:"+strconv.Itoa(proxy.LocalPort())) Expect(err).ToNot(HaveOccurred()) _, err = net.ListenUDP("udp", addr) - Expect(err).To(MatchError(fmt.Sprintf("listen udp 127.0.0.1:%d: bind: address already in use", proxy.LocalPort()))) + if runtime.GOOS == "windows" { + Expect(err).To(MatchError(fmt.Sprintf("listen udp 127.0.0.1:%d: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.", proxy.LocalPort()))) + } else { + Expect(err).To(MatchError(fmt.Sprintf("listen udp 127.0.0.1:%d: bind: address already in use", proxy.LocalPort()))) + } Expect(proxy.Close()).To(Succeed()) // stopping is tested in the next test }) From 70f3f44a0975ad84c96f6efa08f7ad47a39796eb Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 14 Aug 2023 09:36:01 +0700 Subject: [PATCH 011/225] http3: remove leftover ALPN constant for draft-29 (#4027) --- http3/server.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/http3/server.go b/http3/server.go index 728811c06bd..8d39f3749da 100644 --- a/http3/server.go +++ b/http3/server.go @@ -31,12 +31,8 @@ var ( } ) -const ( - // NextProtoH3Draft29 is the ALPN protocol negotiated during the TLS handshake, for QUIC draft 29. - NextProtoH3Draft29 = "h3-29" - // NextProtoH3 is the ALPN protocol negotiated during the TLS handshake, for QUIC v1 and v2. - NextProtoH3 = "h3" -) +// NextProtoH3 is the ALPN protocol negotiated during the TLS handshake, for QUIC v1 and v2. +const NextProtoH3 = "h3" // StreamType is the stream type of a unidirectional stream. type StreamType uint64 From 1d848392bcf0b9611709c8018ad66bb88ddd8ccc Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 16 Aug 2023 09:53:41 +0700 Subject: [PATCH 012/225] ignore QUICConn.SendSessionTicket error if session tickets are disabled (#4030) --- integrationtests/self/resumption_test.go | 58 ++++++++++++++++++++++-- internal/handshake/crypto_setup.go | 12 +++-- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/integrationtests/self/resumption_test.go b/integrationtests/self/resumption_test.go index 264f832ebf5..bedf04704b0 100644 --- a/integrationtests/self/resumption_test.go +++ b/integrationtests/self/resumption_test.go @@ -56,7 +56,7 @@ var _ = Describe("TLS session resumption", func() { context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, - nil, + getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) var sessionKey string @@ -71,7 +71,7 @@ var _ = Describe("TLS session resumption", func() { context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, - nil, + getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) Expect(gets).To(Receive(Equal(sessionKey))) @@ -85,7 +85,7 @@ var _ = Describe("TLS session resumption", func() { It("doesn't use session resumption, if the config disables it", func() { sConf := getTLSConfig() sConf.SessionTicketsDisabled = true - server, err := quic.ListenAddr("localhost:0", sConf, nil) + server, err := quic.ListenAddr("localhost:0", sConf, getQuicConfig(nil)) Expect(err).ToNot(HaveOccurred()) defer server.Close() @@ -98,7 +98,7 @@ var _ = Describe("TLS session resumption", func() { context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, - nil, + getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) Consistently(puts).ShouldNot(Receive()) @@ -114,7 +114,55 @@ var _ = Describe("TLS session resumption", func() { context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, - nil, + getQuicConfig(nil), + ) + Expect(err).ToNot(HaveOccurred()) + Expect(conn.ConnectionState().TLS.DidResume).To(BeFalse()) + + serverConn, err = server.Accept(context.Background()) + Expect(err).ToNot(HaveOccurred()) + Expect(serverConn.ConnectionState().TLS.DidResume).To(BeFalse()) + }) + + It("doesn't use session resumption, if the config returned by GetConfigForClient disables it", func() { + sConf := &tls.Config{ + GetConfigForClient: func(*tls.ClientHelloInfo) (*tls.Config, error) { + conf := getTLSConfig() + conf.SessionTicketsDisabled = true + return conf, nil + }, + } + + server, err := quic.ListenAddr("localhost:0", sConf, getQuicConfig(nil)) + Expect(err).ToNot(HaveOccurred()) + defer server.Close() + + gets := make(chan string, 100) + puts := make(chan string, 100) + cache := newClientSessionCache(tls.NewLRUClientSessionCache(10), gets, puts) + tlsConf := getTLSClientConfig() + tlsConf.ClientSessionCache = cache + conn, err := quic.DialAddr( + context.Background(), + fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), + tlsConf, + getQuicConfig(nil), + ) + Expect(err).ToNot(HaveOccurred()) + Consistently(puts).ShouldNot(Receive()) + Expect(conn.ConnectionState().TLS.DidResume).To(BeFalse()) + + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + serverConn, err := server.Accept(ctx) + Expect(err).ToNot(HaveOccurred()) + Expect(serverConn.ConnectionState().TLS.DidResume).To(BeFalse()) + + conn, err = quic.DialAddr( + context.Background(), + fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), + tlsConf, + getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) Expect(conn.ConnectionState().TLS.DidResume).To(BeFalse()) diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index 35d65b5eecb..a1179257b5a 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "net" + "strings" "sync" "sync/atomic" "time" @@ -356,10 +357,15 @@ func (h *cryptoSetup) getDataForSessionTicket() []byte { // Due to limitations in crypto/tls, it's only possible to generate a single session ticket per connection. // It is only valid for the server. func (h *cryptoSetup) GetSessionTicket() ([]byte, error) { - if h.tlsConf.SessionTicketsDisabled { - return nil, nil - } if err := qtls.SendSessionTicket(h.conn, h.allow0RTT); err != nil { + // Session tickets might be disabled by tls.Config.SessionTicketsDisabled. + // We can't check h.tlsConfig here, since the actual config might have been obtained from + // the GetConfigForClient callback. + // See https://github.com/golang/go/issues/62032. + // Once that issue is resolved, this error assertion can be removed. + if strings.Contains(err.Error(), "session ticket keys unavailable") { + return nil, nil + } return nil, err } ev := h.conn.NextEvent() From bda01bc4894568fbd80175676580b9b523a51c63 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 16 Aug 2023 10:09:01 +0700 Subject: [PATCH 013/225] handshake: use the correct hash function for TLS_AES_256_GCM_SHA384 (#4031) --- internal/handshake/cipher_suite.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/handshake/cipher_suite.go b/internal/handshake/cipher_suite.go index 608d5ea00e6..265231f0c60 100644 --- a/internal/handshake/cipher_suite.go +++ b/internal/handshake/cipher_suite.go @@ -30,7 +30,7 @@ func getCipherSuite(id uint16) *cipherSuite { case tls.TLS_CHACHA20_POLY1305_SHA256: return &cipherSuite{ID: tls.TLS_CHACHA20_POLY1305_SHA256, Hash: crypto.SHA256, KeyLen: 32, AEAD: aeadChaCha20Poly1305} case tls.TLS_AES_256_GCM_SHA384: - return &cipherSuite{ID: tls.TLS_AES_256_GCM_SHA384, Hash: crypto.SHA256, KeyLen: 32, AEAD: aeadAESGCMTLS13} + return &cipherSuite{ID: tls.TLS_AES_256_GCM_SHA384, Hash: crypto.SHA384, KeyLen: 32, AEAD: aeadAESGCMTLS13} default: panic(fmt.Sprintf("unknown cypher suite: %d", id)) } From 2e7ea9119c84904a881bd31eed130edcf200b98e Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 16 Aug 2023 18:58:07 +0700 Subject: [PATCH 014/225] add OSS-Fuzz badge to README (#3942) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a19249b484e..a793f984764 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![PkgGoDev](https://pkg.go.dev/badge/github.com/quic-go/quic-go)](https://pkg.go.dev/github.com/quic-go/quic-go) [![Code Coverage](https://img.shields.io/codecov/c/github/quic-go/quic-go/master.svg?style=flat-square)](https://codecov.io/gh/quic-go/quic-go/) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/quic-go.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:quic-go) quic-go is an implementation of the QUIC protocol ([RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000), [RFC 9001](https://datatracker.ietf.org/doc/html/rfc9001), [RFC 9002](https://datatracker.ietf.org/doc/html/rfc9002)) in Go. It has support for HTTP/3 ([RFC 9114](https://datatracker.ietf.org/doc/html/rfc9114)), including QPACK ([RFC 9204](https://datatracker.ietf.org/doc/html/rfc9204)). From 4f696569a22f88d9bd913b354848f8460c6faed9 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 16 Aug 2023 18:59:11 +0700 Subject: [PATCH 015/225] store the server port as an int, not a string, in HTTP tests (#3959) --- integrationtests/self/http_test.go | 44 ++++++++++++++++-------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/integrationtests/self/http_test.go b/integrationtests/self/http_test.go index e41dc85e4a7..b647d4d9c00 100644 --- a/integrationtests/self/http_test.go +++ b/integrationtests/self/http_test.go @@ -42,7 +42,7 @@ var _ = Describe("HTTP tests", func() { rt *http3.RoundTripper server *http3.Server stoppedServing chan struct{} - port string + port int ) BeforeEach(func() { @@ -93,7 +93,7 @@ var _ = Describe("HTTP tests", func() { Expect(err).NotTo(HaveOccurred()) conn, err := net.ListenUDP("udp", addr) Expect(err).NotTo(HaveOccurred()) - port = strconv.Itoa(conn.LocalAddr().(*net.UDPAddr).Port) + port = conn.LocalAddr().(*net.UDPAddr).Port stoppedServing = make(chan struct{}) @@ -120,7 +120,7 @@ var _ = Describe("HTTP tests", func() { }) It("downloads a hello", func() { - resp, err := client.Get("https://localhost:" + port + "/hello") + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/hello", port)) Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) body, err := io.ReadAll(gbytes.TimeoutReader(resp.Body, 3*time.Second)) @@ -129,12 +129,12 @@ var _ = Describe("HTTP tests", func() { }) It("requests to different servers with the same udpconn", func() { - resp, err := client.Get("https://localhost:" + port + "/remoteAddr") + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/remoteAddr", port)) Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) addr1 := resp.Header.Get("X-RemoteAddr") Expect(addr1).ToNot(Equal("")) - resp, err = client.Get("https://127.0.0.1:" + port + "/remoteAddr") + resp, err = client.Get(fmt.Sprintf("https://127.0.0.1:%d/remoteAddr", port)) Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) addr2 := resp.Header.Get("X-RemoteAddr") @@ -146,7 +146,7 @@ var _ = Describe("HTTP tests", func() { group, ctx := errgroup.WithContext(context.Background()) for i := 0; i < 2; i++ { group.Go(func() error { - req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://localhost:"+port+"/hello", nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://localhost:%d/hello", port), nil) Expect(err).ToNot(HaveOccurred()) resp, err := client.Do(req) Expect(err).ToNot(HaveOccurred()) @@ -172,7 +172,7 @@ var _ = Describe("HTTP tests", func() { close(handlerCalled) }) - req, err := http.NewRequest(http.MethodGet, "https://localhost:"+port+"/headers/request", nil) + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("https://localhost:%d/headers/request", port), nil) Expect(err).ToNot(HaveOccurred()) req.Header.Set("foo", "bar") req.Header.Set("lorem", "ipsum") @@ -189,7 +189,7 @@ var _ = Describe("HTTP tests", func() { w.Header().Set("lorem", "ipsum") }) - resp, err := client.Get("https://localhost:" + port + "/headers/response") + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/headers/response", port)) Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) Expect(resp.Header.Get("foo")).To(Equal("bar")) @@ -197,7 +197,7 @@ var _ = Describe("HTTP tests", func() { }) It("downloads a small file", func() { - resp, err := client.Get("https://localhost:" + port + "/prdata") + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/prdata", port)) Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) body, err := io.ReadAll(gbytes.TimeoutReader(resp.Body, 5*time.Second)) @@ -206,7 +206,7 @@ var _ = Describe("HTTP tests", func() { }) It("downloads a large file", func() { - resp, err := client.Get("https://localhost:" + port + "/prdatalong") + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/prdatalong", port)) Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) body, err := io.ReadAll(gbytes.TimeoutReader(resp.Body, 20*time.Second)) @@ -218,7 +218,7 @@ var _ = Describe("HTTP tests", func() { const num = 150 for i := 0; i < num; i++ { - resp, err := client.Get("https://localhost:" + port + "/hello") + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/hello", port)) Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) body, err := io.ReadAll(gbytes.TimeoutReader(resp.Body, 3*time.Second)) @@ -231,7 +231,7 @@ var _ = Describe("HTTP tests", func() { const num = 150 for i := 0; i < num; i++ { - resp, err := client.Get("https://localhost:" + port + "/prdata") + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/prdata", port)) Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) Expect(resp.Body.Close()).To(Succeed()) @@ -240,7 +240,7 @@ var _ = Describe("HTTP tests", func() { It("posts a small message", func() { resp, err := client.Post( - "https://localhost:"+port+"/echo", + fmt.Sprintf("https://localhost:%d/echo", port), "text/plain", bytes.NewReader([]byte("Hello, world!")), ) @@ -253,7 +253,7 @@ var _ = Describe("HTTP tests", func() { It("uploads a file", func() { resp, err := client.Post( - "https://localhost:"+port+"/echo", + fmt.Sprintf("https://localhost:%d/echo", port), "text/plain", bytes.NewReader(PRData), ) @@ -277,7 +277,7 @@ var _ = Describe("HTTP tests", func() { }) client.Transport.(*http3.RoundTripper).DisableCompression = false - resp, err := client.Get("https://localhost:" + port + "/gzipped/hello") + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/gzipped/hello", port)) Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) Expect(resp.Uncompressed).To(BeTrue()) @@ -303,7 +303,7 @@ var _ = Describe("HTTP tests", func() { } }) - req, err := http.NewRequest(http.MethodGet, "https://localhost:"+port+"/cancel", nil) + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("https://localhost:%d/cancel", port), nil) Expect(err).ToNot(HaveOccurred()) ctx, cancel := context.WithCancel(context.Background()) req = req.WithContext(ctx) @@ -336,7 +336,7 @@ var _ = Describe("HTTP tests", func() { }) r, w := io.Pipe() - req, err := http.NewRequest("PUT", "https://localhost:"+port+"/echoline", r) + req, err := http.NewRequest(http.MethodPut, fmt.Sprintf("https://localhost:%d/echoline", port), r) Expect(err).ToNot(HaveOccurred()) rsp, err := client.Do(req) Expect(err).ToNot(HaveOccurred()) @@ -373,7 +373,7 @@ var _ = Describe("HTTP tests", func() { }() }) - req, err := http.NewRequest(http.MethodGet, "https://localhost:"+port+"/httpstreamer", nil) + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("https://localhost:%d/httpstreamer", port), nil) Expect(err).ToNot(HaveOccurred()) rsp, err := client.Transport.(*http3.RoundTripper).RoundTripOpt(req, http3.RoundTripOpt{DontCloseRequestStream: true}) Expect(err).ToNot(HaveOccurred()) @@ -431,7 +431,11 @@ var _ = Describe("HTTP tests", func() { }) expectedEnd := time.Now().Add(deadlineDelay) - resp, err := client.Post("https://localhost:"+port+"/read-deadline", "text/plain", neverEnding('a')) + resp, err := client.Post( + fmt.Sprintf("https://localhost:%d/read-deadline", port), + "text/plain", + neverEnding('a'), + ) Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) @@ -453,7 +457,7 @@ var _ = Describe("HTTP tests", func() { expectedEnd := time.Now().Add(deadlineDelay) - resp, err := client.Get("https://localhost:" + port + "/write-deadline") + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/write-deadline", port)) Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) From ca3842d6c8409514a63d98a4ff8b5d493a90e7bf Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 16 Aug 2023 20:54:42 +0700 Subject: [PATCH 016/225] automatically set the tls.Config.ServerName if unset (#4032) --- client.go | 16 +++++----------- transport.go | 30 +++++++++++++++--------------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/client.go b/client.go index 4dfacb50d4e..61cd7526526 100644 --- a/client.go +++ b/client.go @@ -55,11 +55,11 @@ func DialAddr(ctx context.Context, addr string, tlsConf *tls.Config, conf *Confi if err != nil { return nil, err } - dl, err := setupTransport(udpConn, tlsConf, true) + tr, err := setupTransport(udpConn, tlsConf, true) if err != nil { return nil, err } - return dl.Dial(ctx, udpAddr, tlsConf, conf) + return tr.dial(ctx, udpAddr, addr, tlsConf, conf, false) } // DialAddrEarly establishes a new 0-RTT QUIC connection to a server. @@ -73,13 +73,13 @@ func DialAddrEarly(ctx context.Context, addr string, tlsConf *tls.Config, conf * if err != nil { return nil, err } - dl, err := setupTransport(udpConn, tlsConf, true) + tr, err := setupTransport(udpConn, tlsConf, true) if err != nil { return nil, err } - conn, err := dl.DialEarly(ctx, udpAddr, tlsConf, conf) + conn, err := tr.dial(ctx, udpAddr, addr, tlsConf, conf, true) if err != nil { - dl.Close() + tr.Close() return nil, err } return conn, nil @@ -163,12 +163,6 @@ func dial( } func newClient(sendConn sendConn, connIDGenerator ConnectionIDGenerator, config *Config, tlsConf *tls.Config, onClose func(), use0RTT bool) (*client, error) { - if tlsConf == nil { - tlsConf = &tls.Config{} - } else { - tlsConf = tlsConf.Clone() - } - srcConnID, err := connIDGenerator.GenerateConnectionID() if err != nil { return nil, err diff --git a/transport.go b/transport.go index 290b647fb50..42fafd49381 100644 --- a/transport.go +++ b/transport.go @@ -148,24 +148,15 @@ func (t *Transport) ListenEarly(tlsConf *tls.Config, conf *Config) (*EarlyListen // Dial dials a new connection to a remote host (not using 0-RTT). func (t *Transport) Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (Connection, error) { - if err := validateConfig(conf); err != nil { - return nil, err - } - conf = populateConfig(conf) - if err := t.init(t.isSingleUse); err != nil { - return nil, err - } - var onClose func() - if t.isSingleUse { - onClose = func() { t.Close() } - } - tlsConf = tlsConf.Clone() - tlsConf.MinVersion = tls.VersionTLS13 - return dial(ctx, newSendConn(t.conn, addr), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, false) + return t.dial(ctx, addr, "", tlsConf, conf, false) } // DialEarly dials a new connection, attempting to use 0-RTT if possible. func (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (EarlyConnection, error) { + return t.dial(ctx, addr, "", tlsConf, conf, true) +} + +func (t *Transport) dial(ctx context.Context, addr net.Addr, hostname string, tlsConf *tls.Config, conf *Config, use0RTT bool) (EarlyConnection, error) { if err := validateConfig(conf); err != nil { return nil, err } @@ -179,7 +170,16 @@ func (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.C } tlsConf = tlsConf.Clone() tlsConf.MinVersion = tls.VersionTLS13 - return dial(ctx, newSendConn(t.conn, addr), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, true) + // If no ServerName is set, infer the ServerName from the hostname we're connecting to. + if tlsConf.ServerName == "" { + if hostname == "" { + if udpAddr, ok := addr.(*net.UDPAddr); ok { + hostname = udpAddr.IP.String() + } + } + tlsConf.ServerName = hostname + } + return dial(ctx, newSendConn(t.conn, addr), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, use0RTT) } func (t *Transport) init(allowZeroLengthConnIDs bool) error { From 51d257d6082b531778855c76a2c3521cdafd7581 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 16 Aug 2023 20:55:44 +0700 Subject: [PATCH 017/225] handshake fuzzer: fix TLS handshake sequence (#4033) There were two problems with the existing code: 1. The transport parameters were rejected due to an invalid value for ActiveConnectionIDLimit, causing the handshake to fail. 2. Handshake messages were passed in at the wrong encryption level, leading to consistent handshake failures. --- fuzzing/handshake/fuzz.go | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/fuzzing/handshake/fuzz.go b/fuzzing/handshake/fuzz.go index 2c5c1259b9b..93cec975c87 100644 --- a/fuzzing/handshake/fuzz.go +++ b/fuzzing/handshake/fuzz.go @@ -147,6 +147,7 @@ func getTransportParameters(seed uint8) *wire.TransportParameters { const maxVarInt = math.MaxUint64 / 4 r := mrand.New(mrand.NewSource(int64(seed))) return &wire.TransportParameters{ + ActiveConnectionIDLimit: 2, InitialMaxData: protocol.ByteCount(r.Int63n(maxVarInt)), InitialMaxStreamDataBidiLocal: protocol.ByteCount(r.Int63n(maxVarInt)), InitialMaxStreamDataBidiRemote: protocol.ByteCount(r.Int63n(maxVarInt)), @@ -302,6 +303,7 @@ func runHandshake(runConfig [confLen]byte, messageConfig uint8, clientConf *tls. if err := client.StartHandshake(); err != nil { log.Fatal(err) } + defer client.Close() server := handshake.NewCryptoSetupServer( protocol.ConnectionID{}, @@ -318,12 +320,13 @@ func runHandshake(runConfig [confLen]byte, messageConfig uint8, clientConf *tls. if err := server.StartHandshake(); err != nil { log.Fatal(err) } + defer server.Close() var clientHandshakeComplete, serverHandshakeComplete bool for { + var processedEvent bool clientLoop: for { - var processedEvent bool ev := client.NextEvent() //nolint:exhaustive // only need to process a few events switch ev.Kind { @@ -334,11 +337,16 @@ func runHandshake(runConfig [confLen]byte, messageConfig uint8, clientConf *tls. break clientLoop case handshake.EventWriteInitialData, handshake.EventWriteHandshakeData: msg := ev.Data + encLevel := protocol.EncryptionInitial + if ev.Kind == handshake.EventWriteHandshakeData { + encLevel = protocol.EncryptionHandshake + } if msg[0] == messageToReplace { fmt.Printf("replacing %s message to the server with %s at %s\n", messageType(msg[0]), messageType(data[0]), messageToReplaceEncLevel) msg = data + encLevel = messageToReplaceEncLevel } - if err := server.HandleMessage(msg, messageToReplaceEncLevel); err != nil { + if err := server.HandleMessage(msg, encLevel); err != nil { return 1 } case handshake.EventHandshakeComplete: @@ -347,9 +355,9 @@ func runHandshake(runConfig [confLen]byte, messageConfig uint8, clientConf *tls. processedEvent = true } + processedEvent = false serverLoop: for { - var processedEvent bool ev := server.NextEvent() //nolint:exhaustive // only need to process a few events switch ev.Kind { @@ -359,12 +367,17 @@ func runHandshake(runConfig [confLen]byte, messageConfig uint8, clientConf *tls. } break serverLoop case handshake.EventWriteInitialData, handshake.EventWriteHandshakeData: + encLevel := protocol.EncryptionInitial + if ev.Kind == handshake.EventWriteHandshakeData { + encLevel = protocol.EncryptionHandshake + } msg := ev.Data if msg[0] == messageToReplace { fmt.Printf("replacing %s message to the client with %s at %s\n", messageType(msg[0]), messageType(data[0]), messageToReplaceEncLevel) msg = data + encLevel = messageToReplaceEncLevel } - if err := client.HandleMessage(msg, messageToReplaceEncLevel); err != nil { + if err := client.HandleMessage(msg, encLevel); err != nil { return 1 } case handshake.EventHandshakeComplete: @@ -410,9 +423,11 @@ func runHandshake(runConfig [confLen]byte, messageConfig uint8, clientConf *tls. client.HandleMessage(ticket, protocol.Encryption1RTT) } if sendPostHandshakeMessageToClient { + fmt.Println("sending post handshake message to the client at", messageToReplaceEncLevel) client.HandleMessage(data, messageToReplaceEncLevel) } if sendPostHandshakeMessageToServer { + fmt.Println("sending post handshake message to the server at", messageToReplaceEncLevel) server.HandleMessage(data, messageToReplaceEncLevel) } From 83c00a574dbaed179d969c918ae5855ac3c634ab Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 16 Aug 2023 21:21:48 +0700 Subject: [PATCH 018/225] ci: also run integration tests on Windows and macOS (#3987) --- .github/workflows/integration.yml | 12 +++++++++--- integrationtests/self/handshake_test.go | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 7ad8f5bab7d..0b8fa90430d 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -5,12 +5,18 @@ jobs: strategy: fail-fast: false matrix: + os: [ "ubuntu" ] go: [ "1.20.x", "1.21.x" ] - runs-on: ${{ fromJSON(vars['INTEGRATION_RUNNER_UBUNTU'] || '"ubuntu-latest"') }} + include: + - os: "windows" + go: "1.21.x" + - os: "macos" + go: "1.21.x" + runs-on: ${{ fromJSON(vars[format('INTEGRATION_RUNNER_{0}', matrix.os)] || format('"{0}-latest"', matrix.os)) }} env: DEBUG: false # set this to true to export qlogs and save them as artifacts TIMESCALE_FACTOR: 3 - name: Integration Tests (Go ${{ matrix.go }}) + name: Integration Tests (${{ matrix.os }}, Go ${{ matrix.go }}) steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 @@ -37,7 +43,7 @@ jobs: QUIC_GO_ENABLE_GSO: true run: go run github.com/onsi/ginkgo/v2/ginkgo -r -v -randomize-all -randomize-suites -trace integrationtests/self -- -version=1 ${{ env.QLOGFLAG }} - name: Run tests (32 bit) - if: success() || failure() # run this step even if the previous one failed + if: ${{ matrix.os != 'macos' && (success() || failure()) }} # run this step even if the previous one failed env: GOARCH: 386 run: | diff --git a/integrationtests/self/handshake_test.go b/integrationtests/self/handshake_test.go index cccff8a6fe8..951c4c7ab66 100644 --- a/integrationtests/self/handshake_test.go +++ b/integrationtests/self/handshake_test.go @@ -453,7 +453,7 @@ var _ = Describe("Handshake tests", func() { It("rejects invalid Retry token with the INVALID_TOKEN error", func() { serverConfig.RequireAddressValidation = func(net.Addr) bool { return true } - serverConfig.MaxRetryTokenAge = time.Nanosecond + serverConfig.MaxRetryTokenAge = -time.Second server, err := quic.ListenAddr("localhost:0", getTLSConfig(), serverConfig) Expect(err).ToNot(HaveOccurred()) From 4122eb7a7d59ecbb47398a24124206e14a196f36 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 29 Jul 2023 15:58:32 -0700 Subject: [PATCH 019/225] disable GSO if sending fails for a particular remote address --- mock_raw_conn_test.go | 122 +++++++++++++++++++++++++++++++ mockgen.go | 3 + packet_handler_map.go | 6 +- send_conn.go | 91 ++++++++++++++--------- send_conn_test.go | 95 ++++++++++++++++-------- server.go | 8 +- sys_conn.go | 6 +- sys_conn_df_linux.go | 40 +--------- sys_conn_helper_linux.go | 30 ++++++++ sys_conn_helper_linux_test.go | 20 +++-- sys_conn_helper_nonlinux.go | 3 + sys_conn_helper_nonlinux_test.go | 7 ++ sys_conn_no_gso.go | 8 -- sys_conn_oob.go | 20 +---- transport.go | 9 +-- 15 files changed, 318 insertions(+), 150 deletions(-) create mode 100644 mock_raw_conn_test.go create mode 100644 sys_conn_helper_nonlinux_test.go delete mode 100644 sys_conn_no_gso.go diff --git a/mock_raw_conn_test.go b/mock_raw_conn_test.go new file mode 100644 index 00000000000..66b9c6115c3 --- /dev/null +++ b/mock_raw_conn_test.go @@ -0,0 +1,122 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/quic-go/quic-go (interfaces: RawConn) + +// Package quic is a generated GoMock package. +package quic + +import ( + net "net" + reflect "reflect" + time "time" + + gomock "github.com/golang/mock/gomock" +) + +// MockRawConn is a mock of RawConn interface. +type MockRawConn struct { + ctrl *gomock.Controller + recorder *MockRawConnMockRecorder +} + +// MockRawConnMockRecorder is the mock recorder for MockRawConn. +type MockRawConnMockRecorder struct { + mock *MockRawConn +} + +// NewMockRawConn creates a new mock instance. +func NewMockRawConn(ctrl *gomock.Controller) *MockRawConn { + mock := &MockRawConn{ctrl: ctrl} + mock.recorder = &MockRawConnMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockRawConn) EXPECT() *MockRawConnMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockRawConn) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockRawConnMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockRawConn)(nil).Close)) +} + +// LocalAddr mocks base method. +func (m *MockRawConn) LocalAddr() net.Addr { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LocalAddr") + ret0, _ := ret[0].(net.Addr) + return ret0 +} + +// LocalAddr indicates an expected call of LocalAddr. +func (mr *MockRawConnMockRecorder) LocalAddr() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockRawConn)(nil).LocalAddr)) +} + +// ReadPacket mocks base method. +func (m *MockRawConn) ReadPacket() (receivedPacket, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReadPacket") + ret0, _ := ret[0].(receivedPacket) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReadPacket indicates an expected call of ReadPacket. +func (mr *MockRawConnMockRecorder) ReadPacket() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadPacket", reflect.TypeOf((*MockRawConn)(nil).ReadPacket)) +} + +// SetReadDeadline mocks base method. +func (m *MockRawConn) SetReadDeadline(arg0 time.Time) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetReadDeadline", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetReadDeadline indicates an expected call of SetReadDeadline. +func (mr *MockRawConnMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockRawConn)(nil).SetReadDeadline), arg0) +} + +// WritePacket mocks base method. +func (m *MockRawConn) WritePacket(arg0 []byte, arg1 net.Addr, arg2 []byte) (int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WritePacket", arg0, arg1, arg2) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WritePacket indicates an expected call of WritePacket. +func (mr *MockRawConnMockRecorder) WritePacket(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePacket", reflect.TypeOf((*MockRawConn)(nil).WritePacket), arg0, arg1, arg2) +} + +// capabilities mocks base method. +func (m *MockRawConn) capabilities() connCapabilities { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "capabilities") + ret0, _ := ret[0].(connCapabilities) + return ret0 +} + +// capabilities indicates an expected call of capabilities. +func (mr *MockRawConnMockRecorder) capabilities() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "capabilities", reflect.TypeOf((*MockRawConn)(nil).capabilities)) +} diff --git a/mockgen.go b/mockgen.go index eb700864ac0..221c1367fcd 100644 --- a/mockgen.go +++ b/mockgen.go @@ -5,6 +5,9 @@ package quic //go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn" type SendConn = sendConn +//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn" +type RawConn = rawConn + //go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender" type Sender = sender diff --git a/packet_handler_map.go b/packet_handler_map.go index 2a16773c8e5..e0f0567d70a 100644 --- a/packet_handler_map.go +++ b/packet_handler_map.go @@ -26,9 +26,9 @@ type connCapabilities struct { // rawConn is a connection that allow reading of a receivedPackeh. type rawConn interface { ReadPacket() (receivedPacket, error) - // The size parameter is used for GSO. - // If GSO is not support, len(b) must be equal to size. - WritePacket(b []byte, size uint16, addr net.Addr, oob []byte) (int, error) + // WritePacket writes a packet on the wire. + // If GSO is enabled, it's the caller's responsibility to set the correct control message. + WritePacket(b []byte, addr net.Addr, oob []byte) (int, error) LocalAddr() net.Addr SetReadDeadline(time.Time) error io.Closer diff --git a/send_conn.go b/send_conn.go index 4e7007fadf8..34cbfd6e23d 100644 --- a/send_conn.go +++ b/send_conn.go @@ -1,10 +1,12 @@ package quic import ( + "fmt" "math" "net" "github.com/quic-go/quic-go/internal/protocol" + "github.com/quic-go/quic-go/internal/utils" ) // A sendConn allows sending using a simple Write() on a non-connected packet conn. @@ -20,61 +22,84 @@ type sendConn interface { type sconn struct { rawConn + localAddr net.Addr remoteAddr net.Addr - info packetInfo - oob []byte + + logger utils.Logger + + info packetInfo + oob []byte + // If GSO enabled, and we receive a GSO error for this remote address, GSO is disabled. + gotGSOError bool } var _ sendConn = &sconn{} -func newSendConn(c rawConn, remote net.Addr) *sconn { - sc := &sconn{ - rawConn: c, - remoteAddr: remote, - } - if c.capabilities().GSO { - // add 32 bytes, so we can add the UDP_SEGMENT msg - sc.oob = make([]byte, 0, 32) +func newSendConn(c rawConn, remote net.Addr, info packetInfo, logger utils.Logger) *sconn { + localAddr := c.LocalAddr() + if info.addr.IsValid() { + if udpAddr, ok := localAddr.(*net.UDPAddr); ok { + addrCopy := *udpAddr + addrCopy.IP = info.addr.AsSlice() + localAddr = &addrCopy + } } - return sc -} -func newSendConnWithPacketInfo(c rawConn, remote net.Addr, info packetInfo) *sconn { oob := info.OOB() - if c.capabilities().GSO { - // add 32 bytes, so we can add the UDP_SEGMENT msg - l := len(oob) - oob = append(oob, make([]byte, 32)...) - oob = oob[:l] - } + // add 32 bytes, so we can add the UDP_SEGMENT msg + l := len(oob) + oob = append(oob, make([]byte, 32)...) + oob = oob[:l] return &sconn{ rawConn: c, + localAddr: localAddr, remoteAddr: remote, info: info, oob: oob, + logger: logger, } } func (c *sconn) Write(p []byte, size protocol.ByteCount) error { + if !c.capabilities().GSO { + if protocol.ByteCount(len(p)) != size { + panic(fmt.Sprintf("inconsistent packet size (%d vs %d)", len(p), size)) + } + _, err := c.WritePacket(p, c.remoteAddr, c.oob) + return err + } + // GSO is supported. Append the control message and send. if size > math.MaxUint16 { panic("size overflow") } - _, err := c.WritePacket(p, uint16(size), c.remoteAddr, c.oob) + _, err := c.WritePacket(p, c.remoteAddr, appendUDPSegmentSizeMsg(c.oob, uint16(size))) + if err != nil && isGSOError(err) { + // disable GSO for future calls + c.gotGSOError = true + if c.logger.Debug() { + c.logger.Debugf("GSO failed when sending to %s", c.remoteAddr) + } + // send out the packets one by one + for len(p) > 0 { + l := len(p) + if l > int(size) { + l = int(size) + } + if _, err := c.WritePacket(p[:l], c.remoteAddr, c.oob); err != nil { + return err + } + p = p[l:] + } + return nil + } return err } -func (c *sconn) RemoteAddr() net.Addr { - return c.remoteAddr +func (c *sconn) capabilities() connCapabilities { + capabilities := c.rawConn.capabilities() + capabilities.GSO = !c.gotGSOError + return capabilities } -func (c *sconn) LocalAddr() net.Addr { - addr := c.rawConn.LocalAddr() - if c.info.addr.IsValid() { - if udpAddr, ok := addr.(*net.UDPAddr); ok { - addrCopy := *udpAddr - addrCopy.IP = c.info.addr.AsSlice() - addr = &addrCopy - } - } - return addr -} +func (c *sconn) RemoteAddr() net.Addr { return c.remoteAddr } +func (c *sconn) LocalAddr() net.Addr { return c.localAddr } diff --git a/send_conn_test.go b/send_conn_test.go index 56fe92366c9..8676d409274 100644 --- a/send_conn_test.go +++ b/send_conn_test.go @@ -2,46 +2,81 @@ package quic import ( "net" + "net/netip" + "github.com/quic-go/quic-go/internal/utils" + + "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) -var _ = Describe("Connection (for sending packets)", func() { - var ( - c sendConn - packetConn *MockPacketConn - addr net.Addr - ) - - BeforeEach(func() { - addr = &net.UDPAddr{IP: net.IPv4(192, 168, 100, 200), Port: 1337} - packetConn = NewMockPacketConn(mockCtrl) - rawConn, err := wrapConn(packetConn) - Expect(err).ToNot(HaveOccurred()) - c = newSendConnWithPacketInfo(rawConn, addr, packetInfo{}) - }) +// Only if appendUDPSegmentSizeMsg actually appends a message (and isn't only a stub implementation), +// GSO is actually supported on this platform. +var platformSupportsGSO = len(appendUDPSegmentSizeMsg([]byte{}, 1337)) > 0 - It("writes", func() { - packetConn.EXPECT().WriteTo([]byte("foobar"), addr) - Expect(c.Write([]byte("foobar"), 6)).To(Succeed()) - }) +var _ = Describe("Connection (for sending packets)", func() { + remoteAddr := &net.UDPAddr{IP: net.IPv4(192, 168, 100, 200), Port: 1337} - It("gets the remote address", func() { + It("gets the local and remote addresses", func() { + localAddr := &net.UDPAddr{IP: net.IPv4(192, 168, 0, 1), Port: 1234} + rawConn := NewMockRawConn(mockCtrl) + rawConn.EXPECT().LocalAddr().Return(localAddr) + c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) + Expect(c.LocalAddr().String()).To(Equal("192.168.0.1:1234")) Expect(c.RemoteAddr().String()).To(Equal("192.168.100.200:1337")) }) - It("gets the local address", func() { - addr := &net.UDPAddr{ - IP: net.IPv4(192, 168, 0, 1), - Port: 1234, - } - packetConn.EXPECT().LocalAddr().Return(addr) - Expect(c.LocalAddr()).To(Equal(addr)) + It("uses the local address from the packet info", func() { + localAddr := &net.UDPAddr{IP: net.IPv4(192, 168, 0, 1), Port: 1234} + rawConn := NewMockRawConn(mockCtrl) + rawConn.EXPECT().LocalAddr().Return(localAddr) + c := newSendConn(rawConn, remoteAddr, packetInfo{addr: netip.AddrFrom4([4]byte{127, 0, 0, 42})}, utils.DefaultLogger) + Expect(c.LocalAddr().String()).To(Equal("127.0.0.42:1234")) }) - It("closes", func() { - packetConn.EXPECT().Close() - Expect(c.Close()).To(Succeed()) - }) + if platformSupportsGSO { + It("writes with GSO", func() { + rawConn := NewMockRawConn(mockCtrl) + rawConn.EXPECT().LocalAddr() + rawConn.EXPECT().capabilities().Return(connCapabilities{GSO: true}).AnyTimes() + c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any()).Do(func(_ []byte, _ net.Addr, oob []byte) { + msg := appendUDPSegmentSizeMsg([]byte{}, 3) + Expect(oob).To(Equal(msg)) + }) + Expect(c.Write([]byte("foobar"), 3)).To(Succeed()) + }) + + It("disables GSO if writing fails", func() { + rawConn := NewMockRawConn(mockCtrl) + rawConn.EXPECT().LocalAddr() + rawConn.EXPECT().capabilities().Return(connCapabilities{GSO: true}).AnyTimes() + c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) + Expect(c.capabilities().GSO).To(BeTrue()) + gomock.InOrder( + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any()).DoAndReturn(func(_ []byte, _ net.Addr, oob []byte) (int, error) { + msg := appendUDPSegmentSizeMsg([]byte{}, 3) + Expect(oob).To(Equal(msg)) + return 0, errGSO + }), + rawConn.EXPECT().WritePacket([]byte("foo"), remoteAddr, []byte{}).Return(3, nil), + rawConn.EXPECT().WritePacket([]byte("bar"), remoteAddr, []byte{}).Return(3, nil), + ) + Expect(c.Write([]byte("foobar"), 3)).To(Succeed()) + Expect(c.capabilities().GSO).To(BeFalse()) // GSO support is now disabled + // make sure we actually enforce that + Expect(func() { c.Write([]byte("foobar"), 3) }).To(PanicWith("inconsistent packet size (6 vs 3)")) + }) + } else { + It("writes without GSO", func() { + remoteAddr := &net.UDPAddr{IP: net.IPv4(192, 168, 100, 200), Port: 1337} + rawConn := NewMockRawConn(mockCtrl) + rawConn.EXPECT().LocalAddr() + rawConn.EXPECT().capabilities() + c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, nil) + Expect(c.Write([]byte("foobar"), 6)).To(Succeed()) + }) + } }) diff --git a/server.go b/server.go index 0f8219e3ae3..c06228c9172 100644 --- a/server.go +++ b/server.go @@ -632,7 +632,7 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error tracer = config.Tracer(context.WithValue(context.Background(), ConnectionTracingKey, tracingID), protocol.PerspectiveServer, connID) } conn = s.newConn( - newSendConnWithPacketInfo(s.conn, p.remoteAddr, p.info), + newSendConn(s.conn, p.remoteAddr, p.info, s.logger), s.connHandler, origDestConnID, retrySrcConnID, @@ -742,7 +742,7 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info packe if s.tracer != nil { s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(buf.Data)), nil) } - _, err = s.conn.WritePacket(buf.Data, uint16(len(buf.Data)), remoteAddr, info.OOB()) + _, err = s.conn.WritePacket(buf.Data, remoteAddr, info.OOB()) return err } @@ -841,7 +841,7 @@ func (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer han if s.tracer != nil { s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(b.Data)), []logging.Frame{ccf}) } - _, err = s.conn.WritePacket(b.Data, uint16(len(b.Data)), remoteAddr, info.OOB()) + _, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB()) return err } @@ -879,7 +879,7 @@ func (s *baseServer) maybeSendVersionNegotiationPacket(p receivedPacket) { if s.tracer != nil { s.tracer.SentVersionNegotiationPacket(p.remoteAddr, src, dest, s.config.Versions) } - if _, err := s.conn.WritePacket(data, uint16(len(data)), p.remoteAddr, p.info.OOB()); err != nil { + if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB()); err != nil { s.logger.Debugf("Error sending Version Negotiation: %s", err) } } diff --git a/sys_conn.go b/sys_conn.go index 414472e71f9..f2224e4cc23 100644 --- a/sys_conn.go +++ b/sys_conn.go @@ -1,7 +1,6 @@ package quic import ( - "fmt" "log" "net" "os" @@ -105,10 +104,7 @@ func (c *basicConn) ReadPacket() (receivedPacket, error) { }, nil } -func (c *basicConn) WritePacket(b []byte, packetSize uint16, addr net.Addr, _ []byte) (n int, err error) { - if uint16(len(b)) != packetSize { - panic(fmt.Sprintf("inconsistent length. got: %d. expected %d", packetSize, len(b))) - } +func (c *basicConn) WritePacket(b []byte, addr net.Addr, _ []byte) (n int, err error) { return c.PacketConn.WriteTo(b, addr) } diff --git a/sys_conn_df_linux.go b/sys_conn_df_linux.go index 199f63474c0..f09eaa5dff8 100644 --- a/sys_conn_df_linux.go +++ b/sys_conn_df_linux.go @@ -4,11 +4,7 @@ package quic import ( "errors" - "log" - "os" - "strconv" "syscall" - "unsafe" "golang.org/x/sys/unix" @@ -38,43 +34,9 @@ func setDF(rawConn syscall.RawConn) (bool, error) { return true, nil } -func maybeSetGSO(rawConn syscall.RawConn) bool { - enable, _ := strconv.ParseBool(os.Getenv("QUIC_GO_ENABLE_GSO")) - if !enable { - return false - } - - var setErr error - if err := rawConn.Control(func(fd uintptr) { - setErr = unix.SetsockoptInt(int(fd), syscall.IPPROTO_UDP, unix.UDP_SEGMENT, 1) - }); err != nil { - setErr = err - } - if setErr != nil { - log.Println("failed to enable GSO") - return false - } - return true -} - func isSendMsgSizeErr(err error) bool { // https://man7.org/linux/man-pages/man7/udp.7.html return errors.Is(err, unix.EMSGSIZE) } -func isRecvMsgSizeErr(err error) bool { return false } - -func appendUDPSegmentSizeMsg(b []byte, size uint16) []byte { - startLen := len(b) - const dataLen = 2 // payload is a uint16 - b = append(b, make([]byte, unix.CmsgSpace(dataLen))...) - h := (*unix.Cmsghdr)(unsafe.Pointer(&b[startLen])) - h.Level = syscall.IPPROTO_UDP - h.Type = unix.UDP_SEGMENT - h.SetLen(unix.CmsgLen(dataLen)) - - // UnixRights uses the private `data` method, but I *think* this achieves the same goal. - offset := startLen + unix.CmsgSpace(0) - *(*uint16)(unsafe.Pointer(&b[offset])) = size - return b -} +func isRecvMsgSizeErr(error) bool { return false } diff --git a/sys_conn_helper_linux.go b/sys_conn_helper_linux.go index 61224eaaf78..4e87bba05bc 100644 --- a/sys_conn_helper_linux.go +++ b/sys_conn_helper_linux.go @@ -4,8 +4,11 @@ package quic import ( "encoding/binary" + "errors" "net/netip" + "os" "syscall" + "unsafe" "golang.org/x/sys/unix" ) @@ -48,3 +51,30 @@ func parseIPv4PktInfo(body []byte) (ip netip.Addr, ifIndex uint32, ok bool) { } return netip.AddrFrom4(*(*[4]byte)(body[8:12])), binary.LittleEndian.Uint32(body), true } + +func appendUDPSegmentSizeMsg(b []byte, size uint16) []byte { + startLen := len(b) + const dataLen = 2 // payload is a uint16 + b = append(b, make([]byte, unix.CmsgSpace(dataLen))...) + h := (*unix.Cmsghdr)(unsafe.Pointer(&b[startLen])) + h.Level = syscall.IPPROTO_UDP + h.Type = unix.UDP_SEGMENT + h.SetLen(unix.CmsgLen(dataLen)) + + // UnixRights uses the private `data` method, but I *think* this achieves the same goal. + offset := startLen + unix.CmsgSpace(0) + *(*uint16)(unsafe.Pointer(&b[offset])) = size + return b +} + +func isGSOError(err error) bool { + var serr *os.SyscallError + if errors.As(err, &serr) { + // EIO is returned by udp_send_skb() if the device driver does not have tx checksums enabled, + // which is a hard requirement of UDP_SEGMENT. See: + // https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man7/udp.7?id=806eabd74910447f21005160e90957bde4db0183#n228 + // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv4/udp.c?h=v6.2&id=c9c3395d5e3dcc6daee66c6908354d47bf98cb0c#n942 + return serr.Err == unix.EIO + } + return false +} diff --git a/sys_conn_helper_linux_test.go b/sys_conn_helper_linux_test.go index fa39c52339d..4cf59abe22c 100644 --- a/sys_conn_helper_linux_test.go +++ b/sys_conn_helper_linux_test.go @@ -1,22 +1,24 @@ -// We need root permissions to use RCVBUFFORCE. -// This test is therefore only compiled when the root build flag is set. -// It can only succeed if the tests are then also run with root permissions. -//go:build linux && root +//go:build linux package quic import ( + "errors" "net" "os" + "golang.org/x/sys/unix" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) +var errGSO = &os.SyscallError{Err: unix.EIO} + var _ = Describe("forcing a change of send and receive buffer sizes", func() { It("forces a change of the receive buffer size", func() { if os.Getuid() != 0 { - Fail("Must be root to force change the receive buffer size") + Skip("Must be root to force change the receive buffer size") } c, err := net.ListenPacket("udp", "127.0.0.1:0") @@ -43,7 +45,7 @@ var _ = Describe("forcing a change of send and receive buffer sizes", func() { It("forces a change of the send buffer size", func() { if os.Getuid() != 0 { - Fail("Must be root to force change the send buffer size") + Skip("Must be root to force change the send buffer size") } c, err := net.ListenPacket("udp", "127.0.0.1:0") @@ -67,4 +69,10 @@ var _ = Describe("forcing a change of send and receive buffer sizes", func() { // The kernel doubles this value (to allow space for bookkeeping overhead) Expect(size).To(Equal(2 * large)) }) + + It("detects GSO errors", func() { + Expect(isGSOError(errGSO)).To(BeTrue()) + Expect(isGSOError(nil)).To(BeFalse()) + Expect(isGSOError(errors.New("test"))).To(BeFalse()) + }) }) diff --git a/sys_conn_helper_nonlinux.go b/sys_conn_helper_nonlinux.go index 80b795c338e..48ab10aa972 100644 --- a/sys_conn_helper_nonlinux.go +++ b/sys_conn_helper_nonlinux.go @@ -4,3 +4,6 @@ package quic func forceSetReceiveBuffer(c any, bytes int) error { return nil } func forceSetSendBuffer(c any, bytes int) error { return nil } + +func appendUDPSegmentSizeMsg(_ []byte, _ uint16) []byte { return nil } +func isGSOError(error) bool { return false } diff --git a/sys_conn_helper_nonlinux_test.go b/sys_conn_helper_nonlinux_test.go new file mode 100644 index 00000000000..29d42ad33ab --- /dev/null +++ b/sys_conn_helper_nonlinux_test.go @@ -0,0 +1,7 @@ +//go:build !linux + +package quic + +import "errors" + +var errGSO = errors.New("fake GSO error") diff --git a/sys_conn_no_gso.go b/sys_conn_no_gso.go deleted file mode 100644 index 6f6a8c917ee..00000000000 --- a/sys_conn_no_gso.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build darwin || freebsd - -package quic - -import "syscall" - -func maybeSetGSO(_ syscall.RawConn) bool { return false } -func appendUDPSegmentSizeMsg(_ []byte, _ uint16) []byte { return nil } diff --git a/sys_conn_oob.go b/sys_conn_oob.go index 84d5e7e6492..aa69262b2e7 100644 --- a/sys_conn_oob.go +++ b/sys_conn_oob.go @@ -5,7 +5,6 @@ package quic import ( "encoding/binary" "errors" - "fmt" "log" "net" "net/netip" @@ -128,10 +127,6 @@ func newConn(c OOBCapablePacketConn, supportsDF bool) (*oobConn, error) { bc = ipv4.NewPacketConn(c) } - // Try enabling GSO. - // This will only succeed on Linux, and only for kernels > 4.18. - supportsGSO := maybeSetGSO(rawConn) - msgs := make([]ipv4.Message, batchSize) for i := range msgs { // preallocate the [][]byte @@ -144,7 +139,6 @@ func newConn(c OOBCapablePacketConn, supportsDF bool) (*oobConn, error) { readPos: batchSize, } oobConn.cap.DF = supportsDF - oobConn.cap.GSO = supportsGSO for i := 0; i < batchSize; i++ { oobConn.messages[i].OOB = make([]byte, oobBufferSize) } @@ -231,17 +225,9 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) { } // WritePacket writes a new packet. -// If the connection supports GSO (and we activated GSO support before), -// it appends the UDP_SEGMENT size message to oob. -// Callers are advised to make sure that oob has a sufficient capacity, -// such that appending the UDP_SEGMENT size message doesn't cause an allocation. -func (c *oobConn) WritePacket(b []byte, packetSize uint16, addr net.Addr, oob []byte) (n int, err error) { - if c.cap.GSO { - oob = appendUDPSegmentSizeMsg(oob, packetSize) - } else if uint16(len(b)) != packetSize { - panic(fmt.Sprintf("inconsistent length. got: %d. expected %d", packetSize, len(b))) - } - n, _, err = c.OOBCapablePacketConn.WriteMsgUDP(b, oob, addr.(*net.UDPAddr)) +// If the connection supports GSO, it's the caller's responsibility to append the right control mesage. +func (c *oobConn) WritePacket(b []byte, addr net.Addr, oob []byte) (int, error) { + n, _, err := c.OOBCapablePacketConn.WriteMsgUDP(b, oob, addr.(*net.UDPAddr)) return n, err } diff --git a/transport.go b/transport.go index 42fafd49381..ae44e3da638 100644 --- a/transport.go +++ b/transport.go @@ -179,7 +179,7 @@ func (t *Transport) dial(ctx context.Context, addr net.Addr, hostname string, tl } tlsConf.ServerName = hostname } - return dial(ctx, newSendConn(t.conn, addr), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, use0RTT) + return dial(ctx, newSendConn(t.conn, addr, packetInfo{}, utils.DefaultLogger), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, use0RTT) } func (t *Transport) init(allowZeroLengthConnIDs bool) error { @@ -195,7 +195,6 @@ func (t *Transport) init(allowZeroLengthConnIDs bool) error { return } } - t.conn = conn t.logger = utils.DefaultLogger // TODO: make this configurable t.conn = conn @@ -229,7 +228,7 @@ func (t *Transport) WriteTo(b []byte, addr net.Addr) (int, error) { if err := t.init(false); err != nil { return 0, err } - return t.conn.WritePacket(b, uint16(len(b)), addr, nil) + return t.conn.WritePacket(b, addr, nil) } func (t *Transport) enqueueClosePacket(p closePacket) { @@ -247,7 +246,7 @@ func (t *Transport) runSendQueue() { case <-t.listening: return case p := <-t.closeQueue: - t.conn.WritePacket(p.payload, uint16(len(p.payload)), p.addr, p.info.OOB()) + t.conn.WritePacket(p.payload, p.addr, p.info.OOB()) case p := <-t.statelessResetQueue: t.sendStatelessReset(p) } @@ -408,7 +407,7 @@ func (t *Transport) sendStatelessReset(p receivedPacket) { rand.Read(data) data[0] = (data[0] & 0x7f) | 0x40 data = append(data, token[:]...) - if _, err := t.conn.WritePacket(data, uint16(len(data)), p.remoteAddr, p.info.OOB()); err != nil { + if _, err := t.conn.WritePacket(data, p.remoteAddr, p.info.OOB()); err != nil { t.logger.Debugf("Error sending Stateless Reset to %s: %s", p.remoteAddr, err) } } From 3a3169551bf6b579fd8e5044479abf6bbfc3bbea Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 30 Jul 2023 16:31:30 -0400 Subject: [PATCH 020/225] detect kernel GSO support --- send_conn.go | 4 +++- send_conn_test.go | 6 +++--- sys_conn_helper_darwin.go | 3 +++ sys_conn_helper_freebsd.go | 3 +++ sys_conn_helper_linux.go | 12 ++++++++++++ sys_conn_helper_nonlinux.go | 4 ++-- sys_conn_oob.go | 5 ++++- 7 files changed, 30 insertions(+), 7 deletions(-) diff --git a/send_conn.go b/send_conn.go index 34cbfd6e23d..d8ddbc871ac 100644 --- a/send_conn.go +++ b/send_conn.go @@ -97,7 +97,9 @@ func (c *sconn) Write(p []byte, size protocol.ByteCount) error { func (c *sconn) capabilities() connCapabilities { capabilities := c.rawConn.capabilities() - capabilities.GSO = !c.gotGSOError + if capabilities.GSO { + capabilities.GSO = !c.gotGSOError + } return capabilities } diff --git a/send_conn_test.go b/send_conn_test.go index 8676d409274..024a8eba07b 100644 --- a/send_conn_test.go +++ b/send_conn_test.go @@ -60,8 +60,8 @@ var _ = Describe("Connection (for sending packets)", func() { Expect(oob).To(Equal(msg)) return 0, errGSO }), - rawConn.EXPECT().WritePacket([]byte("foo"), remoteAddr, []byte{}).Return(3, nil), - rawConn.EXPECT().WritePacket([]byte("bar"), remoteAddr, []byte{}).Return(3, nil), + rawConn.EXPECT().WritePacket([]byte("foo"), remoteAddr, gomock.Len(0)).Return(3, nil), + rawConn.EXPECT().WritePacket([]byte("bar"), remoteAddr, gomock.Len(0)).Return(3, nil), ) Expect(c.Write([]byte("foobar"), 3)).To(Succeed()) Expect(c.capabilities().GSO).To(BeFalse()) // GSO support is now disabled @@ -75,7 +75,7 @@ var _ = Describe("Connection (for sending packets)", func() { rawConn.EXPECT().LocalAddr() rawConn.EXPECT().capabilities() c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) - rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, nil) + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Len(0)) Expect(c.Write([]byte("foobar"), 6)).To(Succeed()) }) } diff --git a/sys_conn_helper_darwin.go b/sys_conn_helper_darwin.go index bf735f0f5b6..758cf77889f 100644 --- a/sys_conn_helper_darwin.go +++ b/sys_conn_helper_darwin.go @@ -5,6 +5,7 @@ package quic import ( "encoding/binary" "net/netip" + "syscall" "golang.org/x/sys/unix" ) @@ -29,3 +30,5 @@ func parseIPv4PktInfo(body []byte) (ip netip.Addr, ifIndex uint32, ok bool) { } return netip.AddrFrom4(*(*[4]byte)(body[8:12])), binary.LittleEndian.Uint32(body), true } + +func isGSOSupported(syscall.RawConn) bool { return false } diff --git a/sys_conn_helper_freebsd.go b/sys_conn_helper_freebsd.go index fe5a7c20edb..a2baae3b38e 100644 --- a/sys_conn_helper_freebsd.go +++ b/sys_conn_helper_freebsd.go @@ -4,6 +4,7 @@ package quic import ( "net/netip" + "syscall" "golang.org/x/sys/unix" ) @@ -24,3 +25,5 @@ func parseIPv4PktInfo(body []byte) (ip netip.Addr, _ uint32, ok bool) { } return netip.AddrFrom4(*(*[4]byte)(body)), 0, true } + +func isGSOSupported(syscall.RawConn) bool { return false } diff --git a/sys_conn_helper_linux.go b/sys_conn_helper_linux.go index 4e87bba05bc..5a177c29dca 100644 --- a/sys_conn_helper_linux.go +++ b/sys_conn_helper_linux.go @@ -52,6 +52,18 @@ func parseIPv4PktInfo(body []byte) (ip netip.Addr, ifIndex uint32, ok bool) { return netip.AddrFrom4(*(*[4]byte)(body[8:12])), binary.LittleEndian.Uint32(body), true } +// isGSOSupported tests if the kernel supports GSO. +// Sending with GSO might still fail later on, if the interface doesn't support it (see isGSOError). +func isGSOSupported(conn syscall.RawConn) bool { + var serr error + if err := conn.Control(func(fd uintptr) { + _, serr = unix.GetsockoptInt(int(fd), unix.IPPROTO_UDP, unix.UDP_SEGMENT) + }); err != nil { + return false + } + return serr == nil +} + func appendUDPSegmentSizeMsg(b []byte, size uint16) []byte { startLen := len(b) const dataLen = 2 // payload is a uint16 diff --git a/sys_conn_helper_nonlinux.go b/sys_conn_helper_nonlinux.go index 48ab10aa972..cace82d5dcc 100644 --- a/sys_conn_helper_nonlinux.go +++ b/sys_conn_helper_nonlinux.go @@ -5,5 +5,5 @@ package quic func forceSetReceiveBuffer(c any, bytes int) error { return nil } func forceSetSendBuffer(c any, bytes int) error { return nil } -func appendUDPSegmentSizeMsg(_ []byte, _ uint16) []byte { return nil } -func isGSOError(error) bool { return false } +func appendUDPSegmentSizeMsg([]byte, uint16) []byte { return nil } +func isGSOError(error) bool { return false } diff --git a/sys_conn_oob.go b/sys_conn_oob.go index aa69262b2e7..4026a7b32c3 100644 --- a/sys_conn_oob.go +++ b/sys_conn_oob.go @@ -137,8 +137,11 @@ func newConn(c OOBCapablePacketConn, supportsDF bool) (*oobConn, error) { batchConn: bc, messages: msgs, readPos: batchSize, + cap: connCapabilities{ + DF: supportsDF, + GSO: isGSOSupported(rawConn), + }, } - oobConn.cap.DF = supportsDF for i := 0; i < batchSize; i++ { oobConn.messages[i].OOB = make([]byte, oobBufferSize) } From 5200f27dcfa7146b6585d292befbbe23cfa55777 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 6 Aug 2023 18:22:47 -0400 Subject: [PATCH 021/225] add QUIC_GO_DISABLE_GSO env to disable GSO --- sys_conn_helper_linux.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sys_conn_helper_linux.go b/sys_conn_helper_linux.go index 5a177c29dca..5bda2286c49 100644 --- a/sys_conn_helper_linux.go +++ b/sys_conn_helper_linux.go @@ -7,12 +7,22 @@ import ( "errors" "net/netip" "os" + "strconv" "syscall" "unsafe" "golang.org/x/sys/unix" ) +var gsoDisabled bool + +func init() { + disabled, err := strconv.ParseBool(os.Getenv("QUIC_GO_DISABLE_GSO")) + if err == nil { + gsoDisabled = disabled + } +} + const ( msgTypeIPTOS = unix.IP_TOS ipv4PKTINFO = unix.IP_PKTINFO @@ -55,6 +65,9 @@ func parseIPv4PktInfo(body []byte) (ip netip.Addr, ifIndex uint32, ok bool) { // isGSOSupported tests if the kernel supports GSO. // Sending with GSO might still fail later on, if the interface doesn't support it (see isGSOError). func isGSOSupported(conn syscall.RawConn) bool { + if gsoDisabled { + return false + } var serr error if err := conn.Control(func(fd uintptr) { _, serr = unix.GetsockoptInt(int(fd), unix.IPPROTO_UDP, unix.UDP_SEGMENT) From 3822dae9bbb1baee54b71e3a5a5a585c62680a0d Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 17 Aug 2023 12:26:36 +0700 Subject: [PATCH 022/225] handshake fuzzer: fix setting of cipher suites (#4037) --- fuzzing/handshake/fuzz.go | 44 +++++++++++++-------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/fuzzing/handshake/fuzz.go b/fuzzing/handshake/fuzz.go index 93cec975c87..a3f549eec7f 100644 --- a/fuzzing/handshake/fuzz.go +++ b/fuzzing/handshake/fuzz.go @@ -17,6 +17,7 @@ import ( "github.com/quic-go/quic-go/fuzzing/internal/helper" "github.com/quic-go/quic-go/internal/handshake" "github.com/quic-go/quic-go/internal/protocol" + "github.com/quic-go/quic-go/internal/qtls" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" ) @@ -84,33 +85,6 @@ func (m messageType) String() string { } } -func appendSuites(suites []uint16, rand uint8) []uint16 { - const ( - s1 = tls.TLS_AES_128_GCM_SHA256 - s2 = tls.TLS_AES_256_GCM_SHA384 - s3 = tls.TLS_CHACHA20_POLY1305_SHA256 - ) - switch rand % 4 { - default: - return suites - case 1: - return append(suites, s1) - case 2: - return append(suites, s2) - case 3: - return append(suites, s3) - } -} - -// consumes 2 bits -func getSuites(rand uint8) []uint16 { - suites := make([]uint16, 0, 3) - for i := 1; i <= 3; i++ { - suites = appendSuites(suites, rand>>i%4) - } - return suites -} - // consumes 3 bits func getClientAuth(rand uint8) tls.ClientAuthType { switch rand { @@ -207,14 +181,26 @@ func runHandshake(runConfig [confLen]byte, messageConfig uint8, clientConf *tls. SessionTicketKey: sessionTicketKey, } + // This sets the cipher suite for both client and server. + // The way crypto/tls is designed doesn't allow us to set different cipher suites for client and server. + resetCipherSuite := func() {} + switch (runConfig[0] >> 6) % 4 { + case 0: + resetCipherSuite = qtls.SetCipherSuite(tls.TLS_AES_128_GCM_SHA256) + case 1: + resetCipherSuite = qtls.SetCipherSuite(tls.TLS_AES_256_GCM_SHA384) + case 3: + resetCipherSuite = qtls.SetCipherSuite(tls.TLS_CHACHA20_POLY1305_SHA256) + default: + } + defer resetCipherSuite() + enable0RTTClient := helper.NthBit(runConfig[0], 0) enable0RTTServer := helper.NthBit(runConfig[0], 1) sendPostHandshakeMessageToClient := helper.NthBit(runConfig[0], 3) sendPostHandshakeMessageToServer := helper.NthBit(runConfig[0], 4) sendSessionTicket := helper.NthBit(runConfig[0], 5) - clientConf.CipherSuites = getSuites(runConfig[0] >> 6) serverConf.ClientAuth = getClientAuth(runConfig[1] & 0b00000111) - serverConf.CipherSuites = getSuites(runConfig[1] >> 6) serverConf.SessionTicketsDisabled = helper.NthBit(runConfig[1], 3) if helper.NthBit(runConfig[2], 0) { clientConf.RootCAs = x509.NewCertPool() From 501cc21c4b7ff3bf3b37a20b4f78fabb741aa046 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 18 Aug 2023 17:01:49 +0700 Subject: [PATCH 023/225] expose crypto/tls errors on the TransportError (#4015) --- go.mod | 2 +- go.sum | 4 ++-- integrationtests/gomodvendor/go.sum | 4 ++-- integrationtests/self/handshake_test.go | 2 ++ internal/handshake/crypto_setup.go | 3 ++- internal/qerr/errors.go | 14 +++++++++++--- internal/qerr/errors_test.go | 21 ++++++++++++++++++--- packet_packer_test.go | 3 ++- 8 files changed, 40 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 2f2a0ff0b62..106c90fd006 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/onsi/ginkgo/v2 v2.9.5 github.com/onsi/gomega v1.27.6 github.com/quic-go/qpack v0.4.0 - github.com/quic-go/qtls-go1-20 v0.3.1 + github.com/quic-go/qtls-go1-20 v0.3.2 golang.org/x/crypto v0.4.0 golang.org/x/exp v0.0.0-20221205204356-47842c84f3db golang.org/x/net v0.10.0 diff --git a/go.sum b/go.sum index c0ed9606da1..f28b844c5b2 100644 --- a/go.sum +++ b/go.sum @@ -90,8 +90,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.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= -github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= +github.com/quic-go/qtls-go1-20 v0.3.2/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= diff --git a/integrationtests/gomodvendor/go.sum b/integrationtests/gomodvendor/go.sum index ad9adb3117c..ab32e13898c 100644 --- a/integrationtests/gomodvendor/go.sum +++ b/integrationtests/gomodvendor/go.sum @@ -136,8 +136,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.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= -github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= +github.com/quic-go/qtls-go1-20 v0.3.2/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= diff --git a/integrationtests/self/handshake_test.go b/integrationtests/self/handshake_test.go index 951c4c7ab66..8123c8fe043 100644 --- a/integrationtests/self/handshake_test.go +++ b/integrationtests/self/handshake_test.go @@ -202,6 +202,8 @@ var _ = Describe("Handshake tests", func() { Expect(errors.As(err, &transportErr)).To(BeTrue()) Expect(transportErr.ErrorCode.IsCryptoError()).To(BeTrue()) Expect(transportErr.Error()).To(ContainSubstring("x509: certificate is valid for localhost, not foo.bar")) + var certErr *tls.CertificateVerificationError + Expect(errors.As(transportErr, &certErr)).To(BeTrue()) }) It("fails the handshake if the client fails to provide the requested client cert", func() { diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index a1179257b5a..332dbd7ef56 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -664,8 +664,9 @@ func (h *cryptoSetup) ConnectionState() ConnectionState { } func wrapError(err error) error { + // alert 80 is an internal error if alertErr := qtls.AlertError(0); errors.As(err, &alertErr) && alertErr != 80 { - return qerr.NewLocalCryptoError(uint8(alertErr), err.Error()) + return qerr.NewLocalCryptoError(uint8(alertErr), err) } return &qerr.TransportError{ErrorCode: qerr.InternalError, ErrorMessage: err.Error()} } diff --git a/internal/qerr/errors.go b/internal/qerr/errors.go index 26ea344521b..2d8511f7765 100644 --- a/internal/qerr/errors.go +++ b/internal/qerr/errors.go @@ -17,15 +17,16 @@ type TransportError struct { FrameType uint64 ErrorCode TransportErrorCode ErrorMessage string + error error // only set for local errors, sometimes } var _ error = &TransportError{} // NewLocalCryptoError create a new TransportError instance for a crypto error -func NewLocalCryptoError(tlsAlert uint8, errorMessage string) *TransportError { +func NewLocalCryptoError(tlsAlert uint8, err error) *TransportError { return &TransportError{ - ErrorCode: 0x100 + TransportErrorCode(tlsAlert), - ErrorMessage: errorMessage, + ErrorCode: 0x100 + TransportErrorCode(tlsAlert), + error: err, } } @@ -35,6 +36,9 @@ func (e *TransportError) Error() string { str += fmt.Sprintf(" (frame type: %#x)", e.FrameType) } msg := e.ErrorMessage + if len(msg) == 0 && e.error != nil { + msg = e.error.Error() + } if len(msg) == 0 { msg = e.ErrorCode.Message() } @@ -48,6 +52,10 @@ func (e *TransportError) Is(target error) bool { return target == net.ErrClosed } +func (e *TransportError) Unwrap() error { + return e.error +} + // An ApplicationErrorCode is an application-defined error code. type ApplicationErrorCode uint64 diff --git a/internal/qerr/errors_test.go b/internal/qerr/errors_test.go index 52d5c9e9fbc..770ebd684d8 100644 --- a/internal/qerr/errors_test.go +++ b/internal/qerr/errors_test.go @@ -2,6 +2,7 @@ package qerr import ( "errors" + "fmt" "net" "github.com/quic-go/quic-go/internal/protocol" @@ -10,6 +11,12 @@ import ( . "github.com/onsi/gomega" ) +type myError int + +var _ error = myError(0) + +func (e myError) Error() string { return fmt.Sprintf("my error %d", e) } + var _ = Describe("QUIC Errors", func() { Context("Transport Errors", func() { It("has a string representation", func() { @@ -41,12 +48,20 @@ var _ = Describe("QUIC Errors", func() { Context("crypto errors", func() { It("has a string representation for errors with a message", func() { - err := NewLocalCryptoError(0x42, "foobar") - Expect(err.Error()).To(Equal("CRYPTO_ERROR 0x142 (local): foobar")) + myErr := myError(1337) + err := NewLocalCryptoError(0x42, myErr) + Expect(err.Error()).To(Equal("CRYPTO_ERROR 0x142 (local): my error 1337")) + }) + + It("unwraps errors", func() { + var myErr myError + err := NewLocalCryptoError(0x42, myError(1337)) + Expect(errors.As(err, &myErr)).To(BeTrue()) + Expect(myErr).To(BeEquivalentTo(1337)) }) It("has a string representation for errors without a message", func() { - err := NewLocalCryptoError(0x2a, "") + err := NewLocalCryptoError(0x2a, nil) Expect(err.Error()).To(Equal("CRYPTO_ERROR 0x12a (local): tls: bad certificate")) }) }) diff --git a/packet_packer_test.go b/packet_packer_test.go index 3ff15eaff03..38ced47ad55 100644 --- a/packet_packer_test.go +++ b/packet_packer_test.go @@ -2,6 +2,7 @@ package quic import ( "bytes" + "errors" "fmt" "net" "time" @@ -334,7 +335,7 @@ var _ = Describe("Packet packer", func() { sealingManager.EXPECT().GetInitialSealer().Return(nil, handshake.ErrKeysDropped) sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil) sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable) - quicErr := qerr.NewLocalCryptoError(0x42, "crypto error") + quicErr := qerr.NewLocalCryptoError(0x42, errors.New("crypto error")) quicErr.FrameType = 0x1234 p, err := packer.PackConnectionClose(quicErr, maxPacketSize, protocol.Version1) Expect(err).ToNot(HaveOccurred()) From 5c5db8cc599b11c9cef913f5a816f42b9ebd9dc6 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 19 Aug 2023 07:16:57 +0700 Subject: [PATCH 024/225] reassemble post-handshake TLS messages before passing them to crypto/tls (#4038) --- connection.go | 8 ++++---- crypto_stream.go | 25 +++++++++++++++++++++++-- crypto_stream_test.go | 22 +++++++++++++++++++++- fuzzing/handshake/fuzz.go | 1 + 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/connection.go b/connection.go index b17f3ce81a3..877f2d03311 100644 --- a/connection.go +++ b/connection.go @@ -243,7 +243,7 @@ var newConnection = func( handshakeDestConnID: destConnID, srcConnIDLen: srcConnID.Len(), tokenGenerator: tokenGenerator, - oneRTTStream: newCryptoStream(), + oneRTTStream: newCryptoStream(true), perspective: protocol.PerspectiveServer, tracer: tracer, logger: logger, @@ -391,7 +391,7 @@ var newClientConnection = func( s.logger, ) s.mtuDiscoverer = newMTUDiscoverer(s.rttStats, getMaxPacketSize(s.conn.RemoteAddr()), s.sentPacketHandler.SetMaxDatagramSize) - oneRTTStream := newCryptoStream() + oneRTTStream := newCryptoStream(true) params := &wire.TransportParameters{ InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamReceiveWindow), InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamReceiveWindow), @@ -447,8 +447,8 @@ var newClientConnection = func( } func (s *connection) preSetup() { - s.initialStream = newCryptoStream() - s.handshakeStream = newCryptoStream() + s.initialStream = newCryptoStream(false) + s.handshakeStream = newCryptoStream(false) s.sendQueue = newSendQueue(s.conn) s.retransmissionQueue = newRetransmissionQueue() s.frameParser = wire.NewFrameParser(s.config.EnableDatagrams) diff --git a/crypto_stream.go b/crypto_stream.go index 4be2a07ae1a..5ce2125decf 100644 --- a/crypto_stream.go +++ b/crypto_stream.go @@ -30,10 +30,17 @@ 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() cryptoStream { - return &cryptoStreamImpl{queue: newFrameSorter()} +func newCryptoStream(onlyCompleteMsg bool) cryptoStream { + return &cryptoStreamImpl{ + queue: newFrameSorter(), + onlyCompleteMsg: onlyCompleteMsg, + } } func (s *cryptoStreamImpl) HandleCryptoFrame(f *wire.CryptoFrame) error { @@ -71,6 +78,20 @@ 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 diff --git a/crypto_stream_test.go b/crypto_stream_test.go index 9a4a2ee57f9..67de9149966 100644 --- a/crypto_stream_test.go +++ b/crypto_stream_test.go @@ -1,6 +1,7 @@ package quic import ( + "crypto/rand" "fmt" "github.com/quic-go/quic-go/internal/protocol" @@ -15,7 +16,7 @@ var _ = Describe("Crypto Stream", func() { var str cryptoStream BeforeEach(func() { - str = newCryptoStream() + str = newCryptoStream(false) }) Context("handling incoming data", func() { @@ -137,4 +138,23 @@ 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)) + }) }) diff --git a/fuzzing/handshake/fuzz.go b/fuzzing/handshake/fuzz.go index a3f549eec7f..be34c22da9e 100644 --- a/fuzzing/handshake/fuzz.go +++ b/fuzzing/handshake/fuzz.go @@ -408,6 +408,7 @@ func runHandshake(runConfig [confLen]byte, messageConfig uint8, clientConf *tls. } client.HandleMessage(ticket, protocol.Encryption1RTT) } + if sendPostHandshakeMessageToClient { fmt.Println("sending post handshake message to the client at", messageToReplaceEncLevel) client.HandleMessage(data, messageToReplaceEncLevel) From 443c6148b6f6a48a421f1a07c9ef9c593aec535a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 19 Aug 2023 07:17:37 +0700 Subject: [PATCH 025/225] protocol: add string representation for ECN values (#4008) --- internal/protocol/protocol.go | 15 +++++++++++++++ internal/protocol/protocol_test.go | 8 ++++++++ 2 files changed, 23 insertions(+) diff --git a/internal/protocol/protocol.go b/internal/protocol/protocol.go index 98bc9ffbc58..b8104882bcc 100644 --- a/internal/protocol/protocol.go +++ b/internal/protocol/protocol.go @@ -43,6 +43,21 @@ const ( ECNCE // 11 ) +func (e ECN) String() string { + switch e { + case ECNNon: + return "Not-ECT" + case ECT1: + return "ECT(1)" + case ECT0: + return "ECT(0)" + case ECNCE: + return "CE" + default: + return fmt.Sprintf("invalid ECN value: %d", e) + } +} + // A ByteCount in QUIC type ByteCount int64 diff --git a/internal/protocol/protocol_test.go b/internal/protocol/protocol_test.go index d9048f01068..e672d31e147 100644 --- a/internal/protocol/protocol_test.go +++ b/internal/protocol/protocol_test.go @@ -22,4 +22,12 @@ var _ = Describe("Protocol", func() { Expect(ECN(0b00000001)).To(Equal(ECT1)) Expect(ECN(0b00000011)).To(Equal(ECNCE)) }) + + It("has a string representation for ECN", func() { + Expect(ECNNon.String()).To(Equal("Not-ECT")) + Expect(ECT0.String()).To(Equal("ECT(0)")) + Expect(ECT1.String()).To(Equal("ECT(1)")) + Expect(ECNCE.String()).To(Equal("CE")) + Expect(ECN(42).String()).To(Equal("invalid ECN value: 42")) + }) }) From 6880f88089d442d6eb739bcbb84875588896dc82 Mon Sep 17 00:00:00 2001 From: Ameagari <47713057+tanghaowillow@users.noreply.github.com> Date: Sat, 19 Aug 2023 10:16:16 +0800 Subject: [PATCH 026/225] save the max_datagram_frame_size transport parameter in the session ticket (#4013) * Add MaxDatagramFrameSize parameter in session ticket * fix gofumpt issues * Update integrationtests/self/zero_rtt_test.go Co-authored-by: Marten Seemann * fix: correct comparsion of max_datagram_frame_size * test: use constant MaxDatagramFrameSize for session ticket test * fix grammar --------- Co-authored-by: Marten Seemann --- integrationtests/self/zero_rtt_oldgo_test.go | 112 ++++++++++++++++++ integrationtests/self/zero_rtt_test.go | 115 +++++++++++++++++++ internal/handshake/session_ticket_test.go | 2 + internal/wire/transport_parameter_test.go | 24 ++++ internal/wire/transport_parameters.go | 10 ++ 5 files changed, 263 insertions(+) diff --git a/integrationtests/self/zero_rtt_oldgo_test.go b/integrationtests/self/zero_rtt_oldgo_test.go index beaf351e249..e5809286787 100644 --- a/integrationtests/self/zero_rtt_oldgo_test.go +++ b/integrationtests/self/zero_rtt_oldgo_test.go @@ -801,4 +801,116 @@ var _ = Describe("0-RTT", func() { Expect(len(zeroRTTPackets)).To(BeNumerically(">", 10)) Expect(zeroRTTPackets[0]).To(Equal(protocol.PacketNumber(0))) }) + + It("sends 0-RTT datagrams", func() { + tlsConf, clientTLSConf := dialAndReceiveSessionTicket(getQuicConfig(&quic.Config{ + EnableDatagrams: true, + })) + + tracer := newPacketTracer() + ln, err := quic.ListenAddrEarly( + "localhost:0", + tlsConf, + getQuicConfig(&quic.Config{ + Allow0RTT: true, + EnableDatagrams: true, + Tracer: newTracer(tracer), + }), + ) + Expect(err).ToNot(HaveOccurred()) + defer ln.Close() + + proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) + defer proxy.Close() + + // second connection + sentMessage := GeneratePRData(100) + var receivedMessage []byte + received := make(chan struct{}) + go func() { + defer GinkgoRecover() + defer close(received) + conn, err := ln.Accept(context.Background()) + Expect(err).ToNot(HaveOccurred()) + receivedMessage, err = conn.ReceiveMessage(context.Background()) + Expect(err).ToNot(HaveOccurred()) + Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) + }() + conn, err := quic.DialAddrEarly( + context.Background(), + fmt.Sprintf("localhost:%d", proxy.LocalPort()), + clientTLSConf, + getQuicConfig(&quic.Config{ + EnableDatagrams: true, + }), + ) + Expect(err).ToNot(HaveOccurred()) + Expect(conn.ConnectionState().SupportsDatagrams).To(BeTrue()) + Expect(conn.SendMessage(sentMessage)).To(Succeed()) + <-conn.HandshakeComplete() + <-received + + Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) + 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()) + 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() { + tlsConf, clientTLSConf := dialAndReceiveSessionTicket(getQuicConfig(&quic.Config{ + EnableDatagrams: true, + })) + + tracer := newPacketTracer() + ln, err := quic.ListenAddrEarly( + "localhost:0", + tlsConf, + getQuicConfig(&quic.Config{ + Allow0RTT: true, + EnableDatagrams: false, + Tracer: newTracer(tracer), + }), + ) + Expect(err).ToNot(HaveOccurred()) + defer ln.Close() + + proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) + defer proxy.Close() + + // second connection + go func() { + defer GinkgoRecover() + conn, err := ln.Accept(context.Background()) + Expect(err).ToNot(HaveOccurred()) + _, err = conn.ReceiveMessage(context.Background()) + Expect(err.Error()).To(Equal("datagram support disabled")) + <-conn.HandshakeComplete() + Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) + }() + conn, err := quic.DialAddrEarly( + context.Background(), + fmt.Sprintf("localhost:%d", proxy.LocalPort()), + clientTLSConf, + getQuicConfig(&quic.Config{ + EnableDatagrams: true, + }), + ) + Expect(err).ToNot(HaveOccurred()) + // the client can temporarily send datagrams but the server doesn't process them. + Expect(conn.ConnectionState().SupportsDatagrams).To(BeTrue()) + Expect(conn.SendMessage(make([]byte, 100))).To(Succeed()) + <-conn.HandshakeComplete() + + Expect(conn.ConnectionState().SupportsDatagrams).To(BeFalse()) + Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) + 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()) + }) }) diff --git a/integrationtests/self/zero_rtt_test.go b/integrationtests/self/zero_rtt_test.go index 2de283aca12..011687ae60f 100644 --- a/integrationtests/self/zero_rtt_test.go +++ b/integrationtests/self/zero_rtt_test.go @@ -938,4 +938,119 @@ var _ = Describe("0-RTT", func() { ) Expect(restored).To(BeTrue()) }) + + It("sends 0-RTT datagrams", func() { + tlsConf := getTLSConfig() + clientTLSConf := getTLSClientConfig() + dialAndReceiveSessionTicket(tlsConf, getQuicConfig(&quic.Config{ + EnableDatagrams: true, + }), clientTLSConf) + + tracer := newPacketTracer() + ln, err := quic.ListenAddrEarly( + "localhost:0", + tlsConf, + getQuicConfig(&quic.Config{ + Allow0RTT: true, + EnableDatagrams: true, + Tracer: newTracer(tracer), + }), + ) + Expect(err).ToNot(HaveOccurred()) + defer ln.Close() + proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) + defer proxy.Close() + + // second connection + sentMessage := GeneratePRData(100) + var receivedMessage []byte + received := make(chan struct{}) + go func() { + defer GinkgoRecover() + defer close(received) + conn, err := ln.Accept(context.Background()) + Expect(err).ToNot(HaveOccurred()) + receivedMessage, err = conn.ReceiveMessage(context.Background()) + Expect(err).ToNot(HaveOccurred()) + Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) + }() + conn, err := quic.DialAddrEarly( + context.Background(), + fmt.Sprintf("localhost:%d", proxy.LocalPort()), + clientTLSConf, + getQuicConfig(&quic.Config{ + EnableDatagrams: true, + }), + ) + Expect(err).ToNot(HaveOccurred()) + Expect(conn.ConnectionState().SupportsDatagrams).To(BeTrue()) + Expect(conn.SendMessage(sentMessage)).To(Succeed()) + <-conn.HandshakeComplete() + <-received + + Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) + 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()) + 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() { + tlsConf := getTLSConfig() + clientTLSConf := getTLSClientConfig() + dialAndReceiveSessionTicket(tlsConf, getQuicConfig(&quic.Config{ + EnableDatagrams: true, + }), clientTLSConf) + + tracer := newPacketTracer() + ln, err := quic.ListenAddrEarly( + "localhost:0", + tlsConf, + getQuicConfig(&quic.Config{ + Allow0RTT: true, + EnableDatagrams: false, + Tracer: newTracer(tracer), + }), + ) + Expect(err).ToNot(HaveOccurred()) + defer ln.Close() + + proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) + defer proxy.Close() + + // second connection + go func() { + defer GinkgoRecover() + conn, err := ln.Accept(context.Background()) + Expect(err).ToNot(HaveOccurred()) + _, err = conn.ReceiveMessage(context.Background()) + Expect(err.Error()).To(Equal("datagram support disabled")) + <-conn.HandshakeComplete() + Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) + }() + conn, err := quic.DialAddrEarly( + context.Background(), + fmt.Sprintf("localhost:%d", proxy.LocalPort()), + clientTLSConf, + getQuicConfig(&quic.Config{ + EnableDatagrams: true, + }), + ) + Expect(err).ToNot(HaveOccurred()) + // the client can temporarily send datagrams but the server doesn't process them. + Expect(conn.ConnectionState().SupportsDatagrams).To(BeTrue()) + Expect(conn.SendMessage(make([]byte, 100))).To(Succeed()) + <-conn.HandshakeComplete() + + Expect(conn.ConnectionState().SupportsDatagrams).To(BeFalse()) + Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) + 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()) + }) }) diff --git a/internal/handshake/session_ticket_test.go b/internal/handshake/session_ticket_test.go index 67e33b2252f..6f004de973d 100644 --- a/internal/handshake/session_ticket_test.go +++ b/internal/handshake/session_ticket_test.go @@ -17,6 +17,7 @@ var _ = Describe("Session Ticket", func() { InitialMaxStreamDataBidiLocal: 1, InitialMaxStreamDataBidiRemote: 2, ActiveConnectionIDLimit: 10, + MaxDatagramFrameSize: 20, }, RTT: 1337 * time.Microsecond, } @@ -25,6 +26,7 @@ var _ = Describe("Session Ticket", func() { 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)) }) diff --git a/internal/wire/transport_parameter_test.go b/internal/wire/transport_parameter_test.go index 9dd306b76ab..2fb795395db 100644 --- a/internal/wire/transport_parameter_test.go +++ b/internal/wire/transport_parameter_test.go @@ -503,6 +503,7 @@ var _ = Describe("Transport Parameters", func() { MaxBidiStreamNum: protocol.StreamNum(getRandomValueUpTo(int64(protocol.MaxStreamCount))), MaxUniStreamNum: protocol.StreamNum(getRandomValueUpTo(int64(protocol.MaxStreamCount))), ActiveConnectionIDLimit: 2 + getRandomValueUpTo(math.MaxInt64-2), + MaxDatagramFrameSize: protocol.ByteCount(getRandomValueUpTo(int64(protocol.MaxDatagramFrameSize))), } Expect(params.ValidFor0RTT(params)).To(BeTrue()) b := params.MarshalForSessionTicket(nil) @@ -515,6 +516,7 @@ var _ = Describe("Transport Parameters", func() { Expect(tp.MaxBidiStreamNum).To(Equal(params.MaxBidiStreamNum)) Expect(tp.MaxUniStreamNum).To(Equal(params.MaxUniStreamNum)) Expect(tp.ActiveConnectionIDLimit).To(Equal(params.ActiveConnectionIDLimit)) + Expect(tp.MaxDatagramFrameSize).To(Equal(params.MaxDatagramFrameSize)) }) It("rejects the parameters if it can't parse them", func() { @@ -540,6 +542,7 @@ var _ = Describe("Transport Parameters", func() { MaxBidiStreamNum: 5, MaxUniStreamNum: 6, ActiveConnectionIDLimit: 7, + MaxDatagramFrameSize: 1000, } BeforeEach(func() { @@ -611,6 +614,16 @@ var _ = Describe("Transport Parameters", func() { p.ActiveConnectionIDLimit = 0 Expect(p.ValidFor0RTT(saved)).To(BeFalse()) }) + + It("accepts the parameters if the MaxDatagramFrameSize was increased", func() { + p.MaxDatagramFrameSize = saved.MaxDatagramFrameSize + 1 + Expect(p.ValidFor0RTT(saved)).To(BeTrue()) + }) + + It("rejects the parameters if the MaxDatagramFrameSize reduced", func() { + p.MaxDatagramFrameSize = saved.MaxDatagramFrameSize - 1 + Expect(p.ValidFor0RTT(saved)).To(BeFalse()) + }) }) Context("client checks the parameters after successfully sending 0-RTT data", func() { @@ -623,6 +636,7 @@ var _ = Describe("Transport Parameters", func() { MaxBidiStreamNum: 5, MaxUniStreamNum: 6, ActiveConnectionIDLimit: 7, + MaxDatagramFrameSize: 1000, } BeforeEach(func() { @@ -699,6 +713,16 @@ var _ = Describe("Transport Parameters", func() { p.ActiveConnectionIDLimit = saved.ActiveConnectionIDLimit + 1 Expect(p.ValidForUpdate(saved)).To(BeTrue()) }) + + It("rejects the parameters if the MaxDatagramFrameSize reduced", func() { + p.MaxDatagramFrameSize = saved.MaxDatagramFrameSize - 1 + Expect(p.ValidForUpdate(saved)).To(BeFalse()) + }) + + It("doesn't reject the parameters if the MaxDatagramFrameSize increased", func() { + p.MaxDatagramFrameSize = saved.MaxDatagramFrameSize + 1 + Expect(p.ValidForUpdate(saved)).To(BeTrue()) + }) }) }) }) diff --git a/internal/wire/transport_parameters.go b/internal/wire/transport_parameters.go index dc0aa22f133..7226521b05a 100644 --- a/internal/wire/transport_parameters.go +++ b/internal/wire/transport_parameters.go @@ -454,6 +454,10 @@ func (p *TransportParameters) MarshalForSessionTicket(b []byte) []byte { b = p.marshalVarintParam(b, initialMaxStreamsBidiParameterID, uint64(p.MaxBidiStreamNum)) // initial_max_uni_streams b = p.marshalVarintParam(b, initialMaxStreamsUniParameterID, uint64(p.MaxUniStreamNum)) + // max_datagram_frame_size + if p.MaxDatagramFrameSize != protocol.InvalidByteCount { + b = p.marshalVarintParam(b, maxDatagramFrameSizeParameterID, uint64(p.MaxDatagramFrameSize)) + } // active_connection_id_limit return p.marshalVarintParam(b, activeConnectionIDLimitParameterID, p.ActiveConnectionIDLimit) } @@ -472,6 +476,9 @@ func (p *TransportParameters) UnmarshalFromSessionTicket(r *bytes.Reader) error // ValidFor0RTT checks if the transport parameters match those saved in the session ticket. func (p *TransportParameters) ValidFor0RTT(saved *TransportParameters) bool { + if saved.MaxDatagramFrameSize != protocol.InvalidByteCount && (p.MaxDatagramFrameSize == protocol.InvalidByteCount || p.MaxDatagramFrameSize < saved.MaxDatagramFrameSize) { + return false + } return p.InitialMaxStreamDataBidiLocal >= saved.InitialMaxStreamDataBidiLocal && p.InitialMaxStreamDataBidiRemote >= saved.InitialMaxStreamDataBidiRemote && p.InitialMaxStreamDataUni >= saved.InitialMaxStreamDataUni && @@ -484,6 +491,9 @@ func (p *TransportParameters) ValidFor0RTT(saved *TransportParameters) bool { // ValidForUpdate checks that the new transport parameters don't reduce limits after resuming a 0-RTT connection. // It is only used on the client side. func (p *TransportParameters) ValidForUpdate(saved *TransportParameters) bool { + if saved.MaxDatagramFrameSize != protocol.InvalidByteCount && (p.MaxDatagramFrameSize == protocol.InvalidByteCount || p.MaxDatagramFrameSize < saved.MaxDatagramFrameSize) { + return false + } return p.ActiveConnectionIDLimit >= saved.ActiveConnectionIDLimit && p.InitialMaxData >= saved.InitialMaxData && p.InitialMaxStreamDataBidiLocal >= saved.InitialMaxStreamDataBidiLocal && From fe3c4f271df1a713a2e98bff2c35f0804b63e801 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 19 Aug 2023 15:19:17 +0700 Subject: [PATCH 027/225] add a method to retrieve non-QUIC packets from the Transport (#3992) --- integrationtests/self/multiplex_test.go | 65 +++++++++++++++++++++ internal/wire/header.go | 4 ++ transport.go | 53 ++++++++++++++++- transport_test.go | 77 ++++++++++++++++++++++++- 4 files changed, 195 insertions(+), 4 deletions(-) diff --git a/integrationtests/self/multiplex_test.go b/integrationtests/self/multiplex_test.go index 9b00bc34358..72c858a10cf 100644 --- a/integrationtests/self/multiplex_test.go +++ b/integrationtests/self/multiplex_test.go @@ -2,9 +2,11 @@ package self_test import ( "context" + "crypto/rand" "io" "net" "runtime" + "sync/atomic" "time" "github.com/quic-go/quic-go" @@ -210,4 +212,67 @@ var _ = Describe("Multiplexing", func() { }) } }) + + It("sends and receives non-QUIC packets", func() { + addr1, err := net.ResolveUDPAddr("udp", "localhost:0") + Expect(err).ToNot(HaveOccurred()) + conn1, err := net.ListenUDP("udp", addr1) + Expect(err).ToNot(HaveOccurred()) + defer conn1.Close() + tr1 := &quic.Transport{Conn: conn1} + + addr2, err := net.ResolveUDPAddr("udp", "localhost:0") + Expect(err).ToNot(HaveOccurred()) + conn2, err := net.ListenUDP("udp", addr2) + Expect(err).ToNot(HaveOccurred()) + defer conn2.Close() + tr2 := &quic.Transport{Conn: conn2} + + server, err := tr1.Listen(getTLSConfig(), getQuicConfig(nil)) + Expect(err).ToNot(HaveOccurred()) + runServer(server) + defer server.Close() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + var sentPackets, rcvdPackets atomic.Int64 + const packetLen = 128 + // send a non-QUIC packet every 100µs + go func() { + defer GinkgoRecover() + ticker := time.NewTicker(time.Millisecond / 10) + defer ticker.Stop() + for { + select { + case <-ticker.C: + case <-ctx.Done(): + return + } + b := make([]byte, packetLen) + rand.Read(b[1:]) // keep the first byte set to 0, so it's not classified as a QUIC packet + _, err := tr1.WriteTo(b, tr2.Conn.LocalAddr()) + Expect(err).ToNot(HaveOccurred()) + sentPackets.Add(1) + } + }() + + // receive and count non-QUIC packets + go func() { + defer GinkgoRecover() + for { + b := make([]byte, 1024) + n, addr, err := tr2.ReadNonQUICPacket(ctx, b) + if err != nil { + Expect(err).To(MatchError(context.Canceled)) + return + } + Expect(addr).To(Equal(tr1.Conn.LocalAddr())) + Expect(n).To(Equal(packetLen)) + rcvdPackets.Add(1) + } + }() + dial(tr2, server.Addr()) + Eventually(func() int64 { return sentPackets.Load() }).Should(BeNumerically(">", 10)) + Eventually(func() int64 { return rcvdPackets.Load() }).Should(BeNumerically(">=", sentPackets.Load()*4/5)) + }) }) diff --git a/internal/wire/header.go b/internal/wire/header.go index e2dc72e421f..0c60f4dd948 100644 --- a/internal/wire/header.go +++ b/internal/wire/header.go @@ -74,6 +74,10 @@ func parseArbitraryLenConnectionIDs(r *bytes.Reader) (dest, src protocol.Arbitra return destConnID, srcConnID, nil } +func IsPotentialQUICPacket(firstByte byte) bool { + return firstByte&0x40 > 0 +} + // IsLongHeaderPacket says if this is a Long Header packet func IsLongHeaderPacket(firstByte byte) bool { return firstByte&0x80 > 0 diff --git a/transport.go b/transport.go index ae44e3da638..fe6dc1fc38e 100644 --- a/transport.go +++ b/transport.go @@ -7,12 +7,12 @@ import ( "errors" "net" "sync" + "sync/atomic" "time" - "github.com/quic-go/quic-go/internal/wire" - "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" + "github.com/quic-go/quic-go/internal/wire" "github.com/quic-go/quic-go/logging" ) @@ -85,6 +85,9 @@ type Transport struct { createdConn bool isSingleUse bool // was created for a single server or client, i.e. by calling quic.Listen or quic.Dial + readingNonQUICPackets atomic.Bool + nonQUICPackets chan receivedPacket + logger utils.Logger } @@ -341,6 +344,13 @@ func (t *Transport) listen(conn rawConn) { } func (t *Transport) handlePacket(p receivedPacket) { + if len(p.data) == 0 { + return + } + if !wire.IsPotentialQUICPacket(p.data[0]) && !wire.IsLongHeaderPacket(p.data[0]) { + t.handleNonQUICPacket(p) + return + } connID, err := wire.ParseConnectionID(p.data, t.connIDLen) if err != nil { t.logger.Debugf("error parsing connection ID on packet from %s: %s", p.remoteAddr, err) @@ -429,3 +439,42 @@ func (t *Transport) maybeHandleStatelessReset(data []byte) bool { } return false } + +func (t *Transport) handleNonQUICPacket(p receivedPacket) { + // Strictly speaking, this is racy, + // but we only care about receiving packets at some point after ReadNonQUICPacket has been called. + if !t.readingNonQUICPackets.Load() { + return + } + select { + case t.nonQUICPackets <- p: + default: + if t.Tracer != nil { + t.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention) + } + } +} + +const maxQueuedNonQUICPackets = 32 + +// ReadNonQUICPacket reads non-QUIC packets received on the underlying connection. +// The detection logic is very simple: Any packet that has the first and second bit of the packet set to 0. +// Note that this is stricter than the detection logic defined in RFC 9443. +func (t *Transport) ReadNonQUICPacket(ctx context.Context, b []byte) (int, net.Addr, error) { + if err := t.init(false); err != nil { + return 0, nil, err + } + if !t.readingNonQUICPackets.Load() { + t.nonQUICPackets = make(chan receivedPacket, maxQueuedNonQUICPackets) + t.readingNonQUICPackets.Store(true) + } + select { + case <-ctx.Done(): + return 0, nil, ctx.Err() + case p := <-t.nonQUICPackets: + n := copy(b, p.data) + return n, p.remoteAddr, nil + case <-t.listening: + return 0, nil, errors.New("closed") + } +} diff --git a/transport_test.go b/transport_test.go index f46affb3dd9..93e1d32ab82 100644 --- a/transport_test.go +++ b/transport_test.go @@ -2,6 +2,7 @@ package quic import ( "bytes" + "context" "crypto/rand" "crypto/tls" "errors" @@ -122,7 +123,7 @@ var _ = Describe("Transport", func() { tr.Close() }) - It("drops unparseable packets", func() { + It("drops unparseable QUIC packets", func() { addr := &net.UDPAddr{IP: net.IPv4(9, 8, 7, 6), Port: 1234} packetChan := make(chan packetToRead) tracer := mocklogging.NewMockTracer(mockCtrl) @@ -136,7 +137,7 @@ var _ = Describe("Transport", func() { tracer.EXPECT().DroppedPacket(addr, logging.PacketTypeNotDetermined, protocol.ByteCount(4), logging.PacketDropHeaderParseError).Do(func(net.Addr, logging.PacketType, protocol.ByteCount, logging.PacketDropReason) { close(dropped) }) packetChan <- packetToRead{ addr: addr, - data: []byte{0, 1, 2, 3}, + data: []byte{0x40 /* set the QUIC bit */, 1, 2, 3}, } Eventually(dropped).Should(BeClosed()) @@ -323,6 +324,78 @@ var _ = Describe("Transport", func() { conns := getMultiplexer().(*connMultiplexer).conns Expect(len(conns)).To(BeZero()) }) + + It("allows receiving non-QUIC packets", func() { + remoteAddr := &net.UDPAddr{IP: net.IPv4(9, 8, 7, 6), Port: 1234} + packetChan := make(chan packetToRead) + tracer := mocklogging.NewMockTracer(mockCtrl) + tr := &Transport{ + Conn: newMockPacketConn(packetChan), + ConnectionIDLength: 10, + Tracer: tracer, + } + tr.init(true) + receivedPacketChan := make(chan []byte) + go func() { + defer GinkgoRecover() + b := make([]byte, 100) + n, addr, err := tr.ReadNonQUICPacket(context.Background(), b) + Expect(err).ToNot(HaveOccurred()) + Expect(addr).To(Equal(remoteAddr)) + receivedPacketChan <- b[:n] + }() + // Receiving of non-QUIC packets is enabled when ReadNonQUICPacket is called. + // Give the Go routine some time to spin up. + time.Sleep(scaleDuration(50 * time.Millisecond)) + packetChan <- packetToRead{ + addr: remoteAddr, + data: []byte{0 /* don't set the QUIC bit */, 1, 2, 3}, + } + + Eventually(receivedPacketChan).Should(Receive(Equal([]byte{0, 1, 2, 3}))) + + // shutdown + close(packetChan) + tr.Close() + }) + + It("drops non-QUIC packet if the application doesn't process them quickly enough", func() { + remoteAddr := &net.UDPAddr{IP: net.IPv4(9, 8, 7, 6), Port: 1234} + packetChan := make(chan packetToRead) + tracer := mocklogging.NewMockTracer(mockCtrl) + tr := &Transport{ + Conn: newMockPacketConn(packetChan), + ConnectionIDLength: 10, + Tracer: tracer, + } + tr.init(true) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + _, _, err := tr.ReadNonQUICPacket(ctx, make([]byte, 10)) + Expect(err).To(MatchError(context.Canceled)) + + for i := 0; i < maxQueuedNonQUICPackets; i++ { + packetChan <- packetToRead{ + addr: remoteAddr, + data: []byte{0 /* don't set the QUIC bit */, 1, 2, 3}, + } + } + + done := make(chan struct{}) + tracer.EXPECT().DroppedPacket(remoteAddr, logging.PacketTypeNotDetermined, protocol.ByteCount(4), logging.PacketDropDOSPrevention).Do(func(net.Addr, logging.PacketType, protocol.ByteCount, logging.PacketDropReason) { + close(done) + }) + packetChan <- packetToRead{ + addr: remoteAddr, + data: []byte{0 /* don't set the QUIC bit */, 1, 2, 3}, + } + Eventually(done).Should(BeClosed()) + + // shutdown + close(packetChan) + tr.Close() + }) }) type mockSyscallConn struct { From f689a5d023ba58cf0acea9bbacc2a94b6bee9549 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 21 Aug 2023 09:48:03 +0700 Subject: [PATCH 028/225] ci: build interop Docker image for pushes to master, and for releases (#4035) * ci: build interop Docker image for pushes to master, and tag releases * use self-hosted runner to build Docker image * Apply suggestions from code review Co-authored-by: Piotr Galar * Update .github/workflows/build-interop-docker.yml Co-authored-by: Piotr Galar * build the correct commit * Update .github/workflows/build-interop-docker.yml --------- Co-authored-by: Piotr Galar --- .github/workflows/build-interop-docker.yml | 23 +++++++++++++++++++--- interop/Dockerfile | 13 ++++++------ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-interop-docker.yml b/.github/workflows/build-interop-docker.yml index e16663c7ea6..bef6f2058be 100644 --- a/.github/workflows/build-interop-docker.yml +++ b/.github/workflows/build-interop-docker.yml @@ -1,11 +1,14 @@ name: Build interop Docker image on: push: - branches: [ interop ] + branches: + - master + tags: + - 'v*' jobs: interop: - runs-on: ubuntu-latest + runs-on: ${{ fromJSON(vars['DOCKER_RUNNER_UBUNTU'] || '"ubuntu-latest"') }} steps: - uses: actions/checkout@v3 - name: Set up QEMU @@ -19,9 +22,23 @@ jobs: with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + - name: set tag name + id: tag + # Tagged releases won't be picked up by the interop runner automatically, + # but they can be useful when debugging regressions. + run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + echo "tag=${GITHUB_REF#refs/tags/}" | tee -a $GITHUB_OUTPUT; + echo "gitref=${GITHUB_REF#refs/tags/}" | tee -a $GITHUB_OUTPUT; + else + echo 'tag=latest' | tee -a $GITHUB_OUTPUT; + echo 'gitref=${{ github.sha }}' | tee -a $GITHUB_OUTPUT; + fi - uses: docker/build-push-action@v4 with: context: "{{defaultContext}}:interop" platforms: linux/amd64,linux/arm64 push: true - tags: martenseemann/quic-go-interop:latest + build-args: | + GITREF=${{ steps.tag.outputs.gitref }} + tags: martenseemann/quic-go-interop:${{ steps.tag.outputs.tag }} diff --git a/interop/Dockerfile b/interop/Dockerfile index 48d4f0962f7..afff1276773 100644 --- a/interop/Dockerfile +++ b/interop/Dockerfile @@ -5,7 +5,7 @@ RUN echo "TARGETPLATFORM: ${TARGETPLATFORM}" RUN apt-get update && apt-get install -y wget tar git -ENV GOVERSION=1.20.2 +ENV GOVERSION=1.20.7 RUN platform=$(echo ${TARGETPLATFORM} | tr '/' '-') && \ filename="go${GOVERSION}.${platform}.tar.gz" && \ @@ -18,14 +18,15 @@ ENV PATH="/go/bin:${PATH}" # build with --build-arg CACHEBUST=$(date +%s) ARG CACHEBUST=1 -RUN git clone https://github.com/quic-go/quic-go && \ - cd quic-go && \ - git fetch origin interop && git checkout -t origin/interop && \ - go get ./... +# build other branches / commits / tags using --build-arg GITREF="" +ARG GITREF="master" +RUN git clone https://github.com/quic-go/quic-go WORKDIR /quic-go +RUN git checkout ${GITREF} +RUN go get ./... -RUN git rev-parse HEAD > commit.txt +RUN git rev-parse HEAD | tee commit.txt RUN go build -o server -ldflags="-X github.com/quic-go/quic-go/qlog.quicGoVersion=$(git describe --always --long --dirty)" interop/server/main.go RUN go build -o client -ldflags="-X github.com/quic-go/quic-go/qlog.quicGoVersion=$(git describe --always --long --dirty)" interop/client/main.go From ced65c0ddcf5b24b0e1f04b07bb18e968a77b05a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 21 Aug 2023 09:55:57 +0700 Subject: [PATCH 029/225] wire: always set the QUIC bit for Version Negotiation packets (#3991) * wire: always set the QUIC bit for Version Negotiation packets * Update internal/wire/version_negotiation_test.go --- internal/wire/version_negotiation.go | 5 ++++- internal/wire/version_negotiation_test.go | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/wire/version_negotiation.go b/internal/wire/version_negotiation.go index 3dc621135b3..afde70fa4a4 100644 --- a/internal/wire/version_negotiation.go +++ b/internal/wire/version_negotiation.go @@ -40,7 +40,10 @@ func ComposeVersionNegotiation(destConnID, srcConnID protocol.ArbitraryLenConnec buf := bytes.NewBuffer(make([]byte, 0, expectedLen)) r := make([]byte, 1) _, _ = rand.Read(r) // ignore the error here. It is not critical to have perfect random here. - buf.WriteByte(r[0] | 0x80) + // Setting the "QUIC bit" (0x40) is not required by the RFC, + // but it allows clients to demultiplex QUIC with a long list of other protocols. + // See RFC 9443 and https://mailarchive.ietf.org/arch/msg/quic/oR4kxGKY6mjtPC1CZegY1ED4beg/ for details. + buf.WriteByte(r[0] | 0xc0) utils.BigEndian.WriteUint32(buf, 0) // version 0 buf.WriteByte(uint8(destConnID.Len())) buf.Write(destConnID.Bytes()) diff --git a/internal/wire/version_negotiation_test.go b/internal/wire/version_negotiation_test.go index 65d0ba911a0..acd6d7ce85f 100644 --- a/internal/wire/version_negotiation_test.go +++ b/internal/wire/version_negotiation_test.go @@ -64,6 +64,7 @@ var _ = Describe("Version Negotiation Packets", func() { versions := []protocol.VersionNumber{1001, 1003} data := ComposeVersionNegotiation(destConnID, srcConnID, versions) Expect(IsLongHeaderPacket(data[0])).To(BeTrue()) + Expect(data[0] & 0x40).ToNot(BeZero()) v, err := ParseVersion(data) Expect(err).ToNot(HaveOccurred()) Expect(v).To(BeZero()) From 824fd8a2f2eb8a08fe6cef7a693fee6be3819e01 Mon Sep 17 00:00:00 2001 From: WeidiDeng Date: Mon, 21 Aug 2023 11:31:22 +0800 Subject: [PATCH 030/225] http3: automatically add content-length for small responses (#3989) * response writer: add content-length automatically when response is small enough and doesn't call Flush * fix comment * add integration test * Update http3/response_writer.go * Update integrationtests/self/http_test.go --------- Co-authored-by: Marten Seemann --- http3/response_writer.go | 97 ++++++++++++++++++++---------- http3/server.go | 8 ++- http3/server_test.go | 41 +++++++++++++ integrationtests/self/http_test.go | 12 ++++ 4 files changed, 126 insertions(+), 32 deletions(-) diff --git a/http3/response_writer.go b/http3/response_writer.go index 3d9271858d6..90a30497ae6 100644 --- a/http3/response_writer.go +++ b/http3/response_writer.go @@ -15,19 +15,61 @@ import ( "github.com/quic-go/qpack" ) +// The maximum length of an encoded HTTP/3 frame header is 16: +// The frame has a type and length field, both QUIC varints (maximum 8 bytes in length) +const frameHeaderLen = 16 + +// headerWriter wraps the stream, so that the first Write call flushes the header to the stream +type headerWriter struct { + str quic.Stream + header http.Header + status int // status code passed to WriteHeader + written bool + + logger utils.Logger +} + +// writeHeader encodes and flush header to the stream +func (hw *headerWriter) writeHeader() error { + var headers bytes.Buffer + enc := qpack.NewEncoder(&headers) + enc.WriteField(qpack.HeaderField{Name: ":status", Value: strconv.Itoa(hw.status)}) + + for k, v := range hw.header { + for index := range v { + enc.WriteField(qpack.HeaderField{Name: strings.ToLower(k), Value: v[index]}) + } + } + + buf := make([]byte, 0, frameHeaderLen+headers.Len()) + buf = (&headersFrame{Length: uint64(headers.Len())}).Append(buf) + hw.logger.Infof("Responding with %d", hw.status) + buf = append(buf, headers.Bytes()...) + + _, err := hw.str.Write(buf) + return err +} + +// first Write will trigger flushing header +func (hw *headerWriter) Write(p []byte) (int, error) { + if !hw.written { + if err := hw.writeHeader(); err != nil { + return 0, err + } + hw.written = true + } + return hw.str.Write(p) +} + type responseWriter struct { + *headerWriter conn quic.Connection - str quic.Stream bufferedStr *bufio.Writer buf []byte - header http.Header - status int // status code passed to WriteHeader headerWritten bool contentLen int64 // if handler set valid Content-Length header numWritten int64 // bytes written - - logger utils.Logger } var ( @@ -37,13 +79,16 @@ var ( ) func newResponseWriter(str quic.Stream, conn quic.Connection, logger utils.Logger) *responseWriter { + hw := &headerWriter{ + str: str, + header: http.Header{}, + logger: logger, + } return &responseWriter{ - header: http.Header{}, - buf: make([]byte, 16), - conn: conn, - str: str, - bufferedStr: bufio.NewWriter(str), - logger: logger, + headerWriter: hw, + buf: make([]byte, frameHeaderLen), + conn: conn, + bufferedStr: bufio.NewWriter(hw), } } @@ -83,27 +128,8 @@ func (w *responseWriter) WriteHeader(status int) { } w.status = status - var headers bytes.Buffer - enc := qpack.NewEncoder(&headers) - enc.WriteField(qpack.HeaderField{Name: ":status", Value: strconv.Itoa(status)}) - - for k, v := range w.header { - for index := range v { - enc.WriteField(qpack.HeaderField{Name: strings.ToLower(k), Value: v[index]}) - } - } - - w.buf = w.buf[:0] - w.buf = (&headersFrame{Length: uint64(headers.Len())}).Append(w.buf) - w.logger.Infof("Responding with %d", status) - if _, err := w.bufferedStr.Write(w.buf); err != nil { - w.logger.Errorf("could not write headers frame: %s", err.Error()) - } - if _, err := w.bufferedStr.Write(headers.Bytes()); err != nil { - w.logger.Errorf("could not write header frame payload: %s", err.Error()) - } if !w.headerWritten { - w.Flush() + w.writeHeader() } } @@ -146,6 +172,15 @@ func (w *responseWriter) Write(p []byte) (int, error) { } func (w *responseWriter) FlushError() error { + if !w.headerWritten { + w.WriteHeader(http.StatusOK) + } + if !w.written { + if err := w.writeHeader(); err != nil { + return err + } + w.written = true + } return w.bufferedStr.Flush() } diff --git a/http3/server.go b/http3/server.go index 8d39f3749da..4587a1fca77 100644 --- a/http3/server.go +++ b/http3/server.go @@ -9,6 +9,7 @@ import ( "net" "net/http" "runtime" + "strconv" "strings" "sync" "time" @@ -627,7 +628,12 @@ func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *q // only write response when there is no panic if !panicked { - r.WriteHeader(http.StatusOK) + // response not written to the client yet, set Content-Length + if !r.written { + if _, haveCL := r.header["Content-Length"]; !haveCL { + r.header.Set("Content-Length", strconv.FormatInt(r.numWritten, 10)) + } + } r.Flush() } // If the EOF was read by the handler, CancelRead() is a no-op. diff --git a/http3/server_test.go b/http3/server_test.go index f180ef0d5c2..67713b922f7 100644 --- a/http3/server_test.go +++ b/http3/server_test.go @@ -180,6 +180,47 @@ var _ = Describe("Server", func() { Expect(hfs).To(HaveKeyWithValue(":status", []string{"200"})) }) + It("sets Content-Length when the handler doesn't flush to the client", func() { + s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("foobar")) + }) + + responseBuf := &bytes.Buffer{} + setRequest(encodeRequest(exampleGetRequest)) + str.EXPECT().Context().Return(reqContext) + str.EXPECT().Write(gomock.Any()).DoAndReturn(responseBuf.Write).AnyTimes() + str.EXPECT().CancelRead(gomock.Any()) + + serr := s.handleRequest(conn, str, qpackDecoder, nil) + Expect(serr.err).ToNot(HaveOccurred()) + hfs := decodeHeader(responseBuf) + Expect(hfs).To(HaveKeyWithValue(":status", []string{"200"})) + Expect(hfs).To(HaveKeyWithValue("content-length", []string{"6"})) + // status, content-length, date, content-type + Expect(hfs).To(HaveLen(4)) + }) + + It("not sets Content-Length when the handler flushes to the client", func() { + s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("foobar")) + // force flush + w.(http.Flusher).Flush() + }) + + responseBuf := &bytes.Buffer{} + setRequest(encodeRequest(exampleGetRequest)) + str.EXPECT().Context().Return(reqContext) + str.EXPECT().Write(gomock.Any()).DoAndReturn(responseBuf.Write).AnyTimes() + str.EXPECT().CancelRead(gomock.Any()) + + serr := s.handleRequest(conn, str, qpackDecoder, nil) + Expect(serr.err).ToNot(HaveOccurred()) + hfs := decodeHeader(responseBuf) + Expect(hfs).To(HaveKeyWithValue(":status", []string{"200"})) + // status, date, content-type + Expect(hfs).To(HaveLen(3)) + }) + It("handles a aborting handler", func() { s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { panic(http.ErrAbortHandler) diff --git a/integrationtests/self/http_test.go b/integrationtests/self/http_test.go index b647d4d9c00..a1067070275 100644 --- a/integrationtests/self/http_test.go +++ b/integrationtests/self/http_test.go @@ -128,6 +128,18 @@ var _ = Describe("HTTP tests", func() { Expect(string(body)).To(Equal("Hello, World!\n")) }) + It("sets content-length for small response", func() { + mux.HandleFunc("/small", func(w http.ResponseWriter, r *http.Request) { + defer GinkgoRecover() + w.Write([]byte("foobar")) + }) + + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/small", port)) + Expect(err).ToNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(200)) + Expect(resp.Header.Get("Content-Length")).To(Equal(strconv.Itoa(len("foobar")))) + }) + It("requests to different servers with the same udpconn", func() { resp, err := client.Get(fmt.Sprintf("https://localhost:%d/remoteAddr", port)) Expect(err).ToNot(HaveOccurred()) From 8d91ad9fcd02d818424401bcc21a78d4e151c7d5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Giorgi Date: Wed, 23 Aug 2023 05:12:08 +0200 Subject: [PATCH 031/225] move QUIC_GO_DISABLE_GSO check out of init (#4041) * move QUIC_GO_DISABLE_GSO test out of init(). * Update sys_conn_helper_linux.go --------- Co-authored-by: Marten Seemann --- sys_conn_helper_linux.go | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/sys_conn_helper_linux.go b/sys_conn_helper_linux.go index 5bda2286c49..6a049241bd5 100644 --- a/sys_conn_helper_linux.go +++ b/sys_conn_helper_linux.go @@ -14,15 +14,6 @@ import ( "golang.org/x/sys/unix" ) -var gsoDisabled bool - -func init() { - disabled, err := strconv.ParseBool(os.Getenv("QUIC_GO_DISABLE_GSO")) - if err == nil { - gsoDisabled = disabled - } -} - const ( msgTypeIPTOS = unix.IP_TOS ipv4PKTINFO = unix.IP_PKTINFO @@ -65,7 +56,8 @@ func parseIPv4PktInfo(body []byte) (ip netip.Addr, ifIndex uint32, ok bool) { // isGSOSupported tests if the kernel supports GSO. // Sending with GSO might still fail later on, if the interface doesn't support it (see isGSOError). func isGSOSupported(conn syscall.RawConn) bool { - if gsoDisabled { + disabled, err := strconv.ParseBool(os.Getenv("QUIC_GO_DISABLE_GSO")) + if err == nil && disabled { return false } var serr error From f633dca488b0858088afae0ba4709b3bfdf798f9 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 23 Aug 2023 10:36:33 +0700 Subject: [PATCH 032/225] update qtls to v0.3.3 (#4044) --- go.mod | 2 +- go.sum | 4 ++-- integrationtests/gomodvendor/go.sum | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 106c90fd006..32092eb6b78 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/onsi/ginkgo/v2 v2.9.5 github.com/onsi/gomega v1.27.6 github.com/quic-go/qpack v0.4.0 - github.com/quic-go/qtls-go1-20 v0.3.2 + github.com/quic-go/qtls-go1-20 v0.3.3 golang.org/x/crypto v0.4.0 golang.org/x/exp v0.0.0-20221205204356-47842c84f3db golang.org/x/net v0.10.0 diff --git a/go.sum b/go.sum index f28b844c5b2..59ef763cbb1 100644 --- a/go.sum +++ b/go.sum @@ -90,8 +90,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.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= -github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +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/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= diff --git a/integrationtests/gomodvendor/go.sum b/integrationtests/gomodvendor/go.sum index ab32e13898c..ae9f9517b99 100644 --- a/integrationtests/gomodvendor/go.sum +++ b/integrationtests/gomodvendor/go.sum @@ -136,8 +136,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.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= -github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +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/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= From d22854641ace1792ca27d7d911a6d62c0075e2c2 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 25 Aug 2023 07:53:02 +0700 Subject: [PATCH 033/225] remove the port from the hostname used for tls.Config.ServerName (#4046) --- transport.go | 31 +++++++++++++++++++++---------- transport_test.go | 12 ++++++++++++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/transport.go b/transport.go index fe6dc1fc38e..d8da9b1a188 100644 --- a/transport.go +++ b/transport.go @@ -159,7 +159,7 @@ func (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.C return t.dial(ctx, addr, "", tlsConf, conf, true) } -func (t *Transport) dial(ctx context.Context, addr net.Addr, hostname string, tlsConf *tls.Config, conf *Config, use0RTT bool) (EarlyConnection, error) { +func (t *Transport) dial(ctx context.Context, addr net.Addr, host string, tlsConf *tls.Config, conf *Config, use0RTT bool) (EarlyConnection, error) { if err := validateConfig(conf); err != nil { return nil, err } @@ -173,15 +173,7 @@ func (t *Transport) dial(ctx context.Context, addr net.Addr, hostname string, tl } tlsConf = tlsConf.Clone() tlsConf.MinVersion = tls.VersionTLS13 - // If no ServerName is set, infer the ServerName from the hostname we're connecting to. - if tlsConf.ServerName == "" { - if hostname == "" { - if udpAddr, ok := addr.(*net.UDPAddr); ok { - hostname = udpAddr.IP.String() - } - } - tlsConf.ServerName = hostname - } + setTLSConfigServerName(tlsConf, addr, host) return dial(ctx, newSendConn(t.conn, addr, packetInfo{}, utils.DefaultLogger), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, use0RTT) } @@ -478,3 +470,22 @@ func (t *Transport) ReadNonQUICPacket(ctx context.Context, b []byte) (int, net.A return 0, nil, errors.New("closed") } } + +func setTLSConfigServerName(tlsConf *tls.Config, addr net.Addr, host string) { + // If no ServerName is set, infer the ServerName from the host we're connecting to. + if tlsConf.ServerName != "" { + return + } + if host == "" { + if udpAddr, ok := addr.(*net.UDPAddr); ok { + tlsConf.ServerName = udpAddr.IP.String() + return + } + } + h, _, err := net.SplitHostPort(host) + if err != nil { // This happens if the host doesn't contain a port number. + tlsConf.ServerName = host + return + } + tlsConf.ServerName = h +} diff --git a/transport_test.go b/transport_test.go index 93e1d32ab82..cf38e32522f 100644 --- a/transport_test.go +++ b/transport_test.go @@ -396,6 +396,18 @@ var _ = Describe("Transport", func() { close(packetChan) tr.Close() }) + + remoteAddr := &net.UDPAddr{IP: net.IPv4(1, 3, 5, 7), Port: 1234} + DescribeTable("setting the tls.Config.ServerName", + func(expected string, conf *tls.Config, addr net.Addr, host string) { + setTLSConfigServerName(conf, addr, host) + Expect(conf.ServerName).To(Equal(expected)) + }, + Entry("uses the value from the config", "foo.bar", &tls.Config{ServerName: "foo.bar"}, remoteAddr, "baz.foo"), + Entry("uses the hostname", "golang.org", &tls.Config{}, remoteAddr, "golang.org"), + Entry("removes the port from the hostname", "golang.org", &tls.Config{}, remoteAddr, "golang.org:1234"), + Entry("uses the IP", "1.3.5.7", &tls.Config{}, remoteAddr, ""), + ) }) type mockSyscallConn struct { From e058f56643f5e1f56208ccb859c2256f419c12cd Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 25 Aug 2023 08:23:44 +0700 Subject: [PATCH 034/225] ci: fix integration test running with and without GSO (#4043) --- .github/workflows/integration.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 0b8fa90430d..be5efa590e2 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -37,10 +37,10 @@ jobs: - name: Run self tests, using QUIC v2 if: success() || failure() # run this step even if the previous one failed run: go run github.com/onsi/ginkgo/v2/ginkgo -r -v -randomize-all -randomize-suites -trace integrationtests/self -- -version=2 ${{ env.QLOGFLAG }} - - name: Run set tests, with GSO enabled - if: success() || failure() # run this step even if the previous one failed + - name: Run self tests, with GSO disabled + if: ${{ matrix.os == 'ubuntu' && (success() || failure()) # run this step even if the previous one failed env: - QUIC_GO_ENABLE_GSO: true + QUIC_GO_DISABLE_GSO: true run: go run github.com/onsi/ginkgo/v2/ginkgo -r -v -randomize-all -randomize-suites -trace integrationtests/self -- -version=1 ${{ env.QLOGFLAG }} - name: Run tests (32 bit) if: ${{ matrix.os != 'macos' && (success() || failure()) }} # run this step even if the previous one failed From 89633069878628392edef3a5fd285eeb11e87889 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 26 Aug 2023 18:23:26 +0700 Subject: [PATCH 035/225] ci: fix syntax error in integration test workflow (#4048) --- .github/workflows/integration.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index be5efa590e2..0e76cba8367 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -21,7 +21,6 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - stable: '!contains(${{ matrix.go }}, "beta") && !contains(${{ matrix.go }}, "rc")' go-version: ${{ matrix.go }} - run: go version - name: set qlogger @@ -38,7 +37,7 @@ jobs: if: success() || failure() # run this step even if the previous one failed run: go run github.com/onsi/ginkgo/v2/ginkgo -r -v -randomize-all -randomize-suites -trace integrationtests/self -- -version=2 ${{ env.QLOGFLAG }} - name: Run self tests, with GSO disabled - if: ${{ matrix.os == 'ubuntu' && (success() || failure()) # run this step even if the previous one failed + if: ${{ matrix.os == 'ubuntu' && (success() || failure()) }} # run this step even if the previous one failed env: QUIC_GO_DISABLE_GSO: true run: go run github.com/onsi/ginkgo/v2/ginkgo -r -v -randomize-all -randomize-suites -trace integrationtests/self -- -version=1 ${{ env.QLOGFLAG }} From 8f34488c7620bfcedc88c64bf70e678c2db5d534 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 27 Aug 2023 11:53:07 +0700 Subject: [PATCH 036/225] fix flaky version negotiation connection unit test (#4052) --- connection_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connection_test.go b/connection_test.go index 5c972733f54..70864190377 100644 --- a/connection_test.go +++ b/connection_test.go @@ -2702,8 +2702,9 @@ var _ = Describe("Client Connection", func() { Expect(recreateErr.nextPacketNumber).To(Equal(protocol.PacketNumber(128))) }) - It("it closes when no matching version is found", func() { + It("closes when no matching version is found", func() { errChan := make(chan error, 1) + packer.EXPECT().PackCoalescedPacket(gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1) go func() { defer GinkgoRecover() cryptoSetup.EXPECT().StartHandshake().MaxTimes(1) @@ -2711,7 +2712,6 @@ var _ = Describe("Client Connection", func() { errChan <- conn.run() }() connRunner.EXPECT().Remove(srcConnID).MaxTimes(1) - packer.EXPECT().PackCoalescedPacket(gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1) gomock.InOrder( tracer.EXPECT().ReceivedVersionNegotiationPacket(gomock.Any(), gomock.Any(), gomock.Any()), tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) { From 2797f85fc0fbea493a3d3ae95cac2be666d7288b Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 28 Aug 2023 16:23:55 +0700 Subject: [PATCH 037/225] switch from unmaintained golang/mock to go.uber.org/mock (#4050) --- client_test.go | 3 +- connection_test.go | 3 +- framer_test.go | 3 +- go.mod | 2 +- go.sum | 24 +-------- http3/body_test.go | 2 +- http3/client_test.go | 2 +- http3/http3_suite_test.go | 3 +- http3/http_stream_test.go | 2 +- http3/mock_quic_early_listener_test.go | 2 +- http3/mock_roundtripcloser_test.go | 2 +- http3/mockgen.go | 4 +- http3/request_writer_test.go | 2 +- http3/response_writer_test.go | 2 +- http3/roundtrip_test.go | 2 +- http3/server_test.go | 2 +- integrationtests/gomodvendor/go.sum | 12 ++--- internal/ackhandler/ackhandler_suite_test.go | 2 +- .../mock_sent_packet_tracker_test.go | 2 +- internal/ackhandler/mockgen.go | 2 +- .../received_packet_handler_test.go | 3 +- .../ackhandler/sent_packet_handler_test.go | 3 +- .../flowcontrol/flowcontrol_suite_test.go | 2 +- internal/handshake/crypto_setup_test.go | 3 +- internal/handshake/handshake_suite_test.go | 3 +- internal/handshake/updatable_aead_test.go | 2 +- .../ackhandler/received_packet_handler.go | 2 +- .../mocks/ackhandler/sent_packet_handler.go | 2 +- internal/mocks/congestion.go | 2 +- internal/mocks/connection_flow_controller.go | 2 +- internal/mocks/crypto_setup.go | 2 +- internal/mocks/logging/connection_tracer.go | 2 +- internal/mocks/logging/tracer.go | 2 +- internal/mocks/long_header_opener.go | 2 +- internal/mocks/mockgen.go | 28 +++++------ internal/mocks/quic/early_conn.go | 2 +- internal/mocks/quic/stream.go | 2 +- internal/mocks/short_header_opener.go | 2 +- internal/mocks/short_header_sealer.go | 2 +- internal/mocks/stream_flow_controller.go | 2 +- internal/mocks/tls/client_session_cache.go | 2 +- internal/qtls/qtls_suite_test.go | 3 +- logging/logging_suite_test.go | 3 +- logging/mock_connection_tracer_test.go | 2 +- logging/mock_tracer_test.go | 2 +- logging/mockgen.go | 4 +- mock_ack_frame_source_test.go | 2 +- mock_batch_conn_test.go | 2 +- mock_conn_runner_test.go | 2 +- mock_crypto_data_handler_test.go | 2 +- mock_crypto_stream_test.go | 2 +- mock_frame_source_test.go | 2 +- mock_mtu_discoverer_test.go | 2 +- mock_packer_test.go | 2 +- mock_packet_handler_manager_test.go | 2 +- mock_packet_handler_test.go | 2 +- mock_packetconn_test.go | 2 +- mock_quic_conn_test.go | 2 +- mock_raw_conn_test.go | 2 +- mock_receive_stream_internal_test.go | 2 +- mock_sealing_manager_test.go | 2 +- mock_send_conn_test.go | 2 +- mock_send_stream_internal_test.go | 2 +- mock_sender_test.go | 2 +- mock_stream_getter_test.go | 2 +- mock_stream_internal_test.go | 2 +- mock_stream_manager_test.go | 2 +- mock_stream_sender_test.go | 2 +- mock_token_store_test.go | 2 +- mock_unknown_packet_handler_test.go | 2 +- mock_unpacker_test.go | 2 +- mockgen.go | 50 +++++++++---------- packet_packer_test.go | 3 +- packet_unpacker_test.go | 2 +- quic_suite_test.go | 2 +- receive_stream_test.go | 2 +- send_conn_test.go | 2 +- send_queue_test.go | 2 +- send_stream_test.go | 2 +- server_test.go | 2 +- streams_map_incoming_test.go | 2 +- streams_map_outgoing_test.go | 2 +- streams_map_test.go | 3 +- sys_conn_oob_test.go | 2 +- sys_conn_test.go | 3 +- tools.go | 2 +- transport_test.go | 2 +- 87 files changed, 130 insertions(+), 167 deletions(-) diff --git a/client_test.go b/client_test.go index 503468915ce..e908b82f139 100644 --- a/client_test.go +++ b/client_test.go @@ -12,10 +12,9 @@ import ( "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/logging" - "github.com/golang/mock/gomock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) type nullMultiplexer struct{} diff --git a/connection_test.go b/connection_test.go index 70864190377..05a0f20d212 100644 --- a/connection_test.go +++ b/connection_test.go @@ -25,10 +25,9 @@ import ( "github.com/quic-go/quic-go/internal/wire" "github.com/quic-go/quic-go/logging" - "github.com/golang/mock/gomock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) func areConnsRunning() bool { diff --git a/framer_test.go b/framer_test.go index 9615e78e21c..add9da713c5 100644 --- a/framer_test.go +++ b/framer_test.go @@ -8,10 +8,9 @@ import ( "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/wire" - "github.com/golang/mock/gomock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Framer", func() { diff --git a/go.mod b/go.mod index 32092eb6b78..fac9c9fb645 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,11 @@ go 1.20 require ( github.com/francoispqt/gojay v1.2.13 - github.com/golang/mock v1.6.0 github.com/onsi/ginkgo/v2 v2.9.5 github.com/onsi/gomega v1.27.6 github.com/quic-go/qpack v0.4.0 github.com/quic-go/qtls-go1-20 v0.3.3 + go.uber.org/mock v0.2.0 golang.org/x/crypto v0.4.0 golang.org/x/exp v0.0.0-20221205204356-47842c84f3db golang.org/x/net v0.10.0 diff --git a/go.sum b/go.sum index 59ef763cbb1..28cab718dd9 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,6 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= @@ -125,14 +123,14 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 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= 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= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -141,7 +139,6 @@ golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZ 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/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -152,9 +149,6 @@ golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -166,8 +160,6 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -175,33 +167,21 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= diff --git a/http3/body_test.go b/http3/body_test.go index 5bcca2e9cd7..7b96345d050 100644 --- a/http3/body_test.go +++ b/http3/body_test.go @@ -6,9 +6,9 @@ import ( "github.com/quic-go/quic-go" mockquic "github.com/quic-go/quic-go/internal/mocks/quic" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Response Body", func() { diff --git a/http3/client_test.go b/http3/client_test.go index babcb064302..66e290e2fa5 100644 --- a/http3/client_test.go +++ b/http3/client_test.go @@ -18,11 +18,11 @@ import ( "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/quicvarint" - "github.com/golang/mock/gomock" "github.com/quic-go/qpack" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Client", func() { diff --git a/http3/http3_suite_test.go b/http3/http3_suite_test.go index 56b2108f987..b34003b92ea 100644 --- a/http3/http3_suite_test.go +++ b/http3/http3_suite_test.go @@ -6,10 +6,9 @@ import ( "testing" "time" - "github.com/golang/mock/gomock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) func TestHttp3(t *testing.T) { diff --git a/http3/http_stream_test.go b/http3/http_stream_test.go index cff5476b8fe..2d2dc3f3528 100644 --- a/http3/http_stream_test.go +++ b/http3/http_stream_test.go @@ -7,9 +7,9 @@ import ( "github.com/quic-go/quic-go" mockquic "github.com/quic-go/quic-go/internal/mocks/quic" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) func getDataFrame(data []byte) []byte { diff --git a/http3/mock_quic_early_listener_test.go b/http3/mock_quic_early_listener_test.go index ab40f0605de..b79e985865a 100644 --- a/http3/mock_quic_early_listener_test.go +++ b/http3/mock_quic_early_listener_test.go @@ -9,8 +9,8 @@ import ( net "net" reflect "reflect" - gomock "github.com/golang/mock/gomock" quic "github.com/quic-go/quic-go" + gomock "go.uber.org/mock/gomock" ) // MockQUICEarlyListener is a mock of QUICEarlyListener interface. diff --git a/http3/mock_roundtripcloser_test.go b/http3/mock_roundtripcloser_test.go index 7aa19ee3f80..ce7f0d19336 100644 --- a/http3/mock_roundtripcloser_test.go +++ b/http3/mock_roundtripcloser_test.go @@ -8,7 +8,7 @@ import ( http "net/http" reflect "reflect" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockRoundTripCloser is a mock of RoundTripCloser interface. diff --git a/http3/mockgen.go b/http3/mockgen.go index 38939e605cd..ad0a8a26e85 100644 --- a/http3/mockgen.go +++ b/http3/mockgen.go @@ -2,7 +2,7 @@ package http3 -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package http3 -destination mock_roundtripcloser_test.go github.com/quic-go/quic-go/http3 RoundTripCloser" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package http3 -destination mock_roundtripcloser_test.go github.com/quic-go/quic-go/http3 RoundTripCloser" type RoundTripCloser = roundTripCloser -//go:generate sh -c "go run github.com/golang/mock/mockgen -package http3 -destination mock_quic_early_listener_test.go github.com/quic-go/quic-go/http3 QUICEarlyListener" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package http3 -destination mock_quic_early_listener_test.go github.com/quic-go/quic-go/http3 QUICEarlyListener" diff --git a/http3/request_writer_test.go b/http3/request_writer_test.go index 74fd239870c..beabb378887 100644 --- a/http3/request_writer_test.go +++ b/http3/request_writer_test.go @@ -8,8 +8,8 @@ import ( mockquic "github.com/quic-go/quic-go/internal/mocks/quic" "github.com/quic-go/quic-go/internal/utils" - "github.com/golang/mock/gomock" "github.com/quic-go/qpack" + "go.uber.org/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" diff --git a/http3/response_writer_test.go b/http3/response_writer_test.go index c803adb73b5..ed6c1d282cf 100644 --- a/http3/response_writer_test.go +++ b/http3/response_writer_test.go @@ -9,11 +9,11 @@ import ( mockquic "github.com/quic-go/quic-go/internal/mocks/quic" "github.com/quic-go/quic-go/internal/utils" - "github.com/golang/mock/gomock" "github.com/quic-go/qpack" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Response Writer", func() { diff --git a/http3/roundtrip_test.go b/http3/roundtrip_test.go index 0c219db7e93..30672384a53 100644 --- a/http3/roundtrip_test.go +++ b/http3/roundtrip_test.go @@ -13,9 +13,9 @@ import ( "github.com/quic-go/quic-go" "github.com/quic-go/quic-go/internal/qerr" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) type mockBody struct { diff --git a/http3/server_test.go b/http3/server_test.go index 67713b922f7..486d31352d5 100644 --- a/http3/server_test.go +++ b/http3/server_test.go @@ -20,8 +20,8 @@ import ( "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/quicvarint" - "github.com/golang/mock/gomock" "github.com/quic-go/qpack" + "go.uber.org/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" diff --git a/integrationtests/gomodvendor/go.sum b/integrationtests/gomodvendor/go.sum index ae9f9517b99..e24232c0b8f 100644 --- a/integrationtests/gomodvendor/go.sum +++ b/integrationtests/gomodvendor/go.sum @@ -39,8 +39,6 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -173,10 +171,11 @@ 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= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 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= 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= @@ -195,7 +194,7 @@ 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.4.2/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= @@ -217,7 +216,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -261,9 +259,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -309,7 +305,7 @@ 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +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= diff --git a/internal/ackhandler/ackhandler_suite_test.go b/internal/ackhandler/ackhandler_suite_test.go index 069aaa7913f..a0cf3ee1799 100644 --- a/internal/ackhandler/ackhandler_suite_test.go +++ b/internal/ackhandler/ackhandler_suite_test.go @@ -3,9 +3,9 @@ package ackhandler import ( "testing" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) func TestCrypto(t *testing.T) { diff --git a/internal/ackhandler/mock_sent_packet_tracker_test.go b/internal/ackhandler/mock_sent_packet_tracker_test.go index 83c28fd54a9..63a9a163e4f 100644 --- a/internal/ackhandler/mock_sent_packet_tracker_test.go +++ b/internal/ackhandler/mock_sent_packet_tracker_test.go @@ -7,8 +7,8 @@ package ackhandler import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockSentPacketTracker is a mock of SentPacketTracker interface. diff --git a/internal/ackhandler/mockgen.go b/internal/ackhandler/mockgen.go index d61783671bf..b9eb8a88e0c 100644 --- a/internal/ackhandler/mockgen.go +++ b/internal/ackhandler/mockgen.go @@ -2,5 +2,5 @@ package ackhandler -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package ackhandler -destination mock_sent_packet_tracker_test.go github.com/quic-go/quic-go/internal/ackhandler SentPacketTracker" +//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/quic-go/quic-go/internal/ackhandler SentPacketTracker" type SentPacketTracker = sentPacketTracker diff --git a/internal/ackhandler/received_packet_handler_test.go b/internal/ackhandler/received_packet_handler_test.go index b07d617869a..387ab7bc840 100644 --- a/internal/ackhandler/received_packet_handler_test.go +++ b/internal/ackhandler/received_packet_handler_test.go @@ -3,14 +3,13 @@ package ackhandler import ( "time" - "github.com/golang/mock/gomock" - "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Received Packet Handler", func() { diff --git a/internal/ackhandler/sent_packet_handler_test.go b/internal/ackhandler/sent_packet_handler_test.go index 6c603c87a4d..fc120171776 100644 --- a/internal/ackhandler/sent_packet_handler_test.go +++ b/internal/ackhandler/sent_packet_handler_test.go @@ -4,8 +4,6 @@ import ( "fmt" "time" - "github.com/golang/mock/gomock" - "github.com/quic-go/quic-go/internal/mocks" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" @@ -14,6 +12,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) type customFrameHandler struct { diff --git a/internal/flowcontrol/flowcontrol_suite_test.go b/internal/flowcontrol/flowcontrol_suite_test.go index 8831296d3d9..6cfe981d7eb 100644 --- a/internal/flowcontrol/flowcontrol_suite_test.go +++ b/internal/flowcontrol/flowcontrol_suite_test.go @@ -3,9 +3,9 @@ package flowcontrol import ( "testing" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) func TestFlowControl(t *testing.T) { diff --git a/internal/handshake/crypto_setup_test.go b/internal/handshake/crypto_setup_test.go index 8b2c5efe95b..e40db500e1c 100644 --- a/internal/handshake/crypto_setup_test.go +++ b/internal/handshake/crypto_setup_test.go @@ -17,10 +17,9 @@ import ( "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" - "github.com/golang/mock/gomock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) const ( diff --git a/internal/handshake/handshake_suite_test.go b/internal/handshake/handshake_suite_test.go index 3289928ea07..80e48a30259 100644 --- a/internal/handshake/handshake_suite_test.go +++ b/internal/handshake/handshake_suite_test.go @@ -6,10 +6,9 @@ import ( "strings" "testing" - "github.com/golang/mock/gomock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) func TestHandshake(t *testing.T) { diff --git a/internal/handshake/updatable_aead_test.go b/internal/handshake/updatable_aead_test.go index db3cf56e1bf..a4a91f01044 100644 --- a/internal/handshake/updatable_aead_test.go +++ b/internal/handshake/updatable_aead_test.go @@ -12,9 +12,9 @@ import ( "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/utils" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Updatable AEAD", func() { diff --git a/internal/mocks/ackhandler/received_packet_handler.go b/internal/mocks/ackhandler/received_packet_handler.go index c73727e0f44..b068586eaab 100644 --- a/internal/mocks/ackhandler/received_packet_handler.go +++ b/internal/mocks/ackhandler/received_packet_handler.go @@ -8,9 +8,9 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockReceivedPacketHandler is a mock of ReceivedPacketHandler interface. diff --git a/internal/mocks/ackhandler/sent_packet_handler.go b/internal/mocks/ackhandler/sent_packet_handler.go index 0904d5cbeef..80aaae0fad1 100644 --- a/internal/mocks/ackhandler/sent_packet_handler.go +++ b/internal/mocks/ackhandler/sent_packet_handler.go @@ -8,10 +8,10 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" ackhandler "github.com/quic-go/quic-go/internal/ackhandler" protocol "github.com/quic-go/quic-go/internal/protocol" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockSentPacketHandler is a mock of SentPacketHandler interface. diff --git a/internal/mocks/congestion.go b/internal/mocks/congestion.go index 6a5e46adddf..d27113a7c2a 100644 --- a/internal/mocks/congestion.go +++ b/internal/mocks/congestion.go @@ -8,8 +8,8 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockSendAlgorithmWithDebugInfos is a mock of SendAlgorithmWithDebugInfos interface. diff --git a/internal/mocks/connection_flow_controller.go b/internal/mocks/connection_flow_controller.go index a0c252f3e3d..1ec76f9e0b0 100644 --- a/internal/mocks/connection_flow_controller.go +++ b/internal/mocks/connection_flow_controller.go @@ -7,8 +7,8 @@ package mocks import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockConnectionFlowController is a mock of ConnectionFlowController interface. diff --git a/internal/mocks/crypto_setup.go b/internal/mocks/crypto_setup.go index 1c707b9cb0b..bf496c221df 100644 --- a/internal/mocks/crypto_setup.go +++ b/internal/mocks/crypto_setup.go @@ -7,9 +7,9 @@ package mocks import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" handshake "github.com/quic-go/quic-go/internal/handshake" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockCryptoSetup is a mock of CryptoSetup interface. diff --git a/internal/mocks/logging/connection_tracer.go b/internal/mocks/logging/connection_tracer.go index 2a7d2f13708..1ca0895d530 100644 --- a/internal/mocks/logging/connection_tracer.go +++ b/internal/mocks/logging/connection_tracer.go @@ -9,11 +9,11 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" utils "github.com/quic-go/quic-go/internal/utils" wire "github.com/quic-go/quic-go/internal/wire" logging "github.com/quic-go/quic-go/logging" + gomock "go.uber.org/mock/gomock" ) // MockConnectionTracer is a mock of ConnectionTracer interface. diff --git a/internal/mocks/logging/tracer.go b/internal/mocks/logging/tracer.go index 56741ef2925..2cdd2335701 100644 --- a/internal/mocks/logging/tracer.go +++ b/internal/mocks/logging/tracer.go @@ -8,10 +8,10 @@ import ( net "net" reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" wire "github.com/quic-go/quic-go/internal/wire" logging "github.com/quic-go/quic-go/logging" + gomock "go.uber.org/mock/gomock" ) // MockTracer is a mock of Tracer interface. diff --git a/internal/mocks/long_header_opener.go b/internal/mocks/long_header_opener.go index cb4970d1e0b..fc284dd8b3e 100644 --- a/internal/mocks/long_header_opener.go +++ b/internal/mocks/long_header_opener.go @@ -7,8 +7,8 @@ package mocks import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockLongHeaderOpener is a mock of LongHeaderOpener interface. diff --git a/internal/mocks/mockgen.go b/internal/mocks/mockgen.go index 8717fce09e2..9bee4270f94 100644 --- a/internal/mocks/mockgen.go +++ b/internal/mocks/mockgen.go @@ -1,19 +1,19 @@ package mocks -//go:generate sh -c "go run github.com/golang/mock/mockgen -package mockquic -destination quic/stream.go github.com/quic-go/quic-go Stream" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package mockquic -destination quic/early_conn_tmp.go github.com/quic-go/quic-go 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 github.com/golang/mock/mockgen -package mocklogging -destination logging/tracer.go github.com/quic-go/quic-go/logging Tracer" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocklogging -destination logging/connection_tracer.go github.com/quic-go/quic-go/logging ConnectionTracer" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocks -destination short_header_sealer.go github.com/quic-go/quic-go/internal/handshake ShortHeaderSealer" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocks -destination short_header_opener.go github.com/quic-go/quic-go/internal/handshake ShortHeaderOpener" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocks -destination long_header_opener.go github.com/quic-go/quic-go/internal/handshake LongHeaderOpener" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocks -destination crypto_setup_tmp.go github.com/quic-go/quic-go/internal/handshake CryptoSetup && sed -E 's~github.com/quic-go/qtls[[:alnum:]_-]*~github.com/quic-go/quic-go/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 github.com/golang/mock/mockgen -package mocks -destination stream_flow_controller.go github.com/quic-go/quic-go/internal/flowcontrol StreamFlowController" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocks -destination congestion.go github.com/quic-go/quic-go/internal/congestion SendAlgorithmWithDebugInfos" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocks -destination connection_flow_controller.go github.com/quic-go/quic-go/internal/flowcontrol ConnectionFlowController" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package mockackhandler -destination ackhandler/sent_packet_handler.go github.com/quic-go/quic-go/internal/ackhandler SentPacketHandler" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package mockackhandler -destination ackhandler/received_packet_handler.go github.com/quic-go/quic-go/internal/ackhandler ReceivedPacketHandler" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mockquic -destination quic/stream.go github.com/quic-go/quic-go Stream" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mockquic -destination quic/early_conn_tmp.go github.com/quic-go/quic-go 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/quic-go/quic-go/logging Tracer" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocklogging -destination logging/connection_tracer.go github.com/quic-go/quic-go/logging ConnectionTracer" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination short_header_sealer.go github.com/quic-go/quic-go/internal/handshake ShortHeaderSealer" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination short_header_opener.go github.com/quic-go/quic-go/internal/handshake ShortHeaderOpener" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination long_header_opener.go github.com/quic-go/quic-go/internal/handshake LongHeaderOpener" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination crypto_setup_tmp.go github.com/quic-go/quic-go/internal/handshake CryptoSetup && sed -E 's~github.com/quic-go/qtls[[:alnum:]_-]*~github.com/quic-go/quic-go/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/quic-go/quic-go/internal/flowcontrol StreamFlowController" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination congestion.go github.com/quic-go/quic-go/internal/congestion SendAlgorithmWithDebugInfos" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination connection_flow_controller.go github.com/quic-go/quic-go/internal/flowcontrol ConnectionFlowController" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mockackhandler -destination ackhandler/sent_packet_handler.go github.com/quic-go/quic-go/internal/ackhandler SentPacketHandler" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mockackhandler -destination ackhandler/received_packet_handler.go github.com/quic-go/quic-go/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 github.com/golang/mock/mockgen -package mocktls -destination tls/client_session_cache.go crypto/tls ClientSessionCache" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocktls -destination tls/client_session_cache.go crypto/tls ClientSessionCache" diff --git a/internal/mocks/quic/early_conn.go b/internal/mocks/quic/early_conn.go index a573e06f72a..c4db88d2ff1 100644 --- a/internal/mocks/quic/early_conn.go +++ b/internal/mocks/quic/early_conn.go @@ -9,9 +9,9 @@ import ( net "net" reflect "reflect" - gomock "github.com/golang/mock/gomock" quic "github.com/quic-go/quic-go" qerr "github.com/quic-go/quic-go/internal/qerr" + gomock "go.uber.org/mock/gomock" ) // MockEarlyConnection is a mock of EarlyConnection interface. diff --git a/internal/mocks/quic/stream.go b/internal/mocks/quic/stream.go index 1221ac3b7be..7fc6560008d 100644 --- a/internal/mocks/quic/stream.go +++ b/internal/mocks/quic/stream.go @@ -9,9 +9,9 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" qerr "github.com/quic-go/quic-go/internal/qerr" + gomock "go.uber.org/mock/gomock" ) // MockStream is a mock of Stream interface. diff --git a/internal/mocks/short_header_opener.go b/internal/mocks/short_header_opener.go index 47e858cb256..ffc8bd48903 100644 --- a/internal/mocks/short_header_opener.go +++ b/internal/mocks/short_header_opener.go @@ -8,8 +8,8 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockShortHeaderOpener is a mock of ShortHeaderOpener interface. diff --git a/internal/mocks/short_header_sealer.go b/internal/mocks/short_header_sealer.go index 666fd8fb1a2..d0109b5e6a8 100644 --- a/internal/mocks/short_header_sealer.go +++ b/internal/mocks/short_header_sealer.go @@ -7,8 +7,8 @@ package mocks import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockShortHeaderSealer is a mock of ShortHeaderSealer interface. diff --git a/internal/mocks/stream_flow_controller.go b/internal/mocks/stream_flow_controller.go index 9d730eba150..05eaf8b9b89 100644 --- a/internal/mocks/stream_flow_controller.go +++ b/internal/mocks/stream_flow_controller.go @@ -7,8 +7,8 @@ package mocks import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockStreamFlowController is a mock of StreamFlowController interface. diff --git a/internal/mocks/tls/client_session_cache.go b/internal/mocks/tls/client_session_cache.go index e3ae2c8e29d..6877f9bb71e 100644 --- a/internal/mocks/tls/client_session_cache.go +++ b/internal/mocks/tls/client_session_cache.go @@ -8,7 +8,7 @@ import ( tls "crypto/tls" reflect "reflect" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockClientSessionCache is a mock of ClientSessionCache interface. diff --git a/internal/qtls/qtls_suite_test.go b/internal/qtls/qtls_suite_test.go index e8ce652a1b9..bde81e6cead 100644 --- a/internal/qtls/qtls_suite_test.go +++ b/internal/qtls/qtls_suite_test.go @@ -3,10 +3,9 @@ package qtls import ( "testing" - gomock "github.com/golang/mock/gomock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) func TestQTLS(t *testing.T) { diff --git a/logging/logging_suite_test.go b/logging/logging_suite_test.go index d37ada48086..d808adfec08 100644 --- a/logging/logging_suite_test.go +++ b/logging/logging_suite_test.go @@ -3,10 +3,9 @@ package logging import ( "testing" - "github.com/golang/mock/gomock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) func TestLogging(t *testing.T) { diff --git a/logging/mock_connection_tracer_test.go b/logging/mock_connection_tracer_test.go index ac6d5fd7cd9..f4f7648a399 100644 --- a/logging/mock_connection_tracer_test.go +++ b/logging/mock_connection_tracer_test.go @@ -9,10 +9,10 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" utils "github.com/quic-go/quic-go/internal/utils" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockConnectionTracer is a mock of ConnectionTracer interface. diff --git a/logging/mock_tracer_test.go b/logging/mock_tracer_test.go index 8526cd3a366..61eb47ea095 100644 --- a/logging/mock_tracer_test.go +++ b/logging/mock_tracer_test.go @@ -8,9 +8,9 @@ import ( net "net" reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockTracer is a mock of Tracer interface. diff --git a/logging/mockgen.go b/logging/mockgen.go index d5091679967..e44c15e1667 100644 --- a/logging/mockgen.go +++ b/logging/mockgen.go @@ -1,4 +1,4 @@ package logging -//go:generate sh -c "go run github.com/golang/mock/mockgen -package logging -self_package github.com/quic-go/quic-go/logging -destination mock_connection_tracer_test.go github.com/quic-go/quic-go/logging ConnectionTracer" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package logging -self_package github.com/quic-go/quic-go/logging -destination mock_tracer_test.go github.com/quic-go/quic-go/logging Tracer" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package logging -self_package github.com/quic-go/quic-go/logging -destination mock_connection_tracer_test.go github.com/quic-go/quic-go/logging ConnectionTracer" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package logging -self_package github.com/quic-go/quic-go/logging -destination mock_tracer_test.go github.com/quic-go/quic-go/logging Tracer" diff --git a/mock_ack_frame_source_test.go b/mock_ack_frame_source_test.go index 1284752b64f..54105f9db18 100644 --- a/mock_ack_frame_source_test.go +++ b/mock_ack_frame_source_test.go @@ -7,9 +7,9 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockAckFrameSource is a mock of AckFrameSource interface. diff --git a/mock_batch_conn_test.go b/mock_batch_conn_test.go index fcb23e34cfe..9621e7b4ec4 100644 --- a/mock_batch_conn_test.go +++ b/mock_batch_conn_test.go @@ -7,7 +7,7 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ipv4 "golang.org/x/net/ipv4" ) diff --git a/mock_conn_runner_test.go b/mock_conn_runner_test.go index ec5873231d9..e404c28362b 100644 --- a/mock_conn_runner_test.go +++ b/mock_conn_runner_test.go @@ -7,8 +7,8 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockConnRunner is a mock of ConnRunner interface. diff --git a/mock_crypto_data_handler_test.go b/mock_crypto_data_handler_test.go index d077886ccc1..22e6eaa2937 100644 --- a/mock_crypto_data_handler_test.go +++ b/mock_crypto_data_handler_test.go @@ -7,9 +7,9 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" handshake "github.com/quic-go/quic-go/internal/handshake" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockCryptoDataHandler is a mock of CryptoDataHandler interface. diff --git a/mock_crypto_stream_test.go b/mock_crypto_stream_test.go index c2048fa8cfa..253e95e8cbd 100644 --- a/mock_crypto_stream_test.go +++ b/mock_crypto_stream_test.go @@ -7,9 +7,9 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockCryptoStream is a mock of CryptoStream interface. diff --git a/mock_frame_source_test.go b/mock_frame_source_test.go index e23aa39d80a..040c75815bf 100644 --- a/mock_frame_source_test.go +++ b/mock_frame_source_test.go @@ -7,9 +7,9 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" ackhandler "github.com/quic-go/quic-go/internal/ackhandler" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockFrameSource is a mock of FrameSource interface. diff --git a/mock_mtu_discoverer_test.go b/mock_mtu_discoverer_test.go index 406943c580c..1f5432cd55a 100644 --- a/mock_mtu_discoverer_test.go +++ b/mock_mtu_discoverer_test.go @@ -8,9 +8,9 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" ackhandler "github.com/quic-go/quic-go/internal/ackhandler" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockMTUDiscoverer is a mock of MTUDiscoverer interface. diff --git a/mock_packer_test.go b/mock_packer_test.go index d54fe58b8d4..4eedab98859 100644 --- a/mock_packer_test.go +++ b/mock_packer_test.go @@ -7,10 +7,10 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" ackhandler "github.com/quic-go/quic-go/internal/ackhandler" protocol "github.com/quic-go/quic-go/internal/protocol" qerr "github.com/quic-go/quic-go/internal/qerr" + gomock "go.uber.org/mock/gomock" ) // MockPacker is a mock of Packer interface. diff --git a/mock_packet_handler_manager_test.go b/mock_packet_handler_manager_test.go index 7b70a8dbd9f..c948d9d5199 100644 --- a/mock_packet_handler_manager_test.go +++ b/mock_packet_handler_manager_test.go @@ -7,8 +7,8 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockPacketHandlerManager is a mock of PacketHandlerManager interface. diff --git a/mock_packet_handler_test.go b/mock_packet_handler_test.go index 529d1b8411b..e84905899ab 100644 --- a/mock_packet_handler_test.go +++ b/mock_packet_handler_test.go @@ -7,8 +7,8 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockPacketHandler is a mock of PacketHandler interface. diff --git a/mock_packetconn_test.go b/mock_packetconn_test.go index d6731e4ac75..c8e20bf2880 100644 --- a/mock_packetconn_test.go +++ b/mock_packetconn_test.go @@ -9,7 +9,7 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockPacketConn is a mock of PacketConn interface. diff --git a/mock_quic_conn_test.go b/mock_quic_conn_test.go index 18932051022..20015c661db 100644 --- a/mock_quic_conn_test.go +++ b/mock_quic_conn_test.go @@ -9,9 +9,9 @@ import ( net "net" reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" qerr "github.com/quic-go/quic-go/internal/qerr" + gomock "go.uber.org/mock/gomock" ) // MockQUICConn is a mock of QUICConn interface. diff --git a/mock_raw_conn_test.go b/mock_raw_conn_test.go index 66b9c6115c3..0a1a0f3ac70 100644 --- a/mock_raw_conn_test.go +++ b/mock_raw_conn_test.go @@ -9,7 +9,7 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockRawConn is a mock of RawConn interface. diff --git a/mock_receive_stream_internal_test.go b/mock_receive_stream_internal_test.go index a4cbb276cff..518e275b8d3 100644 --- a/mock_receive_stream_internal_test.go +++ b/mock_receive_stream_internal_test.go @@ -8,10 +8,10 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" qerr "github.com/quic-go/quic-go/internal/qerr" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockReceiveStreamI is a mock of ReceiveStreamI interface. diff --git a/mock_sealing_manager_test.go b/mock_sealing_manager_test.go index 26e442e5994..b77c747a38b 100644 --- a/mock_sealing_manager_test.go +++ b/mock_sealing_manager_test.go @@ -7,8 +7,8 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" handshake "github.com/quic-go/quic-go/internal/handshake" + gomock "go.uber.org/mock/gomock" ) // MockSealingManager is a mock of SealingManager interface. diff --git a/mock_send_conn_test.go b/mock_send_conn_test.go index 62c01a23fef..04df8763032 100644 --- a/mock_send_conn_test.go +++ b/mock_send_conn_test.go @@ -8,8 +8,8 @@ import ( net "net" reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockSendConn is a mock of SendConn interface. diff --git a/mock_send_stream_internal_test.go b/mock_send_stream_internal_test.go index c0581bc290a..4fb89a35371 100644 --- a/mock_send_stream_internal_test.go +++ b/mock_send_stream_internal_test.go @@ -9,11 +9,11 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" ackhandler "github.com/quic-go/quic-go/internal/ackhandler" protocol "github.com/quic-go/quic-go/internal/protocol" qerr "github.com/quic-go/quic-go/internal/qerr" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockSendStreamI is a mock of SendStreamI interface. diff --git a/mock_sender_test.go b/mock_sender_test.go index feafdf4e06f..c2a0fa8f245 100644 --- a/mock_sender_test.go +++ b/mock_sender_test.go @@ -7,8 +7,8 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockSender is a mock of Sender interface. diff --git a/mock_stream_getter_test.go b/mock_stream_getter_test.go index d02387507e0..0ff7f13fbbe 100644 --- a/mock_stream_getter_test.go +++ b/mock_stream_getter_test.go @@ -7,8 +7,8 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" + gomock "go.uber.org/mock/gomock" ) // MockStreamGetter is a mock of StreamGetter interface. diff --git a/mock_stream_internal_test.go b/mock_stream_internal_test.go index 512b4b1d992..447438c1575 100644 --- a/mock_stream_internal_test.go +++ b/mock_stream_internal_test.go @@ -9,11 +9,11 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" ackhandler "github.com/quic-go/quic-go/internal/ackhandler" protocol "github.com/quic-go/quic-go/internal/protocol" qerr "github.com/quic-go/quic-go/internal/qerr" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockStreamI is a mock of StreamI interface. diff --git a/mock_stream_manager_test.go b/mock_stream_manager_test.go index 2159372d1cf..dc4a39eb37a 100644 --- a/mock_stream_manager_test.go +++ b/mock_stream_manager_test.go @@ -8,9 +8,9 @@ import ( context "context" reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockStreamManager is a mock of StreamManager interface. diff --git a/mock_stream_sender_test.go b/mock_stream_sender_test.go index b4898c67edb..94606942d64 100644 --- a/mock_stream_sender_test.go +++ b/mock_stream_sender_test.go @@ -7,9 +7,9 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockStreamSender is a mock of StreamSender interface. diff --git a/mock_token_store_test.go b/mock_token_store_test.go index 0fb461a6aab..8576a3e205c 100644 --- a/mock_token_store_test.go +++ b/mock_token_store_test.go @@ -7,7 +7,7 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockTokenStore is a mock of TokenStore interface. diff --git a/mock_unknown_packet_handler_test.go b/mock_unknown_packet_handler_test.go index f74897825f0..6f29101a3b3 100644 --- a/mock_unknown_packet_handler_test.go +++ b/mock_unknown_packet_handler_test.go @@ -7,7 +7,7 @@ package quic import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockUnknownPacketHandler is a mock of UnknownPacketHandler interface. diff --git a/mock_unpacker_test.go b/mock_unpacker_test.go index a144fb4c6a9..272585c0453 100644 --- a/mock_unpacker_test.go +++ b/mock_unpacker_test.go @@ -8,9 +8,9 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" protocol "github.com/quic-go/quic-go/internal/protocol" wire "github.com/quic-go/quic-go/internal/wire" + gomock "go.uber.org/mock/gomock" ) // MockUnpacker is a mock of Unpacker interface. diff --git a/mockgen.go b/mockgen.go index 221c1367fcd..ea0aa58bedd 100644 --- a/mockgen.go +++ b/mockgen.go @@ -2,76 +2,76 @@ package quic -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn" type SendConn = sendConn -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn" type RawConn = rawConn -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender" type Sender = sender -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_internal_test.go github.com/quic-go/quic-go StreamI" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_internal_test.go github.com/quic-go/quic-go StreamI" type StreamI = streamI -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_stream_test.go github.com/quic-go/quic-go CryptoStream" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_stream_test.go github.com/quic-go/quic-go CryptoStream" type CryptoStream = cryptoStream -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_receive_stream_internal_test.go github.com/quic-go/quic-go ReceiveStreamI" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_receive_stream_internal_test.go github.com/quic-go/quic-go ReceiveStreamI" type ReceiveStreamI = receiveStreamI -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_stream_internal_test.go github.com/quic-go/quic-go SendStreamI" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_stream_internal_test.go github.com/quic-go/quic-go SendStreamI" type SendStreamI = sendStreamI -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_getter_test.go github.com/quic-go/quic-go StreamGetter" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_getter_test.go github.com/quic-go/quic-go StreamGetter" type StreamGetter = streamGetter -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_sender_test.go github.com/quic-go/quic-go StreamSender" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_sender_test.go github.com/quic-go/quic-go StreamSender" type StreamSender = streamSender -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_data_handler_test.go github.com/quic-go/quic-go CryptoDataHandler" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_data_handler_test.go github.com/quic-go/quic-go CryptoDataHandler" type CryptoDataHandler = cryptoDataHandler -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_frame_source_test.go github.com/quic-go/quic-go FrameSource" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_frame_source_test.go github.com/quic-go/quic-go FrameSource" type FrameSource = frameSource -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_ack_frame_source_test.go github.com/quic-go/quic-go AckFrameSource" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_ack_frame_source_test.go github.com/quic-go/quic-go AckFrameSource" type AckFrameSource = ackFrameSource -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_manager_test.go github.com/quic-go/quic-go StreamManager" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_manager_test.go github.com/quic-go/quic-go StreamManager" type StreamManager = streamManager -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sealing_manager_test.go github.com/quic-go/quic-go SealingManager" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sealing_manager_test.go github.com/quic-go/quic-go SealingManager" type SealingManager = sealingManager -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_unpacker_test.go github.com/quic-go/quic-go Unpacker" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_unpacker_test.go github.com/quic-go/quic-go Unpacker" type Unpacker = unpacker -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packer_test.go github.com/quic-go/quic-go Packer" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packer_test.go github.com/quic-go/quic-go Packer" type Packer = packer -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_mtu_discoverer_test.go github.com/quic-go/quic-go MTUDiscoverer" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_mtu_discoverer_test.go github.com/quic-go/quic-go MTUDiscoverer" type MTUDiscoverer = mtuDiscoverer -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_conn_runner_test.go github.com/quic-go/quic-go ConnRunner" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_conn_runner_test.go github.com/quic-go/quic-go ConnRunner" type ConnRunner = connRunner -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_quic_conn_test.go github.com/quic-go/quic-go QUICConn" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_quic_conn_test.go github.com/quic-go/quic-go QUICConn" type QUICConn = quicConn -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_test.go github.com/quic-go/quic-go PacketHandler" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_test.go github.com/quic-go/quic-go PacketHandler" type PacketHandler = packetHandler -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_unknown_packet_handler_test.go github.com/quic-go/quic-go UnknownPacketHandler" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_unknown_packet_handler_test.go github.com/quic-go/quic-go UnknownPacketHandler" type UnknownPacketHandler = unknownPacketHandler -//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager" +//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager" type PacketHandlerManager = packetHandlerManager // Need to use source mode for the batchConn, since reflect mode follows type aliases. // See https://github.com/golang/mock/issues/244 for details. // -//go:generate sh -c "go run github.com/golang/mock/mockgen -package quic -self_package github.com/quic-go/quic-go -source sys_conn_oob.go -destination mock_batch_conn_test.go -mock_names batchConn=MockBatchConn" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package quic -self_package github.com/quic-go/quic-go -source sys_conn_oob.go -destination mock_batch_conn_test.go -mock_names batchConn=MockBatchConn" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_token_store_test.go github.com/quic-go/quic-go TokenStore" -//go:generate sh -c "go run github.com/golang/mock/mockgen -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_packetconn_test.go net PacketConn" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_token_store_test.go github.com/quic-go/quic-go TokenStore" +//go:generate sh -c "go run go.uber.org/mock/mockgen -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_packetconn_test.go net PacketConn" diff --git a/packet_packer_test.go b/packet_packer_test.go index 38ced47ad55..6dba31f9db4 100644 --- a/packet_packer_test.go +++ b/packet_packer_test.go @@ -18,10 +18,9 @@ import ( "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" - "github.com/golang/mock/gomock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Packet packer", func() { diff --git a/packet_unpacker_test.go b/packet_unpacker_test.go index 927635cb4e0..035a431d062 100644 --- a/packet_unpacker_test.go +++ b/packet_unpacker_test.go @@ -10,9 +10,9 @@ import ( "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/wire" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Packet Unpacker", func() { diff --git a/quic_suite_test.go b/quic_suite_test.go index d979d81bc47..954ca60b94a 100644 --- a/quic_suite_test.go +++ b/quic_suite_test.go @@ -9,9 +9,9 @@ import ( "sync" "testing" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) func TestQuicGo(t *testing.T) { diff --git a/receive_stream_test.go b/receive_stream_test.go index f3c515e6b2b..f688433d310 100644 --- a/receive_stream_test.go +++ b/receive_stream_test.go @@ -12,10 +12,10 @@ import ( "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/wire" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/onsi/gomega/gbytes" + "go.uber.org/mock/gomock" ) var _ = Describe("Receive Stream", func() { diff --git a/send_conn_test.go b/send_conn_test.go index 024a8eba07b..7f07243006d 100644 --- a/send_conn_test.go +++ b/send_conn_test.go @@ -6,9 +6,9 @@ import ( "github.com/quic-go/quic-go/internal/utils" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) // Only if appendUDPSegmentSizeMsg actually appends a message (and isn't only a stub implementation), diff --git a/send_queue_test.go b/send_queue_test.go index 5a9e6598f2c..69562c589e6 100644 --- a/send_queue_test.go +++ b/send_queue_test.go @@ -5,9 +5,9 @@ import ( "github.com/quic-go/quic-go/internal/protocol" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Send Queue", func() { diff --git a/send_stream_test.go b/send_stream_test.go index 3356b4200b2..ad1d0469bec 100644 --- a/send_stream_test.go +++ b/send_stream_test.go @@ -11,7 +11,6 @@ import ( "golang.org/x/exp/rand" - "github.com/golang/mock/gomock" "github.com/quic-go/quic-go/internal/ackhandler" "github.com/quic-go/quic-go/internal/mocks" "github.com/quic-go/quic-go/internal/protocol" @@ -20,6 +19,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/onsi/gomega/gbytes" + "go.uber.org/mock/gomock" ) var _ = Describe("Send Stream", func() { diff --git a/server_test.go b/server_test.go index 2ba39cf5ef3..4705225ab1c 100644 --- a/server_test.go +++ b/server_test.go @@ -20,9 +20,9 @@ import ( "github.com/quic-go/quic-go/internal/wire" "github.com/quic-go/quic-go/logging" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Server", func() { diff --git a/streams_map_incoming_test.go b/streams_map_incoming_test.go index c3366542de3..b5abba51873 100644 --- a/streams_map_incoming_test.go +++ b/streams_map_incoming_test.go @@ -10,9 +10,9 @@ import ( "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/wire" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) type mockGenericStream struct { diff --git a/streams_map_outgoing_test.go b/streams_map_outgoing_test.go index 7b4b28c39de..b4b2e25bde8 100644 --- a/streams_map_outgoing_test.go +++ b/streams_map_outgoing_test.go @@ -13,9 +13,9 @@ import ( "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/wire" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Streams Map (outgoing)", func() { diff --git a/streams_map_test.go b/streams_map_test.go index 6300ea8d5be..77ee4aa8293 100644 --- a/streams_map_test.go +++ b/streams_map_test.go @@ -6,8 +6,6 @@ import ( "fmt" "net" - "github.com/golang/mock/gomock" - "github.com/quic-go/quic-go/internal/flowcontrol" "github.com/quic-go/quic-go/internal/mocks" "github.com/quic-go/quic-go/internal/protocol" @@ -16,6 +14,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) func (e streamError) TestError() error { diff --git a/sys_conn_oob_test.go b/sys_conn_oob_test.go index 30b333b971f..3ae97ed924a 100644 --- a/sys_conn_oob_test.go +++ b/sys_conn_oob_test.go @@ -13,9 +13,9 @@ import ( "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("OOB Conn Test", func() { diff --git a/sys_conn_test.go b/sys_conn_test.go index 418e2c31d07..5eb0417a730 100644 --- a/sys_conn_test.go +++ b/sys_conn_test.go @@ -6,10 +6,9 @@ import ( "github.com/quic-go/quic-go/internal/protocol" - "github.com/golang/mock/gomock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Basic Conn Test", func() { diff --git a/tools.go b/tools.go index e848317f15d..d00ce748d6e 100644 --- a/tools.go +++ b/tools.go @@ -3,6 +3,6 @@ package quic import ( - _ "github.com/golang/mock/mockgen" _ "github.com/onsi/ginkgo/v2/ginkgo" + _ "go.uber.org/mock/mockgen" ) diff --git a/transport_test.go b/transport_test.go index cf38e32522f..14c6fdbbcf8 100644 --- a/transport_test.go +++ b/transport_test.go @@ -15,9 +15,9 @@ import ( "github.com/quic-go/quic-go/internal/wire" "github.com/quic-go/quic-go/logging" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "go.uber.org/mock/gomock" ) var _ = Describe("Transport", func() { From d7334c16e7d03fdf692c8e2a3d110687b90a1466 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 31 Aug 2023 13:33:40 +0700 Subject: [PATCH 038/225] move the DisableVersionNegotiationPackets flag to the Transport (#4047) * move the DisableVersionNegotiationPackets flag to the Transport * add an integration test for DisableVersionNegotiationPackets --- config.go | 41 ++++++++-------- config_test.go | 1 - .../versionnegotiation/handshake_test.go | 44 ++++++++++++++++- interface.go | 4 -- server.go | 41 ++++++++-------- server_test.go | 2 +- transport.go | 47 ++++++++++--------- 7 files changed, 112 insertions(+), 68 deletions(-) diff --git a/config.go b/config.go index 59df4cfd952..59a4d9224e6 100644 --- a/config.go +++ b/config.go @@ -110,26 +110,25 @@ 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, + 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, + Allow0RTT: config.Allow0RTT, + Tracer: config.Tracer, } } diff --git a/config_test.go b/config_test.go index 1eca3d5d4df..7208b4add65 100644 --- a/config_test.go +++ b/config_test.go @@ -192,7 +192,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()) }) diff --git a/integrationtests/versionnegotiation/handshake_test.go b/integrationtests/versionnegotiation/handshake_test.go index 965700c1560..a079f6e12d2 100644 --- a/integrationtests/versionnegotiation/handshake_test.go +++ b/integrationtests/versionnegotiation/handshake_test.go @@ -3,8 +3,10 @@ package versionnegotiation import ( "context" "crypto/tls" + "errors" "fmt" "net" + "time" "github.com/quic-go/quic-go" "github.com/quic-go/quic-go/integrationtests/tools/israce" @@ -113,7 +115,7 @@ var _ = Describe("Handshake tests", func() { 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{} serverConfig := &quic.Config{} @@ -147,5 +149,45 @@ var _ = Describe("Handshake tests", func() { Expect(serverTracer.serverVersions).To(Equal(serverConfig.Versions)) Expect(serverTracer.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 := &versionNegotiationTracer{} + 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} + clientTracer := &versionNegotiationTracer{} + _, 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(clientTracer.receivedVersionNegotiation).To(BeFalse()) + }) } }) diff --git a/interface.go b/interface.go index c3fb2b1058c..5d5ab5b0a0f 100644 --- a/interface.go +++ b/interface.go @@ -322,10 +322,6 @@ 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 diff --git a/server.go b/server.go index c06228c9172..14cc6f8249a 100644 --- a/server.go +++ b/server.go @@ -59,7 +59,8 @@ type zeroRTTQueue struct { type baseServer struct { mutex sync.Mutex - acceptEarlyConns bool + disableVersionNegotiation bool + acceptEarlyConns bool tlsConf *tls.Config config *Config @@ -226,6 +227,7 @@ func newServer( config *Config, tracer logging.Tracer, onClose func(), + disableVersionNegotiation bool, acceptEarly bool, ) (*baseServer, error) { tokenGenerator, err := handshake.NewTokenGenerator(rand.Reader) @@ -233,23 +235,24 @@ func newServer( return nil, err } s := &baseServer{ - conn: conn, - tlsConf: tlsConf, - config: config, - tokenGenerator: tokenGenerator, - connIDGenerator: connIDGenerator, - connHandler: connHandler, - connQueue: make(chan quicConn), - errorChan: make(chan struct{}), - running: make(chan struct{}), - receivedPackets: make(chan receivedPacket, protocol.MaxServerUnprocessedPackets), - versionNegotiationQueue: make(chan receivedPacket, 4), - invalidTokenQueue: make(chan receivedPacket, 4), - newConn: newConnection, - tracer: tracer, - logger: utils.DefaultLogger.WithPrefix("server"), - acceptEarlyConns: acceptEarly, - onClose: onClose, + conn: conn, + tlsConf: tlsConf, + config: config, + tokenGenerator: tokenGenerator, + connIDGenerator: connIDGenerator, + connHandler: connHandler, + connQueue: make(chan quicConn), + errorChan: make(chan struct{}), + running: make(chan struct{}), + receivedPackets: make(chan receivedPacket, protocol.MaxServerUnprocessedPackets), + versionNegotiationQueue: make(chan receivedPacket, 4), + invalidTokenQueue: make(chan receivedPacket, 4), + newConn: newConnection, + tracer: tracer, + logger: utils.DefaultLogger.WithPrefix("server"), + acceptEarlyConns: acceptEarly, + disableVersionNegotiation: disableVersionNegotiation, + onClose: onClose, } if acceptEarly { s.zeroRTTQueues = map[protocol.ConnectionID]*zeroRTTQueue{} @@ -383,7 +386,7 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st } // send a Version Negotiation Packet if the client is speaking a different protocol version if !protocol.IsSupportedVersion(s.config.Versions, v) { - if s.config.DisableVersionNegotiationPackets { + if s.disableVersionNegotiation { return false } diff --git a/server_test.go b/server_test.go index 4705225ab1c..e959aee5d0b 100644 --- a/server_test.go +++ b/server_test.go @@ -357,7 +357,7 @@ var _ = Describe("Server", func() { }) It("doesn't send a Version Negotiation packets if sending them is disabled", func() { - serv.config.DisableVersionNegotiationPackets = true + serv.disableVersionNegotiation = true srcConnID := protocol.ParseConnectionID([]byte{1, 2, 3, 4, 5}) destConnID := protocol.ParseConnectionID([]byte{1, 2, 3, 4, 5, 6}) packet := getPacket(&wire.Header{ diff --git a/transport.go b/transport.go index d8da9b1a188..9f93cbb94cc 100644 --- a/transport.go +++ b/transport.go @@ -57,6 +57,11 @@ type Transport struct { // See section 10.3 of RFC 9000 for details. StatelessResetKey *StatelessResetKey + // 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 clients. + DisableVersionNegotiationPackets bool + // A Tracer traces events that don't belong to a single QUIC connection. Tracer logging.Tracer @@ -95,28 +100,10 @@ type Transport struct { // There can only be a single listener on any net.PacketConn. // Listen may only be called again after the current Listener was closed. func (t *Transport) Listen(tlsConf *tls.Config, conf *Config) (*Listener, error) { - if tlsConf == nil { - return nil, errors.New("quic: tls.Config not set") - } - if err := validateConfig(conf); err != nil { - return nil, err - } - - t.mutex.Lock() - defer t.mutex.Unlock() - - if t.server != nil { - return nil, errListenerAlreadySet - } - conf = populateServerConfig(conf) - if err := t.init(false); err != nil { - return nil, err - } - s, err := newServer(t.conn, t.handlerMap, t.connIDGenerator, tlsConf, conf, t.Tracer, t.closeServer, false) + s, err := t.createServer(tlsConf, conf, false) if err != nil { return nil, err } - t.server = s return &Listener{baseServer: s}, nil } @@ -124,6 +111,14 @@ func (t *Transport) Listen(tlsConf *tls.Config, conf *Config) (*Listener, error) // There can only be a single listener on any net.PacketConn. // Listen may only be called again after the current Listener was closed. func (t *Transport) ListenEarly(tlsConf *tls.Config, conf *Config) (*EarlyListener, error) { + s, err := t.createServer(tlsConf, conf, true) + if err != nil { + return nil, err + } + return &EarlyListener{baseServer: s}, nil +} + +func (t *Transport) createServer(tlsConf *tls.Config, conf *Config, allow0RTT bool) (*baseServer, error) { if tlsConf == nil { return nil, errors.New("quic: tls.Config not set") } @@ -141,12 +136,22 @@ func (t *Transport) ListenEarly(tlsConf *tls.Config, conf *Config) (*EarlyListen if err := t.init(false); err != nil { return nil, err } - s, err := newServer(t.conn, t.handlerMap, t.connIDGenerator, tlsConf, conf, t.Tracer, t.closeServer, true) + s, err := newServer( + t.conn, + t.handlerMap, + t.connIDGenerator, + tlsConf, + conf, + t.Tracer, + t.closeServer, + t.DisableVersionNegotiationPackets, + allow0RTT, + ) if err != nil { return nil, err } t.server = s - return &EarlyListener{baseServer: s}, nil + return s, nil } // Dial dials a new connection to a remote host (not using 0-RTT). From 090e505aa9072a4125765e59b0399fc7850aa3d9 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 31 Aug 2023 14:49:27 +0700 Subject: [PATCH 039/225] move GSO control message handling to the oobConn (#4056) * move GSO control message handling to the oobConn * disable OOB test on Windows * improve GSO tests * update ooConn.WritePacket comment --- connection.go | 12 ++++----- connection_test.go | 36 +++++++++++++------------- mock_raw_conn_test.go | 8 +++--- mock_send_conn_test.go | 3 +-- mock_sender_test.go | 3 +-- packet_handler_map.go | 5 ++-- send_conn.go | 40 +++++++++-------------------- send_conn_test.go | 58 ++++++++++++++++++++---------------------- send_queue.go | 15 +++++------ send_queue_test.go | 8 +++--- server.go | 6 ++--- sys_conn.go | 5 +++- sys_conn_oob.go | 10 ++++++-- sys_conn_oob_test.go | 34 +++++++++++++++++++++++++ transport.go | 6 ++--- 15 files changed, 134 insertions(+), 115 deletions(-) diff --git a/connection.go b/connection.go index 877f2d03311..eb80cd1377d 100644 --- a/connection.go +++ b/connection.go @@ -1832,7 +1832,7 @@ func (s *connection) sendPackets(now time.Time) error { } 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.sendQueue.Send(buf, 0) // This is kind of a hack. We need to trigger sending again somehow. s.pacingDeadline = deadlineSendImmediately return nil @@ -1881,7 +1881,7 @@ func (s *connection) sendPacketsWithoutGSO(now time.Time) error { return err } - s.sendQueue.Send(buf, buf.Len()) + s.sendQueue.Send(buf, 0) if s.sendQueue.WouldBlock() { return nil @@ -1938,7 +1938,7 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error { continue } - s.sendQueue.Send(buf, maxSize) + s.sendQueue.Send(buf, uint16(maxSize)) if dontSendMore { return nil @@ -1986,7 +1986,7 @@ func (s *connection) maybeSendAckOnlyPacket(now time.Time) error { } 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.sendQueue.Send(buf, 0) return nil } @@ -2078,7 +2078,7 @@ func (s *connection) sendPackedCoalescedPacket(packet *coalescedPacket, now time s.sentPacketHandler.SentPacket(now, p.PacketNumber, largestAcked, p.StreamFrames, p.Frames, protocol.Encryption1RTT, p.Length, p.IsPathMTUProbePacket) } s.connIDManager.SentPacket() - s.sendQueue.Send(packet.buffer, packet.buffer.Len()) + s.sendQueue.Send(packet.buffer, 0) return nil } @@ -2101,7 +2101,7 @@ func (s *connection) sendConnectionClose(e error) ([]byte, error) { return nil, err } s.logCoalescedPacket(packet) - return packet.buffer.Data, s.conn.Write(packet.buffer.Data, packet.buffer.Len()) + return packet.buffer.Data, s.conn.Write(packet.buffer.Data, 0) } func (s *connection) logLongHeaderPacket(p *longHeaderPacket) { diff --git a/connection_test.go b/connection_test.go index 05a0f20d212..eb512513941 100644 --- a/connection_test.go +++ b/connection_test.go @@ -1243,7 +1243,7 @@ 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()).Do(func(*packetBuffer, uint16) { close(sent) }) tracer.EXPECT().SentShortHeaderPacket(&logging.ShortHeader{ DestConnectionID: p.DestConnID, PacketNumber: p.PacketNumber, @@ -1291,7 +1291,7 @@ 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) }) + sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16) { close(sent) }) tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), nil, []logging.Frame{}) conn.scheduleSending() Eventually(sent).Should(BeClosed()) @@ -1347,7 +1347,7 @@ var _ = Describe("Connection", func() { 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()).Do(func(*packetBuffer, uint16) { close(sent) }) if enc == protocol.Encryption1RTT { tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), p.shortHdrPacket.Length, gomock.Any(), gomock.Any()) } else { @@ -1372,7 +1372,7 @@ var _ = Describe("Connection", func() { 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()).Do(func(*packetBuffer, uint16) { close(sent) }) if enc == protocol.Encryption1RTT { tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), p.shortHdrPacket.Length, gomock.Any(), gomock.Any()) } else { @@ -1428,10 +1428,10 @@ var _ = Describe("Connection", func() { 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()).Do(func(b *packetBuffer, _ uint16) { 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()).Do(func(b *packetBuffer, _ uint16) { Expect(b.Data).To(Equal([]byte("packet11"))) }) go func() { @@ -1456,7 +1456,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())).Do(func(b *packetBuffer, l uint16) { Expect(b.Data).To(Equal(append(payload1, payload2...))) }) go func() { @@ -1481,7 +1481,7 @@ var _ = Describe("Connection", func() { expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, payload1) expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2) 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())).Do(func(b *packetBuffer, l uint16) { Expect(b.Data).To(Equal(append(payload1, payload2...))) }) go func() { @@ -1564,7 +1564,7 @@ var _ = Describe("Connection", func() { ) 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()).DoAndReturn(func(*packetBuffer, uint16) { written <- struct{}{} }).Times(2) go func() { defer GinkgoRecover() cryptoSetup.EXPECT().StartHandshake().MaxTimes(1) @@ -1587,7 +1587,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()).DoAndReturn(func(*packetBuffer, uint16) { written <- struct{}{} }).Times(3) go func() { defer GinkgoRecover() cryptoSetup.EXPECT().StartHandshake().MaxTimes(1) @@ -1622,7 +1622,7 @@ var _ = Describe("Connection", func() { sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).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()).DoAndReturn(func(*packetBuffer, uint16) { close(written) }) available <- struct{}{} Eventually(written).Should(BeClosed()) }) @@ -1646,7 +1646,7 @@ var _ = Describe("Connection", func() { sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).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()).DoAndReturn(func(*packetBuffer, uint16) { close(written) }) conn.scheduleSending() time.Sleep(scaleDuration(50 * time.Millisecond)) @@ -1661,7 +1661,7 @@ var _ = Describe("Connection", func() { 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()).DoAndReturn(func(*packetBuffer, uint16) { written <- struct{}{} }) go func() { defer GinkgoRecover() cryptoSetup.EXPECT().StartHandshake().MaxTimes(1) @@ -1680,7 +1680,7 @@ var _ = Describe("Connection", func() { 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()).DoAndReturn(func(*packetBuffer, uint16) { written <- struct{}{} }) available <- struct{}{} Eventually(written).Should(Receive()) @@ -1713,7 +1713,7 @@ var _ = Describe("Connection", func() { 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()).DoAndReturn(func(*packetBuffer, uint16) { written <- struct{}{} }) mtuDiscoverer.EXPECT().ShouldSendProbe(gomock.Any()).Return(true) ping := ackhandler.Frame{Frame: &wire.PingFrame{}} mtuDiscoverer.EXPECT().GetPing().Return(ping, protocol.ByteCount(1234)) @@ -1776,7 +1776,7 @@ 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) }) + sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16) { close(written) }) tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() conn.scheduleSending() Eventually(written).Should(BeClosed()) @@ -1799,7 +1799,7 @@ 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) }) + sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16) { close(written) }) tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() go func() { defer GinkgoRecover() @@ -1864,7 +1864,7 @@ var _ = Describe("Connection", func() { ) 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)).Do(func([]byte, uint16) { close(sent) }) go func() { defer GinkgoRecover() diff --git a/mock_raw_conn_test.go b/mock_raw_conn_test.go index 0a1a0f3ac70..84d8f276b3e 100644 --- a/mock_raw_conn_test.go +++ b/mock_raw_conn_test.go @@ -93,18 +93,18 @@ func (mr *MockRawConnMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Cal } // WritePacket mocks base method. -func (m *MockRawConn) WritePacket(arg0 []byte, arg1 net.Addr, arg2 []byte) (int, error) { +func (m *MockRawConn) WritePacket(arg0 []byte, arg1 net.Addr, arg2 []byte, arg3 uint16) (int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "WritePacket", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "WritePacket", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(int) ret1, _ := ret[1].(error) return ret0, ret1 } // WritePacket indicates an expected call of WritePacket. -func (mr *MockRawConnMockRecorder) WritePacket(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockRawConnMockRecorder) WritePacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePacket", reflect.TypeOf((*MockRawConn)(nil).WritePacket), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePacket", reflect.TypeOf((*MockRawConn)(nil).WritePacket), arg0, arg1, arg2, arg3) } // capabilities mocks base method. diff --git a/mock_send_conn_test.go b/mock_send_conn_test.go index 04df8763032..529b9c58f22 100644 --- a/mock_send_conn_test.go +++ b/mock_send_conn_test.go @@ -8,7 +8,6 @@ import ( net "net" reflect "reflect" - protocol "github.com/quic-go/quic-go/internal/protocol" gomock "go.uber.org/mock/gomock" ) @@ -78,7 +77,7 @@ func (mr *MockSendConnMockRecorder) RemoteAddr() *gomock.Call { } // Write mocks base method. -func (m *MockSendConn) Write(arg0 []byte, arg1 protocol.ByteCount) error { +func (m *MockSendConn) Write(arg0 []byte, arg1 uint16) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Write", arg0, arg1) ret0, _ := ret[0].(error) diff --git a/mock_sender_test.go b/mock_sender_test.go index c2a0fa8f245..406715623bb 100644 --- a/mock_sender_test.go +++ b/mock_sender_test.go @@ -7,7 +7,6 @@ package quic import ( reflect "reflect" - protocol "github.com/quic-go/quic-go/internal/protocol" gomock "go.uber.org/mock/gomock" ) @@ -75,7 +74,7 @@ func (mr *MockSenderMockRecorder) Run() *gomock.Call { } // Send mocks base method. -func (m *MockSender) Send(arg0 *packetBuffer, arg1 protocol.ByteCount) { +func (m *MockSender) Send(arg0 *packetBuffer, arg1 uint16) { m.ctrl.T.Helper() m.ctrl.Call(m, "Send", arg0, arg1) } diff --git a/packet_handler_map.go b/packet_handler_map.go index e0f0567d70a..60b7cef9b26 100644 --- a/packet_handler_map.go +++ b/packet_handler_map.go @@ -27,8 +27,9 @@ type connCapabilities struct { type rawConn interface { ReadPacket() (receivedPacket, error) // WritePacket writes a packet on the wire. - // If GSO is enabled, it's the caller's responsibility to set the correct control message. - WritePacket(b []byte, addr net.Addr, oob []byte) (int, error) + // gsoSize is the size of a single packet, or 0 to disable GSO. + // It is invalid to set gsoSize if capabilities.GSO is not set. + WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gsoSize uint16) (int, error) LocalAddr() net.Addr SetReadDeadline(time.Time) error io.Closer diff --git a/send_conn.go b/send_conn.go index d8ddbc871ac..272c61b1248 100644 --- a/send_conn.go +++ b/send_conn.go @@ -1,17 +1,14 @@ package quic import ( - "fmt" - "math" "net" - "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" ) // A sendConn allows sending using a simple Write() on a non-connected packet conn. type sendConn interface { - Write(b []byte, size protocol.ByteCount) error + Write(b []byte, gsoSize uint16) error Close() error LocalAddr() net.Addr RemoteAddr() net.Addr @@ -27,8 +24,7 @@ type sconn struct { logger utils.Logger - info packetInfo - oob []byte + packetInfoOOB []byte // If GSO enabled, and we receive a GSO error for this remote address, GSO is disabled. gotGSOError bool } @@ -51,28 +47,16 @@ func newSendConn(c rawConn, remote net.Addr, info packetInfo, logger utils.Logge oob = append(oob, make([]byte, 32)...) oob = oob[:l] return &sconn{ - rawConn: c, - localAddr: localAddr, - remoteAddr: remote, - info: info, - oob: oob, - logger: logger, + rawConn: c, + localAddr: localAddr, + remoteAddr: remote, + packetInfoOOB: oob, + logger: logger, } } -func (c *sconn) Write(p []byte, size protocol.ByteCount) error { - if !c.capabilities().GSO { - if protocol.ByteCount(len(p)) != size { - panic(fmt.Sprintf("inconsistent packet size (%d vs %d)", len(p), size)) - } - _, err := c.WritePacket(p, c.remoteAddr, c.oob) - return err - } - // GSO is supported. Append the control message and send. - if size > math.MaxUint16 { - panic("size overflow") - } - _, err := c.WritePacket(p, c.remoteAddr, appendUDPSegmentSizeMsg(c.oob, uint16(size))) +func (c *sconn) Write(p []byte, gsoSize uint16) error { + _, err := c.WritePacket(p, c.remoteAddr, c.packetInfoOOB, gsoSize) if err != nil && isGSOError(err) { // disable GSO for future calls c.gotGSOError = true @@ -82,10 +66,10 @@ func (c *sconn) Write(p []byte, size protocol.ByteCount) error { // send out the packets one by one for len(p) > 0 { l := len(p) - if l > int(size) { - l = int(size) + if l > int(gsoSize) { + l = int(gsoSize) } - if _, err := c.WritePacket(p[:l], c.remoteAddr, c.oob); err != nil { + if _, err := c.WritePacket(p[:l], c.remoteAddr, c.packetInfoOOB, 0); err != nil { return err } p = p[l:] diff --git a/send_conn_test.go b/send_conn_test.go index 7f07243006d..963f2482295 100644 --- a/send_conn_test.go +++ b/send_conn_test.go @@ -3,6 +3,7 @@ package quic import ( "net" "net/netip" + "runtime" "github.com/quic-go/quic-go/internal/utils" @@ -35,48 +36,43 @@ var _ = Describe("Connection (for sending packets)", func() { Expect(c.LocalAddr().String()).To(Equal("127.0.0.42:1234")) }) - if platformSupportsGSO { - It("writes with GSO", func() { + // We're not using an OOB conn on windows, and packetInfo.OOB() always returns an empty slice. + if runtime.GOOS != "windows" { + It("sets the OOB", func() { rawConn := NewMockRawConn(mockCtrl) rawConn.EXPECT().LocalAddr() - rawConn.EXPECT().capabilities().Return(connCapabilities{GSO: true}).AnyTimes() - c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) - rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any()).Do(func(_ []byte, _ net.Addr, oob []byte) { - msg := appendUDPSegmentSizeMsg([]byte{}, 3) - Expect(oob).To(Equal(msg)) - }) - Expect(c.Write([]byte("foobar"), 3)).To(Succeed()) + rawConn.EXPECT().capabilities().AnyTimes() + pi := packetInfo{addr: netip.IPv6Loopback()} + Expect(pi.OOB()).ToNot(BeEmpty()) + c := newSendConn(rawConn, remoteAddr, pi, utils.DefaultLogger) + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, pi.OOB(), uint16(0)) + Expect(c.Write([]byte("foobar"), 0)).To(Succeed()) }) + } - It("disables GSO if writing fails", func() { + It("writes", func() { + rawConn := NewMockRawConn(mockCtrl) + rawConn.EXPECT().LocalAddr() + rawConn.EXPECT().capabilities().AnyTimes() + c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any(), uint16(3)) + Expect(c.Write([]byte("foobar"), 3)).To(Succeed()) + }) + + if platformSupportsGSO { + It("disables GSO if sending fails", func() { rawConn := NewMockRawConn(mockCtrl) rawConn.EXPECT().LocalAddr() rawConn.EXPECT().capabilities().Return(connCapabilities{GSO: true}).AnyTimes() c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) Expect(c.capabilities().GSO).To(BeTrue()) gomock.InOrder( - rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any()).DoAndReturn(func(_ []byte, _ net.Addr, oob []byte) (int, error) { - msg := appendUDPSegmentSizeMsg([]byte{}, 3) - Expect(oob).To(Equal(msg)) - return 0, errGSO - }), - rawConn.EXPECT().WritePacket([]byte("foo"), remoteAddr, gomock.Len(0)).Return(3, nil), - rawConn.EXPECT().WritePacket([]byte("bar"), remoteAddr, gomock.Len(0)).Return(3, nil), + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any(), uint16(4)).Return(0, errGSO), + rawConn.EXPECT().WritePacket([]byte("foob"), remoteAddr, gomock.Any(), uint16(0)).Return(4, nil), + rawConn.EXPECT().WritePacket([]byte("ar"), remoteAddr, gomock.Any(), uint16(0)).Return(2, nil), ) - Expect(c.Write([]byte("foobar"), 3)).To(Succeed()) - Expect(c.capabilities().GSO).To(BeFalse()) // GSO support is now disabled - // make sure we actually enforce that - Expect(func() { c.Write([]byte("foobar"), 3) }).To(PanicWith("inconsistent packet size (6 vs 3)")) - }) - } else { - It("writes without GSO", func() { - remoteAddr := &net.UDPAddr{IP: net.IPv4(192, 168, 100, 200), Port: 1337} - rawConn := NewMockRawConn(mockCtrl) - rawConn.EXPECT().LocalAddr() - rawConn.EXPECT().capabilities() - c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) - rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Len(0)) - Expect(c.Write([]byte("foobar"), 6)).To(Succeed()) + Expect(c.Write([]byte("foobar"), 4)).To(Succeed()) + Expect(c.capabilities().GSO).To(BeFalse()) }) } }) diff --git a/send_queue.go b/send_queue.go index a9f7ca1a0ee..2da546e510d 100644 --- a/send_queue.go +++ b/send_queue.go @@ -1,9 +1,8 @@ package quic -import "github.com/quic-go/quic-go/internal/protocol" - type sender interface { - Send(p *packetBuffer, packetSize protocol.ByteCount) + // Send sends a packet. GSO is only used if gsoSize > 0. + Send(p *packetBuffer, gsoSize uint16) Run() error WouldBlock() bool Available() <-chan struct{} @@ -11,8 +10,8 @@ type sender interface { } type queueEntry struct { - buf *packetBuffer - size protocol.ByteCount + buf *packetBuffer + gsoSize uint16 } type sendQueue struct { @@ -40,9 +39,9 @@ func newSendQueue(conn sendConn) sender { // Send sends out a packet. It's guaranteed to not block. // Callers need to make sure that there's actually space in the send queue by calling WouldBlock. // Otherwise Send will panic. -func (h *sendQueue) Send(p *packetBuffer, size protocol.ByteCount) { +func (h *sendQueue) Send(p *packetBuffer, gsoSize uint16) { select { - case h.queue <- queueEntry{buf: p, size: size}: + case h.queue <- queueEntry{buf: p, gsoSize: gsoSize}: // clear available channel if we've reached capacity if len(h.queue) == sendQueueCapacity { select { @@ -77,7 +76,7 @@ func (h *sendQueue) Run() error { // make sure that all queued packets are actually sent out shouldClose = true case e := <-h.queue: - if err := h.conn.Write(e.buf.Data, e.size); err != nil { + if err := h.conn.Write(e.buf.Data, e.gsoSize); err != nil { // This additional check enables: // 1. Checking for "datagram too large" message from the kernel, as such, // 2. Path MTU discovery,and diff --git a/send_queue_test.go b/send_queue_test.go index 69562c589e6..0ed7bea5758 100644 --- a/send_queue_test.go +++ b/send_queue_test.go @@ -3,8 +3,6 @@ package quic import ( "errors" - "github.com/quic-go/quic-go/internal/protocol" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "go.uber.org/mock/gomock" @@ -31,7 +29,7 @@ var _ = Describe("Send Queue", func() { q.Send(p, 10) // make sure the packet size is passed through to the conn written := make(chan struct{}) - c.EXPECT().Write([]byte("foobar"), protocol.ByteCount(10)).Do(func([]byte, protocol.ByteCount) { close(written) }) + c.EXPECT().Write([]byte("foobar"), uint16(10)).Do(func([]byte, uint16) { close(written) }) done := make(chan struct{}) go func() { defer GinkgoRecover() @@ -79,7 +77,7 @@ var _ = Describe("Send Queue", func() { write := make(chan struct{}, 1) written := make(chan struct{}, 100) // now start sending out packets. This should free up queue space. - c.EXPECT().Write(gomock.Any(), gomock.Any()).DoAndReturn(func([]byte, protocol.ByteCount) error { + c.EXPECT().Write(gomock.Any(), gomock.Any()).DoAndReturn(func([]byte, uint16) error { written <- struct{}{} <-write return nil @@ -149,7 +147,7 @@ var _ = Describe("Send Queue", func() { It("blocks Close() until the packet has been sent out", func() { written := make(chan []byte) - c.EXPECT().Write(gomock.Any(), gomock.Any()).Do(func(p []byte, _ protocol.ByteCount) { written <- p }) + c.EXPECT().Write(gomock.Any(), gomock.Any()).Do(func(p []byte, _ uint16) { written <- p }) done := make(chan struct{}) go func() { defer GinkgoRecover() diff --git a/server.go b/server.go index 14cc6f8249a..495ca65ac93 100644 --- a/server.go +++ b/server.go @@ -745,7 +745,7 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info packe if s.tracer != nil { s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(buf.Data)), nil) } - _, err = s.conn.WritePacket(buf.Data, remoteAddr, info.OOB()) + _, err = s.conn.WritePacket(buf.Data, remoteAddr, info.OOB(), 0) return err } @@ -844,7 +844,7 @@ func (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer han if s.tracer != nil { s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(b.Data)), []logging.Frame{ccf}) } - _, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB()) + _, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB(), 0) return err } @@ -882,7 +882,7 @@ func (s *baseServer) maybeSendVersionNegotiationPacket(p receivedPacket) { if s.tracer != nil { s.tracer.SentVersionNegotiationPacket(p.remoteAddr, src, dest, s.config.Versions) } - if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB()); err != nil { + if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0); err != nil { s.logger.Debugf("Error sending Version Negotiation: %s", err) } } diff --git a/sys_conn.go b/sys_conn.go index f2224e4cc23..a72aead5813 100644 --- a/sys_conn.go +++ b/sys_conn.go @@ -104,7 +104,10 @@ func (c *basicConn) ReadPacket() (receivedPacket, error) { }, nil } -func (c *basicConn) WritePacket(b []byte, addr net.Addr, _ []byte) (n int, err error) { +func (c *basicConn) WritePacket(b []byte, addr net.Addr, _ []byte, gsoSize uint16) (n int, err error) { + if gsoSize != 0 { + panic("cannot use GSO with a basicConn") + } return c.PacketConn.WriteTo(b, addr) } diff --git a/sys_conn_oob.go b/sys_conn_oob.go index 4026a7b32c3..24b73e9cc9a 100644 --- a/sys_conn_oob.go +++ b/sys_conn_oob.go @@ -228,8 +228,14 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) { } // WritePacket writes a new packet. -// If the connection supports GSO, it's the caller's responsibility to append the right control mesage. -func (c *oobConn) WritePacket(b []byte, addr net.Addr, oob []byte) (int, error) { +func (c *oobConn) WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gsoSize uint16) (int, error) { + oob := packetInfoOOB + if gsoSize > 0 { + if !c.capabilities().GSO { + panic("GSO disabled") + } + oob = appendUDPSegmentSizeMsg(oob, gsoSize) + } n, _, err := c.OOBCapablePacketConn.WriteMsgUDP(b, oob, addr.(*net.UDPAddr)) return n, err } diff --git a/sys_conn_oob_test.go b/sys_conn_oob_test.go index 3ae97ed924a..54dac82d27c 100644 --- a/sys_conn_oob_test.go +++ b/sys_conn_oob_test.go @@ -18,6 +18,16 @@ import ( "go.uber.org/mock/gomock" ) +type oobRecordingConn struct { + *net.UDPConn + oobs [][]byte +} + +func (c *oobRecordingConn) WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error) { + c.oobs = append(c.oobs, oob) + return c.UDPConn.WriteMsgUDP(b, oob, addr) +} + var _ = Describe("OOB Conn Test", func() { runServer := func(network, address string) (*net.UDPConn, <-chan receivedPacket) { addr, err := net.ResolveUDPAddr(network, address) @@ -242,4 +252,28 @@ var _ = Describe("OOB Conn Test", func() { } }) }) + + if platformSupportsGSO { + Context("GSO", func() { + It("appends the GSO control message", func() { + addr, err := net.ResolveUDPAddr("udp", "localhost:0") + Expect(err).ToNot(HaveOccurred()) + udpConn, err := net.ListenUDP("udp", addr) + Expect(err).ToNot(HaveOccurred()) + c := &oobRecordingConn{UDPConn: udpConn} + oobConn, err := newConn(c, true) + Expect(err).ToNot(HaveOccurred()) + Expect(oobConn.capabilities().GSO).To(BeTrue()) + + oob := make([]byte, 0, 42) + oobConn.WritePacket([]byte("foobar"), addr, oob, 3) + Expect(c.oobs).To(HaveLen(1)) + oobMsg := c.oobs[0] + Expect(oobMsg).ToNot(BeEmpty()) + Expect(oobMsg).To(HaveCap(cap(oob))) // check that it appended to oob + expected := appendUDPSegmentSizeMsg([]byte{}, 3) + Expect(oobMsg).To(Equal(expected)) + }) + }) + } }) diff --git a/transport.go b/transport.go index 9f93cbb94cc..41c9734710d 100644 --- a/transport.go +++ b/transport.go @@ -228,7 +228,7 @@ func (t *Transport) WriteTo(b []byte, addr net.Addr) (int, error) { if err := t.init(false); err != nil { return 0, err } - return t.conn.WritePacket(b, addr, nil) + return t.conn.WritePacket(b, addr, nil, 0) } func (t *Transport) enqueueClosePacket(p closePacket) { @@ -246,7 +246,7 @@ func (t *Transport) runSendQueue() { case <-t.listening: return case p := <-t.closeQueue: - t.conn.WritePacket(p.payload, p.addr, p.info.OOB()) + t.conn.WritePacket(p.payload, p.addr, p.info.OOB(), 0) case p := <-t.statelessResetQueue: t.sendStatelessReset(p) } @@ -414,7 +414,7 @@ func (t *Transport) sendStatelessReset(p receivedPacket) { rand.Read(data) data[0] = (data[0] & 0x7f) | 0x40 data = append(data, token[:]...) - if _, err := t.conn.WritePacket(data, p.remoteAddr, p.info.OOB()); err != nil { + if _, err := t.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0); err != nil { t.logger.Debugf("Error sending Stateless Reset to %s: %s", p.remoteAddr, err) } } From 6cde43785f033f314e9c35fef7e0f56ec628e709 Mon Sep 17 00:00:00 2001 From: Ameagari <47713057+tanghaowillow@users.noreply.github.com> Date: Sat, 2 Sep 2023 10:40:35 +0800 Subject: [PATCH 040/225] integration tests: fix connection timeout in 0-RTT test (#4060) --- integrationtests/self/zero_rtt_oldgo_test.go | 4 ++-- integrationtests/self/zero_rtt_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/integrationtests/self/zero_rtt_oldgo_test.go b/integrationtests/self/zero_rtt_oldgo_test.go index e5809286787..3e9277b937a 100644 --- a/integrationtests/self/zero_rtt_oldgo_test.go +++ b/integrationtests/self/zero_rtt_oldgo_test.go @@ -852,12 +852,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()) 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() { @@ -907,10 +907,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()) }) }) diff --git a/integrationtests/self/zero_rtt_test.go b/integrationtests/self/zero_rtt_test.go index 011687ae60f..c9bdeff6990 100644 --- a/integrationtests/self/zero_rtt_test.go +++ b/integrationtests/self/zero_rtt_test.go @@ -989,13 +989,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()) 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() { @@ -1047,10 +1047,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()) }) }) From 96b1943cf58d228891e5298c429de85bdefd1ef4 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 4 Sep 2023 11:45:41 +0700 Subject: [PATCH 041/225] ackhandler: rename variables to follow RFC 9002 terminology (#4062) --- internal/ackhandler/interfaces.go | 2 +- .../ackhandler/received_packet_handler.go | 10 ++--- .../ackhandler/received_packet_tracker.go | 44 +++++++++---------- .../received_packet_tracker_test.go | 14 +++--- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/internal/ackhandler/interfaces.go b/internal/ackhandler/interfaces.go index ba95f8a9b18..9c4a5b80cb5 100644 --- a/internal/ackhandler/interfaces.go +++ b/internal/ackhandler/interfaces.go @@ -44,7 +44,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 diff --git a/internal/ackhandler/received_packet_handler.go b/internal/ackhandler/received_packet_handler.go index e11ee1eeb9e..b37f91c5ca8 100644 --- a/internal/ackhandler/received_packet_handler.go +++ b/internal/ackhandler/received_packet_handler.go @@ -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()) diff --git a/internal/ackhandler/received_packet_tracker.go b/internal/ackhandler/received_packet_tracker.go index b188386631d..0ed929fa5b5 100644 --- a/internal/ackhandler/received_packet_tracker.go +++ b/internal/ackhandler/received_packet_tracker.go @@ -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,22 +45,22 @@ 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) } switch ecn { case protocol.ECNNon: @@ -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 diff --git a/internal/ackhandler/received_packet_tracker_test.go b/internal/ackhandler/received_packet_tracker_test.go index 4818bd090ad..8c76f207b14 100644 --- a/internal/ackhandler/received_packet_tracker_test.go +++ b/internal/ackhandler/received_packet_tracker_test.go @@ -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)) }) }) From 591d864e5ee1953b181644f15abc5fecda2b9fdc Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 5 Sep 2023 17:47:05 +0700 Subject: [PATCH 042/225] ci: update GitHub checkout and setup-go actions to v4 (#4067) --- .github/workflows/build-interop-docker.yml | 2 +- .github/workflows/cross-compile.yml | 4 ++-- .github/workflows/go-generate.yml | 4 ++-- .github/workflows/integration.yml | 4 ++-- .github/workflows/lint.yml | 8 ++++---- .github/workflows/unit.yml | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build-interop-docker.yml b/.github/workflows/build-interop-docker.yml index bef6f2058be..8aaac826370 100644 --- a/.github/workflows/build-interop-docker.yml +++ b/.github/workflows/build-interop-docker.yml @@ -10,7 +10,7 @@ jobs: interop: runs-on: ${{ fromJSON(vars['DOCKER_RUNNER_UBUNTU'] || '"ubuntu-latest"') }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx diff --git a/.github/workflows/cross-compile.yml b/.github/workflows/cross-compile.yml index 46309b0ae7e..1e8d16b9a2c 100644 --- a/.github/workflows/cross-compile.yml +++ b/.github/workflows/cross-compile.yml @@ -8,8 +8,8 @@ jobs: runs-on: ${{ fromJSON(vars['CROSS_COMPILE_RUNNER_UBUNTU'] || '"ubuntu-latest"') }} name: "Cross Compilation (Go ${{matrix.go}})" steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 with: go-version: ${{ matrix.go }} - name: Install build utils diff --git a/.github/workflows/go-generate.yml b/.github/workflows/go-generate.yml index 441f442fae9..4add84e3a7b 100644 --- a/.github/workflows/go-generate.yml +++ b/.github/workflows/go-generate.yml @@ -3,8 +3,8 @@ jobs: gogenerate: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 with: go-version: "1.20.x" - name: Install dependencies diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 0e76cba8367..90ed611b0c7 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -18,8 +18,8 @@ jobs: TIMESCALE_FACTOR: 3 name: Integration Tests (${{ matrix.os }}, Go ${{ matrix.go }}) steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 with: go-version: ${{ matrix.go }} - run: go version diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index dfde763689a..1c74c53b28f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -4,8 +4,8 @@ jobs: check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 with: skip-pkg-cache: true go-version: "1.20.x" @@ -25,8 +25,8 @@ jobs: golangci-lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 with: go-version: "1.20.x" - name: golangci-lint (Linux) diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index c9eff032476..6dd625d2e6f 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -11,8 +11,8 @@ jobs: runs-on: ${{ fromJSON(vars[format('UNIT_RUNNER_{0}', matrix.os)] || format('"{0}-latest"', matrix.os)) }} name: Unit tests (${{ matrix.os}}, Go ${{ matrix.go }}) steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 with: go-version: ${{ matrix.go }} - run: go version From 6cac231f6a4d7e3241f3409962bd1a7819b4e1da Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 6 Sep 2023 23:02:33 +0700 Subject: [PATCH 043/225] update qtls-go1-20 to v0.3.4 (#4068) --- go.mod | 2 +- go.sum | 4 ++-- integrationtests/gomodvendor/go.sum | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index fac9c9fb645..936a3786336 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/onsi/ginkgo/v2 v2.9.5 github.com/onsi/gomega v1.27.6 github.com/quic-go/qpack v0.4.0 - github.com/quic-go/qtls-go1-20 v0.3.3 + github.com/quic-go/qtls-go1-20 v0.3.4 go.uber.org/mock v0.2.0 golang.org/x/crypto v0.4.0 golang.org/x/exp v0.0.0-20221205204356-47842c84f3db diff --git a/go.sum b/go.sum index 28cab718dd9..8a3bc65580b 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,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= diff --git a/integrationtests/gomodvendor/go.sum b/integrationtests/gomodvendor/go.sum index e24232c0b8f..5e207944f9c 100644 --- a/integrationtests/gomodvendor/go.sum +++ b/integrationtests/gomodvendor/go.sum @@ -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= From dc0369cad423db07420a4e54bcf35d8b4e399bba Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 7 Sep 2023 11:27:03 +0700 Subject: [PATCH 044/225] remove TLS post-handshake message reassembly logic (#4073) Go 1.21.1 was released, which fixed the bug that made this workaround necessary. --- connection.go | 8 ++++---- crypto_stream.go | 25 ++----------------------- crypto_stream_test.go | 22 +--------------------- 3 files changed, 7 insertions(+), 48 deletions(-) diff --git a/connection.go b/connection.go index eb80cd1377d..42b6c122070 100644 --- a/connection.go +++ b/connection.go @@ -243,7 +243,7 @@ var newConnection = func( handshakeDestConnID: destConnID, srcConnIDLen: srcConnID.Len(), tokenGenerator: tokenGenerator, - oneRTTStream: newCryptoStream(true), + oneRTTStream: newCryptoStream(), perspective: protocol.PerspectiveServer, tracer: tracer, logger: logger, @@ -391,7 +391,7 @@ var newClientConnection = func( 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), @@ -447,8 +447,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) diff --git a/crypto_stream.go b/crypto_stream.go index 5ce2125decf..4be2a07ae1a 100644 --- a/crypto_stream.go +++ b/crypto_stream.go @@ -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 diff --git a/crypto_stream_test.go b/crypto_stream_test.go index 67de9149966..9a4a2ee57f9 100644 --- a/crypto_stream_test.go +++ b/crypto_stream_test.go @@ -1,7 +1,6 @@ package quic import ( - "crypto/rand" "fmt" "github.com/quic-go/quic-go/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)) - }) }) From 54b76ceb3e91bd1f153c47d30e90891c75d83cb8 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 9 Sep 2023 20:12:19 +0700 Subject: [PATCH 045/225] ackhandler: use the receive time of the Retry packet for RTT estimation (#4070) --- connection.go | 6 ++-- connection_test.go | 9 ++++-- internal/ackhandler/interfaces.go | 4 +-- internal/ackhandler/sent_packet_handler.go | 3 +- .../ackhandler/sent_packet_handler_test.go | 28 +++++++++++-------- .../mocks/ackhandler/sent_packet_handler.go | 8 +++--- 6 files changed, 32 insertions(+), 26 deletions(-) diff --git a/connection.go b/connection.go index 42b6c122070..1f3dadfdd02 100644 --- a/connection.go +++ b/connection.go @@ -927,7 +927,7 @@ 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. @@ -1013,7 +1013,7 @@ 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 { s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) @@ -1062,7 +1062,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte) bool /* wa } 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 } diff --git a/connection_test.go b/connection_test.go index eb512513941..8b7c763f2b4 100644 --- a/connection_test.go +++ b/connection_test.go @@ -2767,9 +2767,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")) @@ -2778,7 +2779,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() { @@ -3143,7 +3146,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")) diff --git a/internal/ackhandler/interfaces.go b/internal/ackhandler/interfaces.go index 9c4a5b80cb5..7b4eaa31e1e 100644 --- a/internal/ackhandler/interfaces.go +++ b/internal/ackhandler/interfaces.go @@ -13,10 +13,10 @@ type SentPacketHandler interface { SentPacket(t time.Time, pn, largestAcked protocol.PacketNumber, streamFrames []StreamFrame, frames []Frame, encLevel protocol.EncryptionLevel, 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. diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index c955da6e977..a03d9f5322f 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -824,7 +824,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) { @@ -850,7 +850,6 @@ 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()) diff --git a/internal/ackhandler/sent_packet_handler_test.go b/internal/ackhandler/sent_packet_handler_test.go index fc120171776..396014d7893 100644 --- a/internal/ackhandler/sent_packet_handler_test.go +++ b/internal/ackhandler/sent_packet_handler_test.go @@ -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,49 +1379,53 @@ 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()) }) }) diff --git a/internal/mocks/ackhandler/sent_packet_handler.go b/internal/mocks/ackhandler/sent_packet_handler.go index 80aaae0fad1..24f5a157123 100644 --- a/internal/mocks/ackhandler/sent_packet_handler.go +++ b/internal/mocks/ackhandler/sent_packet_handler.go @@ -148,17 +148,17 @@ func (mr *MockSentPacketHandlerMockRecorder) ReceivedBytes(arg0 interface{}) *go } // 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 interface{}) *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. From e1fcac3e4682b27880b1d0d312cc947a59bd0086 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 9 Sep 2023 20:12:37 +0700 Subject: [PATCH 046/225] set the handshake timeout to twice the handshake idle timeout (#4063) --- config.go | 3 +-- config_test.go | 7 +------ connection_test.go | 4 ++-- integrationtests/self/timeout_test.go | 2 +- interface.go | 3 ++- internal/protocol/params.go | 3 --- 6 files changed, 7 insertions(+), 15 deletions(-) diff --git a/config.go b/config.go index 59a4d9224e6..35b7c89785b 100644 --- a/config.go +++ b/config.go @@ -6,7 +6,6 @@ import ( "time" "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/quicvarint" ) @@ -17,7 +16,7 @@ func (c *Config) Clone() *Config { } func (c *Config) handshakeTimeout() time.Duration { - return utils.Max(protocol.DefaultHandshakeTimeout, 2*c.HandshakeIdleTimeout) + return 2 * c.HandshakeIdleTimeout } func validateConfig(config *Config) error { diff --git a/config_test.go b/config_test.go index 7208b4add65..87386122b66 100644 --- a/config_test.go +++ b/config_test.go @@ -115,12 +115,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)) }) diff --git a/connection_test.go b/connection_test.go index 8b7c763f2b4..4c02c492ccb 100644 --- a/connection_test.go +++ b/connection_test.go @@ -2201,7 +2201,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( @@ -2261,7 +2261,7 @@ var _ = Describe("Connection", func() { }) 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() diff --git a/integrationtests/self/timeout_test.go b/integrationtests/self/timeout_test.go index c5ec46d4b4c..47569b77e74 100644 --- a/integrationtests/self/timeout_test.go +++ b/integrationtests/self/timeout_test.go @@ -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 }() diff --git a/interface.go b/interface.go index 5d5ab5b0a0f..fadd868da6f 100644 --- a/interface.go +++ b/interface.go @@ -250,7 +250,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. diff --git a/internal/protocol/params.go b/internal/protocol/params.go index fe3a7562580..0f118c49c68 100644 --- a/internal/protocol/params.go +++ b/internal/protocol/params.go @@ -108,9 +108,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 From abfe1ef548cc407102f0e3a201847c5043abd5d4 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 10 Sep 2023 13:53:12 +0700 Subject: [PATCH 047/225] remove Config.MaxRetryTokenAge, set it to the handshake timeout (#4064) There is no good reason to manually set the validity period for Retry tokens. Retry tokens are only valid on a single connection during the handshake, so it makes sense to limit their validity to the configured handshake timeout. --- config.go | 8 ++++---- config_test.go | 2 -- integrationtests/self/handshake_test.go | 20 ++++++++++++++++++-- interface.go | 3 --- internal/protocol/params.go | 3 --- server.go | 2 +- server_test.go | 3 ++- 7 files changed, 25 insertions(+), 16 deletions(-) diff --git a/config.go b/config.go index 35b7c89785b..dea118b3932 100644 --- a/config.go +++ b/config.go @@ -19,6 +19,10 @@ func (c *Config) handshakeTimeout() time.Duration { return 2 * c.HandshakeIdleTimeout } +func (c *Config) maxRetryTokenAge() time.Duration { + return c.handshakeTimeout() +} + func validateConfig(config *Config) error { if config == nil { return nil @@ -52,9 +56,6 @@ func populateServerConfig(config *Config) *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 } } @@ -114,7 +115,6 @@ func populateConfig(config *Config) *Config { HandshakeIdleTimeout: handshakeIdleTimeout, MaxIdleTimeout: idleTimeout, MaxTokenAge: config.MaxTokenAge, - MaxRetryTokenAge: config.MaxRetryTokenAge, RequireAddressValidation: config.RequireAddressValidation, KeepAlivePeriod: config.KeepAlivePeriod, InitialStreamReceiveWindow: initialStreamReceiveWindow, diff --git a/config_test.go b/config_test.go index 87386122b66..9cb665a30b8 100644 --- a/config_test.go +++ b/config_test.go @@ -80,8 +80,6 @@ var _ = Describe("Config", func() { 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": diff --git a/integrationtests/self/handshake_test.go b/integrationtests/self/handshake_test.go index 8123c8fe043..f90ac2fd690 100644 --- a/integrationtests/self/handshake_test.go +++ b/integrationtests/self/handshake_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/quic-go/quic-go" + quicproxy "github.com/quic-go/quic-go/integrationtests/tools/proxy" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/qtls" @@ -454,16 +455,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, ) diff --git a/interface.go b/interface.go index fadd868da6f..8faf0eb8e27 100644 --- a/interface.go +++ b/interface.go @@ -265,9 +265,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. diff --git a/internal/protocol/params.go b/internal/protocol/params.go index 0f118c49c68..3ca68bf83d0 100644 --- a/internal/protocol/params.go +++ b/internal/protocol/params.go @@ -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. diff --git a/server.go b/server.go index 495ca65ac93..92b5e91a6c8 100644 --- a/server.go +++ b/server.go @@ -531,7 +531,7 @@ func (s *baseServer) validateToken(token *handshake.Token, addr net.Addr) bool { if !token.IsRetryToken && time.Since(token.SentTime) > s.config.MaxTokenAge { return false } - if token.IsRetryToken && time.Since(token.SentTime) > s.config.MaxRetryTokenAge { + if token.IsRetryToken && time.Since(token.SentTime) > s.config.maxRetryTokenAge() { return false } return true diff --git a/server_test.go b/server_test.go index e959aee5d0b..31a977648d8 100644 --- a/server_test.go +++ b/server_test.go @@ -833,7 +833,8 @@ var _ = Describe("Server", func() { It("sends an INVALID_TOKEN error, if an expired retry token is received", func() { serv.config.RequireAddressValidation = func(net.Addr) bool { return true } - serv.config.MaxRetryTokenAge = time.Millisecond + serv.config.HandshakeIdleTimeout = time.Millisecond / 2 // the maximum retry token age is equivalent to the handshake timeout + Expect(serv.config.maxRetryTokenAge()).To(Equal(time.Millisecond)) raddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337} token, err := serv.tokenGenerator.NewRetryToken(raddr, protocol.ConnectionID{}, protocol.ConnectionID{}) Expect(err).ToNot(HaveOccurred()) From a7f807856cf74836e6734ea04620679a21fcaf95 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 11 Sep 2023 11:49:29 +0700 Subject: [PATCH 048/225] randomize the serialization order of control frames (#4069) * randomize the serialization order of control frames * add comment for packetPacker.appendPacketPayload --- packet_packer.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packet_packer.go b/packet_packer.go index 577f3b043a4..0483f35bfb4 100644 --- a/packet_packer.go +++ b/packet_packer.go @@ -1,9 +1,13 @@ package quic import ( + crand "crypto/rand" + "encoding/binary" "errors" "fmt" + "golang.org/x/exp/rand" + "github.com/quic-go/quic-go/internal/ackhandler" "github.com/quic-go/quic-go/internal/handshake" "github.com/quic-go/quic-go/internal/protocol" @@ -122,6 +126,7 @@ type packetPacker struct { acks ackFrameSource datagramQueue *datagramQueue retransmissionQueue *retransmissionQueue + rand rand.Rand numNonAckElicitingAcks int } @@ -140,6 +145,9 @@ func newPacketPacker( datagramQueue *datagramQueue, perspective protocol.Perspective, ) *packetPacker { + var b [8]byte + _, _ = crand.Read(b[:]) + return &packetPacker{ cryptoSetup: cryptoSetup, getDestConnID: getDestConnID, @@ -151,6 +159,7 @@ func newPacketPacker( perspective: perspective, framer: framer, acks: acks, + rand: *rand.New(rand.NewSource(binary.BigEndian.Uint64(b[:]))), pnManager: packetNumberManager, } } @@ -832,6 +841,8 @@ func (p *packetPacker) appendShortHeaderPacket( }, nil } +// appendPacketPayload serializes the payload of a packet into the raw byte slice. +// It modifies the order of payload.frames. func (p *packetPacker) appendPacketPayload(raw []byte, pl payload, paddingLen protocol.ByteCount, v protocol.VersionNumber) ([]byte, error) { payloadOffset := len(raw) if pl.ack != nil { @@ -844,6 +855,11 @@ func (p *packetPacker) appendPacketPayload(raw []byte, pl payload, paddingLen pr if paddingLen > 0 { raw = append(raw, make([]byte, paddingLen)...) } + // Randomize the order of the control frames. + // This makes sure that the receiver doesn't rely on the order in which frames are packed. + if len(pl.frames) > 1 { + p.rand.Shuffle(len(pl.frames), func(i, j int) { pl.frames[i], pl.frames[j] = pl.frames[j], pl.frames[i] }) + } for _, f := range pl.frames { var err error raw, err = f.Frame.Append(raw, v) From f919473598e73a57dc7dde987f33b9d2822e8893 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 30 Jul 2023 13:42:15 -0400 Subject: [PATCH 049/225] add support for writing the ECN control message (Linux, macOS) --- send_conn.go | 13 ++++++++++--- sys_conn_df_windows.go | 4 ++++ sys_conn_helper_darwin.go | 2 ++ sys_conn_helper_freebsd.go | 2 ++ sys_conn_helper_linux.go | 2 ++ sys_conn_no_oob.go | 5 +++++ sys_conn_oob.go | 30 ++++++++++++++++++++++++++++++ sys_conn_oob_test.go | 36 ++++++++++++++++++++++++++++++++++++ 8 files changed, 91 insertions(+), 3 deletions(-) diff --git a/send_conn.go b/send_conn.go index 272c61b1248..030e0fba7e1 100644 --- a/send_conn.go +++ b/send_conn.go @@ -3,6 +3,7 @@ package quic import ( "net" + "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" ) @@ -42,10 +43,16 @@ func newSendConn(c rawConn, remote net.Addr, info packetInfo, logger utils.Logge } oob := info.OOB() - // add 32 bytes, so we can add the UDP_SEGMENT msg + if remoteUDPAddr, ok := remote.(*net.UDPAddr); ok { + if remoteUDPAddr.IP.To4() != nil { + oob = appendIPv4ECNMsg(oob, protocol.ECT1) + } else { + oob = appendIPv6ECNMsg(oob, protocol.ECT1) + } + } + // increase oob slice capacity, so we can add the UDP_SEGMENT and ECN control messages without allocating l := len(oob) - oob = append(oob, make([]byte, 32)...) - oob = oob[:l] + oob = append(oob, make([]byte, 64)...)[:l] return &sconn{ rawConn: c, localAddr: localAddr, diff --git a/sys_conn_df_windows.go b/sys_conn_df_windows.go index e27635ec9c8..e56b7460781 100644 --- a/sys_conn_df_windows.go +++ b/sys_conn_df_windows.go @@ -8,6 +8,7 @@ import ( "golang.org/x/sys/windows" + "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" ) @@ -52,3 +53,6 @@ func isRecvMsgSizeErr(err error) bool { // https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2 return errors.Is(err, windows.WSAEMSGSIZE) } + +func appendIPv4ECNMsg([]byte, protocol.ECN) []byte { return nil } +func appendIPv6ECNMsg([]byte, protocol.ECN) []byte { return nil } diff --git a/sys_conn_helper_darwin.go b/sys_conn_helper_darwin.go index 758cf77889f..d761072f206 100644 --- a/sys_conn_helper_darwin.go +++ b/sys_conn_helper_darwin.go @@ -15,6 +15,8 @@ const ( ipv4PKTINFO = unix.IP_RECVPKTINFO ) +const ecnIPv4DataLen = 4 + // ReadBatch only returns a single packet on OSX, // see https://godoc.org/golang.org/x/net/ipv4#PacketConn.ReadBatch. const batchSize = 1 diff --git a/sys_conn_helper_freebsd.go b/sys_conn_helper_freebsd.go index a2baae3b38e..5e635b18df8 100644 --- a/sys_conn_helper_freebsd.go +++ b/sys_conn_helper_freebsd.go @@ -14,6 +14,8 @@ const ( ipv4PKTINFO = 0x7 ) +const ecnIPv4DataLen = 4 + const batchSize = 8 func parseIPv4PktInfo(body []byte) (ip netip.Addr, _ uint32, ok bool) { diff --git a/sys_conn_helper_linux.go b/sys_conn_helper_linux.go index 6a049241bd5..622f4e6f344 100644 --- a/sys_conn_helper_linux.go +++ b/sys_conn_helper_linux.go @@ -19,6 +19,8 @@ const ( ipv4PKTINFO = unix.IP_PKTINFO ) +const ecnIPv4DataLen = 4 + const batchSize = 8 // needs to smaller than MaxUint8 (otherwise the type of oobConn.readPos has to be changed) func forceSetReceiveBuffer(c syscall.RawConn, bytes int) error { diff --git a/sys_conn_no_oob.go b/sys_conn_no_oob.go index 2a1f807efd4..c1fb6fb192d 100644 --- a/sys_conn_no_oob.go +++ b/sys_conn_no_oob.go @@ -5,6 +5,8 @@ package quic import ( "net" "net/netip" + + "github.com/quic-go/quic-go/internal/protocol" ) func newConn(c net.PacketConn, supportsDF bool) (*basicConn, error) { @@ -14,6 +16,9 @@ func newConn(c net.PacketConn, supportsDF bool) (*basicConn, error) { func inspectReadBuffer(any) (int, error) { return 0, nil } func inspectWriteBuffer(any) (int, error) { return 0, nil } +func appendIPv4ECNMsg([]byte, protocol.ECN) []byte { return nil } +func appendIPv6ECNMsg([]byte, protocol.ECN) []byte { return nil } + type packetInfo struct { addr netip.Addr } diff --git a/sys_conn_oob.go b/sys_conn_oob.go index 24b73e9cc9a..6446d89384a 100644 --- a/sys_conn_oob.go +++ b/sys_conn_oob.go @@ -11,6 +11,7 @@ import ( "sync" "syscall" "time" + "unsafe" "golang.org/x/net/ipv4" "golang.org/x/net/ipv6" @@ -279,3 +280,32 @@ func (info *packetInfo) OOB() []byte { } return nil } + +func appendIPv4ECNMsg(b []byte, val protocol.ECN) []byte { + startLen := len(b) + b = append(b, make([]byte, unix.CmsgSpace(ecnIPv4DataLen))...) + h := (*unix.Cmsghdr)(unsafe.Pointer(&b[startLen])) + h.Level = syscall.IPPROTO_IP + h.Type = unix.IP_TOS + h.SetLen(unix.CmsgLen(ecnIPv4DataLen)) + + // UnixRights uses the private `data` method, but I *think* this achieves the same goal. + offset := startLen + unix.CmsgSpace(0) + b[offset] = uint8(val) + return b +} + +func appendIPv6ECNMsg(b []byte, val protocol.ECN) []byte { + startLen := len(b) + const dataLen = 4 + b = append(b, make([]byte, unix.CmsgSpace(dataLen))...) + h := (*unix.Cmsghdr)(unsafe.Pointer(&b[startLen])) + h.Level = syscall.IPPROTO_IPV6 + h.Type = unix.IPV6_TCLASS + h.SetLen(unix.CmsgLen(dataLen)) + + // UnixRights uses the private `data` method, but I *think* this achieves the same goal. + offset := startLen + unix.CmsgSpace(0) + b[offset] = uint8(val) + return b +} diff --git a/sys_conn_oob_test.go b/sys_conn_oob_test.go index 54dac82d27c..9d0f5e9d23c 100644 --- a/sys_conn_oob_test.go +++ b/sys_conn_oob_test.go @@ -139,6 +139,42 @@ var _ = Describe("OOB Conn Test", func() { Expect(utils.IsIPv4(p.remoteAddr.(*net.UDPAddr).IP)).To(BeFalse()) Expect(p.ecn).To(Equal(protocol.ECT1)) }) + + It("sends packets with ECN on IPv4", func() { + conn, packetChan := runServer("udp4", "localhost:0") + defer conn.Close() + + c, err := net.ListenUDP("udp4", nil) + Expect(err).ToNot(HaveOccurred()) + defer c.Close() + + for _, val := range []protocol.ECN{protocol.ECNNon, protocol.ECT1, protocol.ECT0, protocol.ECNCE} { + _, _, err = c.WriteMsgUDP([]byte("foobar"), appendIPv4ECNMsg([]byte{}, val), conn.LocalAddr().(*net.UDPAddr)) + Expect(err).ToNot(HaveOccurred()) + var p receivedPacket + Eventually(packetChan).Should(Receive(&p)) + Expect(p.data).To(Equal([]byte("foobar"))) + Expect(p.ecn).To(Equal(val)) + } + }) + + It("sends packets with ECN on IPv6", func() { + conn, packetChan := runServer("udp6", "[::1]:0") + defer conn.Close() + + c, err := net.ListenUDP("udp6", nil) + Expect(err).ToNot(HaveOccurred()) + defer c.Close() + + for _, val := range []protocol.ECN{protocol.ECNNon, protocol.ECT1, protocol.ECT0, protocol.ECNCE} { + _, _, err = c.WriteMsgUDP([]byte("foobar"), appendIPv6ECNMsg([]byte{}, val), conn.LocalAddr().(*net.UDPAddr)) + Expect(err).ToNot(HaveOccurred()) + var p receivedPacket + Eventually(packetChan).Should(Receive(&p)) + Expect(p.data).To(Equal([]byte("foobar"))) + Expect(p.ecn).To(Equal(val)) + } + }) }) Context("Packet Info conn", func() { From 5dd6d91c11eb6ecf871c1a134ececb71c2e73a9e Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 12 Aug 2023 10:08:40 +0800 Subject: [PATCH 050/225] send and track packets with ECN markings --- connection.go | 65 +++--- connection_test.go | 200 +++++++++--------- internal/ackhandler/interfaces.go | 4 +- internal/ackhandler/sent_packet_handler.go | 6 + .../ackhandler/sent_packet_handler_test.go | 2 +- .../mocks/ackhandler/sent_packet_handler.go | 22 +- mock_raw_conn_test.go | 9 +- mock_send_conn_test.go | 9 +- mock_sender_test.go | 9 +- packet_handler_map.go | 2 +- send_conn.go | 15 +- send_conn_test.go | 17 +- send_queue.go | 12 +- send_queue_test.go | 36 ++-- server.go | 6 +- sys_conn.go | 2 +- sys_conn_df_windows.go | 4 - sys_conn_no_oob.go | 5 - sys_conn_oob.go | 9 +- sys_conn_oob_test.go | 30 ++- transport.go | 6 +- 21 files changed, 264 insertions(+), 206 deletions(-) diff --git a/connection.go b/connection.go index 1f3dadfdd02..f234ea3f38e 100644 --- a/connection.go +++ b/connection.go @@ -1830,9 +1830,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, 0) + ecn := s.sentPacketHandler.ECNMode() + 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 @@ -1852,7 +1853,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(), now); err != nil { return err } sendMode := s.sentPacketHandler.SendMode(now) @@ -1873,7 +1874,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() + if _, err := s.appendOnePacket(buf, s.mtuDiscoverer.CurrentSize(), ecn, now); err != nil { if err == errNothingToPack { buf.Release() return nil @@ -1881,7 +1883,7 @@ func (s *connection) sendPacketsWithoutGSO(now time.Time) error { return err } - s.sendQueue.Send(buf, 0) + s.sendQueue.Send(buf, 0, ecn) if s.sendQueue.WouldBlock() { return nil @@ -1908,7 +1910,8 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error { for { var dontSendMore bool - size, err := s.appendPacket(buf, maxSize, now) + ecn := s.sentPacketHandler.ECNMode() + size, err := s.appendOnePacket(buf, maxSize, ecn, now) if err != nil { if err != errNothingToPack { return err @@ -1938,7 +1941,7 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error { continue } - s.sendQueue.Send(buf, uint16(maxSize)) + s.sendQueue.Send(buf, uint16(maxSize), ecn) if dontSendMore { return nil @@ -1966,6 +1969,7 @@ func (s *connection) resetPacingDeadline() { } func (s *connection) maybeSendAckOnlyPacket(now time.Time) error { + ecn := s.sentPacketHandler.ECNMode() if !s.handshakeConfirmed { packet, err := s.packer.PackCoalescedPacket(true, s.mtuDiscoverer.CurrentSize(), s.version) if err != nil { @@ -1974,7 +1978,7 @@ 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()) } p, buf, err := s.packer.PackAckOnlyPacket(s.mtuDiscoverer.CurrentSize(), s.version) @@ -1984,9 +1988,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, 0) + 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 } @@ -2018,24 +2022,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(), now) } -// appendPacket appends a new packet to the given packetBuffer. +// appendOnePacket 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) appendOnePacket(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 } @@ -2044,12 +2048,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 @@ -2058,7 +2062,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. @@ -2075,10 +2079,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, 0) + s.sendQueue.Send(packet.buffer, 0, ecn) return nil } @@ -2100,8 +2104,9 @@ 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, 0) + ecn := s.sentPacketHandler.ECNMode() + s.logCoalescedPacket(packet, ecn) + return packet.buffer.Data, s.conn.Write(packet.buffer.Data, 0, ecn) } func (s *connection) logLongHeaderPacket(p *longHeaderPacket) { @@ -2144,11 +2149,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() { @@ -2191,7 +2197,7 @@ func (s *connection) logShortHeaderPacket( } } -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. @@ -2204,6 +2210,7 @@ func (s *connection) logCoalescedPacket(packet *coalescedPacket) { packet.shortHdrPacket.PacketNumber, packet.shortHdrPacket.PacketNumberLen, packet.shortHdrPacket.KeyPhase, + ecn, packet.shortHdrPacket.Length, false, ) @@ -2219,7 +2226,7 @@ func (s *connection) logCoalescedPacket(packet *coalescedPacket) { s.logLongHeaderPacket(p) } 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) } } diff --git a/connection_test.go b/connection_test.go index 4c02c492ccb..828f4ced1b2 100644 --- a/connection_test.go +++ b/connection_test.go @@ -454,7 +454,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 @@ -475,7 +475,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() @@ -494,7 +494,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(), @@ -516,7 +516,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(), @@ -565,7 +565,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() @@ -609,13 +609,14 @@ 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().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()) + 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()) tracer.EXPECT().ClosedConnection(gomock.Any()) tracer.EXPECT().Close() @@ -837,7 +838,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()) }) @@ -872,7 +873,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()) }) @@ -908,7 +909,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()) }) @@ -930,7 +931,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() @@ -958,7 +959,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()) }) @@ -980,7 +981,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)) @@ -1190,6 +1191,7 @@ var _ = Describe("Connection", func() { var ( connDone chan struct{} sender *MockSender + sph *mockackhandler.MockSentPacketHandler ) BeforeEach(func() { @@ -1198,14 +1200,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().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() @@ -1226,12 +1231,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().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}), @@ -1243,7 +1247,7 @@ 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, uint16) { 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, @@ -1256,6 +1260,9 @@ var _ = Describe("Connection", func() { 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().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) @@ -1264,13 +1271,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().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()) @@ -1278,12 +1284,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().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")) @@ -1291,7 +1296,7 @@ var _ = Describe("Connection", func() { conn.connFlowController = fc runConn() sent := make(chan struct{}) - sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16) { close(sent) }) + sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(sent) }) tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), nil, []logging.Frame{}) conn.scheduleSending() Eventually(sent).Should(BeClosed()) @@ -1300,11 +1305,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) @@ -1333,21 +1336,19 @@ 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() 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, uint16) { 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()) } else { @@ -1358,21 +1359,18 @@ var _ = Describe("Connection", func() { }) 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() 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, uint16) { 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()) } else { @@ -1409,10 +1407,11 @@ var _ = Describe("Connection", func() { AfterEach(func() { // make the go routine return + sph.EXPECT().ECNMode().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() @@ -1421,17 +1420,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().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, _ uint16) { + 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, _ uint16) { + 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() { @@ -1446,7 +1446,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().Times(3) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3) payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize()) rand.Read(payload1) @@ -1456,7 +1457,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(), uint16(conn.mtuDiscoverer.CurrentSize())).Do(func(b *packetBuffer, l uint16) { + 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() { @@ -1471,8 +1472,9 @@ 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().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().Times(2) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone) payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize()) rand.Read(payload1) @@ -1481,7 +1483,7 @@ var _ = Describe("Connection", func() { expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, payload1) expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2) sender.EXPECT().WouldBlock().AnyTimes() - sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize())).Do(func(b *packetBuffer, l uint16) { + 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() { @@ -1495,12 +1497,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().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) @@ -1512,13 +1515,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() 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) @@ -1532,12 +1536,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().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) @@ -1552,19 +1557,21 @@ var _ = Describe("Connection", func() { pacingDelay := scaleDuration(100 * time.Millisecond) gomock.InOrder( sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny), + sph.EXPECT().ECNMode(), 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(), 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, uint16) { 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) @@ -1578,8 +1585,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().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++ { @@ -1587,7 +1595,7 @@ var _ = Describe("Connection", func() { } written := make(chan struct{}, 3) sender.EXPECT().WouldBlock().AnyTimes() - sender.EXPECT().Send(gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16) { 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) @@ -1618,11 +1626,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().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, uint16) { 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()) }) @@ -1639,14 +1648,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().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, uint16) { 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)) @@ -1655,13 +1665,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() 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, uint16) { 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) @@ -1675,12 +1686,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().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, uint16) { 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()) @@ -1691,6 +1703,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().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() @@ -1708,12 +1721,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() 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, uint16) { 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)) @@ -1747,7 +1761,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() @@ -1760,8 +1774,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().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) @@ -1776,7 +1791,7 @@ 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, uint16) { close(written) }) + 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()).AnyTimes() conn.scheduleSending() Eventually(written).Should(BeClosed()) @@ -1788,9 +1803,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().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)) @@ -1799,7 +1813,7 @@ var _ = Describe("Connection", func() { conn.receivedPacketHandler = rph written := make(chan struct{}) - sender.EXPECT().Send(gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16) { close(written) }) + 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()).AnyTimes() go func() { defer GinkgoRecover() @@ -1841,18 +1855,11 @@ var _ = Describe("Connection", func() { sph.EXPECT().GetLossDetectionTimeout().AnyTimes() sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes() + sph.EXPECT().ECNMode().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) { @@ -1864,7 +1871,7 @@ var _ = Describe("Connection", func() { ) sent := make(chan struct{}) - mconn.EXPECT().Write([]byte("foobar"), uint16(0)).Do(func([]byte, uint16) { close(sent) }) + mconn.EXPECT().Write([]byte("foobar"), uint16(0), protocol.ECT1).Do(func([]byte, uint16, protocol.ECN) { close(sent) }) go func() { defer GinkgoRecover() @@ -1881,7 +1888,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() @@ -1952,7 +1959,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()) @@ -1961,11 +1968,12 @@ 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().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()) + 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()) conn.sentPacketHandler = sph done := make(chan struct{}) @@ -1987,7 +1995,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() }() @@ -2016,7 +2024,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() @@ -2043,7 +2051,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()) @@ -2102,7 +2110,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() @@ -2255,7 +2263,7 @@ 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()) }) @@ -2338,7 +2346,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() @@ -2554,7 +2562,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() @@ -2851,7 +2859,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(), diff --git a/internal/ackhandler/interfaces.go b/internal/ackhandler/interfaces.go index 7b4eaa31e1e..ba224228a51 100644 --- a/internal/ackhandler/interfaces.go +++ b/internal/ackhandler/interfaces.go @@ -10,7 +10,7 @@ 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, rcvTime time.Time) (bool /* 1-RTT packet acked */, error) @@ -29,6 +29,8 @@ type SentPacketHandler interface { // only to be called once the handshake is complete QueueProbePacket(protocol.EncryptionLevel) bool /* was a packet queued */ + ECNMode() protocol.ECN + PeekPacketNumber(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen) PopPacketNumber(protocol.EncryptionLevel) protocol.PacketNumber diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index a03d9f5322f..3b972b667be 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -228,6 +228,7 @@ func (h *sentPacketHandler) SentPacket( streamFrames []StreamFrame, frames []Frame, encLevel protocol.EncryptionLevel, + _ protocol.ECN, size protocol.ByteCount, isPathMTUProbePacket bool, ) { @@ -712,6 +713,11 @@ func (h *sentPacketHandler) GetLossDetectionTimeout() time.Time { return h.alarm } +func (h *sentPacketHandler) ECNMode() protocol.ECN { + // TODO: implement ECN logic + return protocol.ECNNon +} + func (h *sentPacketHandler) PeekPacketNumber(encLevel protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen) { pnSpace := h.getPacketNumberSpace(encLevel) pn := pnSpace.pns.Peek() diff --git a/internal/ackhandler/sent_packet_handler_test.go b/internal/ackhandler/sent_packet_handler_test.go index 396014d7893..614b7c85756 100644 --- a/internal/ackhandler/sent_packet_handler_test.go +++ b/internal/ackhandler/sent_packet_handler_test.go @@ -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) { diff --git a/internal/mocks/ackhandler/sent_packet_handler.go b/internal/mocks/ackhandler/sent_packet_handler.go index 24f5a157123..3479d9e617c 100644 --- a/internal/mocks/ackhandler/sent_packet_handler.go +++ b/internal/mocks/ackhandler/sent_packet_handler.go @@ -49,6 +49,20 @@ func (mr *MockSentPacketHandlerMockRecorder) DropPackets(arg0 interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropPackets", reflect.TypeOf((*MockSentPacketHandler)(nil).DropPackets), arg0) } +// ECNMode mocks base method. +func (m *MockSentPacketHandler) ECNMode() protocol.ECN { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ECNMode") + ret0, _ := ret[0].(protocol.ECN) + return ret0 +} + +// ECNMode indicates an expected call of ECNMode. +func (mr *MockSentPacketHandlerMockRecorder) ECNMode() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNMode", reflect.TypeOf((*MockSentPacketHandler)(nil).ECNMode)) +} + // GetLossDetectionTimeout mocks base method. func (m *MockSentPacketHandler) GetLossDetectionTimeout() time.Time { m.ctrl.T.Helper() @@ -176,15 +190,15 @@ func (mr *MockSentPacketHandlerMockRecorder) SendMode(arg0 interface{}) *gomock. } // 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 interface{}) *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. diff --git a/mock_raw_conn_test.go b/mock_raw_conn_test.go index 84d8f276b3e..d462fc87dc0 100644 --- a/mock_raw_conn_test.go +++ b/mock_raw_conn_test.go @@ -9,6 +9,7 @@ import ( reflect "reflect" time "time" + protocol "github.com/quic-go/quic-go/internal/protocol" gomock "go.uber.org/mock/gomock" ) @@ -93,18 +94,18 @@ func (mr *MockRawConnMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Cal } // WritePacket mocks base method. -func (m *MockRawConn) WritePacket(arg0 []byte, arg1 net.Addr, arg2 []byte, arg3 uint16) (int, error) { +func (m *MockRawConn) WritePacket(arg0 []byte, arg1 net.Addr, arg2 []byte, arg3 uint16, arg4 protocol.ECN) (int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "WritePacket", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "WritePacket", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(int) ret1, _ := ret[1].(error) return ret0, ret1 } // WritePacket indicates an expected call of WritePacket. -func (mr *MockRawConnMockRecorder) WritePacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockRawConnMockRecorder) WritePacket(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePacket", reflect.TypeOf((*MockRawConn)(nil).WritePacket), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePacket", reflect.TypeOf((*MockRawConn)(nil).WritePacket), arg0, arg1, arg2, arg3, arg4) } // capabilities mocks base method. diff --git a/mock_send_conn_test.go b/mock_send_conn_test.go index 529b9c58f22..6568f9e5ffb 100644 --- a/mock_send_conn_test.go +++ b/mock_send_conn_test.go @@ -8,6 +8,7 @@ import ( net "net" reflect "reflect" + protocol "github.com/quic-go/quic-go/internal/protocol" gomock "go.uber.org/mock/gomock" ) @@ -77,17 +78,17 @@ func (mr *MockSendConnMockRecorder) RemoteAddr() *gomock.Call { } // Write mocks base method. -func (m *MockSendConn) Write(arg0 []byte, arg1 uint16) error { +func (m *MockSendConn) Write(arg0 []byte, arg1 uint16, arg2 protocol.ECN) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Write", arg0, arg1) + ret := m.ctrl.Call(m, "Write", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // Write indicates an expected call of Write. -func (mr *MockSendConnMockRecorder) Write(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSendConnMockRecorder) Write(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendConn)(nil).Write), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendConn)(nil).Write), arg0, arg1, arg2) } // capabilities mocks base method. diff --git a/mock_sender_test.go b/mock_sender_test.go index 406715623bb..67bb9d09e42 100644 --- a/mock_sender_test.go +++ b/mock_sender_test.go @@ -7,6 +7,7 @@ package quic import ( reflect "reflect" + protocol "github.com/quic-go/quic-go/internal/protocol" gomock "go.uber.org/mock/gomock" ) @@ -74,15 +75,15 @@ func (mr *MockSenderMockRecorder) Run() *gomock.Call { } // Send mocks base method. -func (m *MockSender) Send(arg0 *packetBuffer, arg1 uint16) { +func (m *MockSender) Send(arg0 *packetBuffer, arg1 uint16, arg2 protocol.ECN) { m.ctrl.T.Helper() - m.ctrl.Call(m, "Send", arg0, arg1) + m.ctrl.Call(m, "Send", arg0, arg1, arg2) } // Send indicates an expected call of Send. -func (mr *MockSenderMockRecorder) Send(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) Send(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockSender)(nil).Send), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockSender)(nil).Send), arg0, arg1, arg2) } // WouldBlock mocks base method. diff --git a/packet_handler_map.go b/packet_handler_map.go index 60b7cef9b26..d7d92377c5e 100644 --- a/packet_handler_map.go +++ b/packet_handler_map.go @@ -29,7 +29,7 @@ type rawConn interface { // WritePacket writes a packet on the wire. // gsoSize is the size of a single packet, or 0 to disable GSO. // It is invalid to set gsoSize if capabilities.GSO is not set. - WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gsoSize uint16) (int, error) + WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gsoSize uint16, ecn protocol.ECN) (int, error) LocalAddr() net.Addr SetReadDeadline(time.Time) error io.Closer diff --git a/send_conn.go b/send_conn.go index 030e0fba7e1..4fda1469122 100644 --- a/send_conn.go +++ b/send_conn.go @@ -9,7 +9,7 @@ import ( // A sendConn allows sending using a simple Write() on a non-connected packet conn. type sendConn interface { - Write(b []byte, gsoSize uint16) error + Write(b []byte, gsoSize uint16, ecn protocol.ECN) error Close() error LocalAddr() net.Addr RemoteAddr() net.Addr @@ -43,13 +43,6 @@ func newSendConn(c rawConn, remote net.Addr, info packetInfo, logger utils.Logge } oob := info.OOB() - if remoteUDPAddr, ok := remote.(*net.UDPAddr); ok { - if remoteUDPAddr.IP.To4() != nil { - oob = appendIPv4ECNMsg(oob, protocol.ECT1) - } else { - oob = appendIPv6ECNMsg(oob, protocol.ECT1) - } - } // increase oob slice capacity, so we can add the UDP_SEGMENT and ECN control messages without allocating l := len(oob) oob = append(oob, make([]byte, 64)...)[:l] @@ -62,8 +55,8 @@ func newSendConn(c rawConn, remote net.Addr, info packetInfo, logger utils.Logge } } -func (c *sconn) Write(p []byte, gsoSize uint16) error { - _, err := c.WritePacket(p, c.remoteAddr, c.packetInfoOOB, gsoSize) +func (c *sconn) Write(p []byte, gsoSize uint16, ecn protocol.ECN) error { + _, err := c.WritePacket(p, c.remoteAddr, c.packetInfoOOB, gsoSize, ecn) if err != nil && isGSOError(err) { // disable GSO for future calls c.gotGSOError = true @@ -76,7 +69,7 @@ func (c *sconn) Write(p []byte, gsoSize uint16) error { if l > int(gsoSize) { l = int(gsoSize) } - if _, err := c.WritePacket(p[:l], c.remoteAddr, c.packetInfoOOB, 0); err != nil { + if _, err := c.WritePacket(p[:l], c.remoteAddr, c.packetInfoOOB, 0, ecn); err != nil { return err } p = p[l:] diff --git a/send_conn_test.go b/send_conn_test.go index 963f2482295..bbac8fe7c3d 100644 --- a/send_conn_test.go +++ b/send_conn_test.go @@ -5,6 +5,7 @@ import ( "net/netip" "runtime" + "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" . "github.com/onsi/ginkgo/v2" @@ -45,8 +46,8 @@ var _ = Describe("Connection (for sending packets)", func() { pi := packetInfo{addr: netip.IPv6Loopback()} Expect(pi.OOB()).ToNot(BeEmpty()) c := newSendConn(rawConn, remoteAddr, pi, utils.DefaultLogger) - rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, pi.OOB(), uint16(0)) - Expect(c.Write([]byte("foobar"), 0)).To(Succeed()) + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, pi.OOB(), uint16(0), protocol.ECT1) + Expect(c.Write([]byte("foobar"), 0, protocol.ECT1)).To(Succeed()) }) } @@ -55,8 +56,8 @@ var _ = Describe("Connection (for sending packets)", func() { rawConn.EXPECT().LocalAddr() rawConn.EXPECT().capabilities().AnyTimes() c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) - rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any(), uint16(3)) - Expect(c.Write([]byte("foobar"), 3)).To(Succeed()) + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any(), uint16(3), protocol.ECNCE) + Expect(c.Write([]byte("foobar"), 3, protocol.ECNCE)).To(Succeed()) }) if platformSupportsGSO { @@ -67,11 +68,11 @@ var _ = Describe("Connection (for sending packets)", func() { c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) Expect(c.capabilities().GSO).To(BeTrue()) gomock.InOrder( - rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any(), uint16(4)).Return(0, errGSO), - rawConn.EXPECT().WritePacket([]byte("foob"), remoteAddr, gomock.Any(), uint16(0)).Return(4, nil), - rawConn.EXPECT().WritePacket([]byte("ar"), remoteAddr, gomock.Any(), uint16(0)).Return(2, nil), + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any(), uint16(4), protocol.ECNCE).Return(0, errGSO), + rawConn.EXPECT().WritePacket([]byte("foob"), remoteAddr, gomock.Any(), uint16(0), protocol.ECNCE).Return(4, nil), + rawConn.EXPECT().WritePacket([]byte("ar"), remoteAddr, gomock.Any(), uint16(0), protocol.ECNCE).Return(2, nil), ) - Expect(c.Write([]byte("foobar"), 4)).To(Succeed()) + Expect(c.Write([]byte("foobar"), 4, protocol.ECNCE)).To(Succeed()) Expect(c.capabilities().GSO).To(BeFalse()) }) } diff --git a/send_queue.go b/send_queue.go index 2da546e510d..bde02334858 100644 --- a/send_queue.go +++ b/send_queue.go @@ -1,8 +1,9 @@ package quic +import "github.com/quic-go/quic-go/internal/protocol" + type sender interface { - // Send sends a packet. GSO is only used if gsoSize > 0. - Send(p *packetBuffer, gsoSize uint16) + Send(p *packetBuffer, gsoSize uint16, ecn protocol.ECN) Run() error WouldBlock() bool Available() <-chan struct{} @@ -12,6 +13,7 @@ type sender interface { type queueEntry struct { buf *packetBuffer gsoSize uint16 + ecn protocol.ECN } type sendQueue struct { @@ -39,9 +41,9 @@ func newSendQueue(conn sendConn) sender { // Send sends out a packet. It's guaranteed to not block. // Callers need to make sure that there's actually space in the send queue by calling WouldBlock. // Otherwise Send will panic. -func (h *sendQueue) Send(p *packetBuffer, gsoSize uint16) { +func (h *sendQueue) Send(p *packetBuffer, gsoSize uint16, ecn protocol.ECN) { select { - case h.queue <- queueEntry{buf: p, gsoSize: gsoSize}: + case h.queue <- queueEntry{buf: p, gsoSize: gsoSize, ecn: ecn}: // clear available channel if we've reached capacity if len(h.queue) == sendQueueCapacity { select { @@ -76,7 +78,7 @@ func (h *sendQueue) Run() error { // make sure that all queued packets are actually sent out shouldClose = true case e := <-h.queue: - if err := h.conn.Write(e.buf.Data, e.gsoSize); err != nil { + if err := h.conn.Write(e.buf.Data, e.gsoSize, e.ecn); err != nil { // This additional check enables: // 1. Checking for "datagram too large" message from the kernel, as such, // 2. Path MTU discovery,and diff --git a/send_queue_test.go b/send_queue_test.go index 0ed7bea5758..e8cb8bdc048 100644 --- a/send_queue_test.go +++ b/send_queue_test.go @@ -3,6 +3,8 @@ package quic import ( "errors" + "github.com/quic-go/quic-go/internal/protocol" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "go.uber.org/mock/gomock" @@ -26,10 +28,10 @@ var _ = Describe("Send Queue", func() { It("sends a packet", func() { p := getPacket([]byte("foobar")) - q.Send(p, 10) // make sure the packet size is passed through to the conn + q.Send(p, 10, protocol.ECT1) // make sure the packet size is passed through to the conn written := make(chan struct{}) - c.EXPECT().Write([]byte("foobar"), uint16(10)).Do(func([]byte, uint16) { close(written) }) + c.EXPECT().Write([]byte("foobar"), uint16(10), protocol.ECT1).Do(func([]byte, uint16, protocol.ECN) { close(written) }) done := make(chan struct{}) go func() { defer GinkgoRecover() @@ -45,19 +47,19 @@ var _ = Describe("Send Queue", func() { It("panics when Send() is called although there's no space in the queue", func() { for i := 0; i < sendQueueCapacity; i++ { Expect(q.WouldBlock()).To(BeFalse()) - q.Send(getPacket([]byte("foobar")), 6) + q.Send(getPacket([]byte("foobar")), 6, protocol.ECNNon) } Expect(q.WouldBlock()).To(BeTrue()) - Expect(func() { q.Send(getPacket([]byte("raboof")), 6) }).To(Panic()) + Expect(func() { q.Send(getPacket([]byte("raboof")), 6, protocol.ECNNon) }).To(Panic()) }) It("signals when sending is possible again", func() { Expect(q.WouldBlock()).To(BeFalse()) - q.Send(getPacket([]byte("foobar1")), 6) + q.Send(getPacket([]byte("foobar1")), 6, protocol.ECNNon) Consistently(q.Available()).ShouldNot(Receive()) // now start sending out packets. This should free up queue space. - c.EXPECT().Write(gomock.Any(), gomock.Any()).MinTimes(1).MaxTimes(2) + c.EXPECT().Write(gomock.Any(), gomock.Any(), protocol.ECNNon).MinTimes(1).MaxTimes(2) done := make(chan struct{}) go func() { defer GinkgoRecover() @@ -67,7 +69,7 @@ var _ = Describe("Send Queue", func() { Eventually(q.Available()).Should(Receive()) Expect(q.WouldBlock()).To(BeFalse()) - Expect(func() { q.Send(getPacket([]byte("foobar2")), 7) }).ToNot(Panic()) + Expect(func() { q.Send(getPacket([]byte("foobar2")), 7, protocol.ECNNon) }).ToNot(Panic()) q.Close() Eventually(done).Should(BeClosed()) @@ -77,7 +79,7 @@ var _ = Describe("Send Queue", func() { write := make(chan struct{}, 1) written := make(chan struct{}, 100) // now start sending out packets. This should free up queue space. - c.EXPECT().Write(gomock.Any(), gomock.Any()).DoAndReturn(func([]byte, uint16) error { + c.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func([]byte, uint16, protocol.ECN) error { written <- struct{}{} <-write return nil @@ -92,19 +94,19 @@ var _ = Describe("Send Queue", func() { close(done) }() - q.Send(getPacket([]byte("foobar")), 6) + q.Send(getPacket([]byte("foobar")), 6, protocol.ECNNon) <-written // now fill up the send queue for i := 0; i < sendQueueCapacity; i++ { Expect(q.WouldBlock()).To(BeFalse()) - q.Send(getPacket([]byte("foobar")), 6) + q.Send(getPacket([]byte("foobar")), 6, protocol.ECNNon) } // One more packet is queued when it's picked up by Run and written to the connection. // In this test, it's blocked on write channel in the mocked Write call. <-written Eventually(q.WouldBlock()).Should(BeFalse()) - q.Send(getPacket([]byte("foobar")), 6) + q.Send(getPacket([]byte("foobar")), 6, protocol.ECNNon) Expect(q.WouldBlock()).To(BeTrue()) Consistently(q.Available()).ShouldNot(Receive()) @@ -130,15 +132,15 @@ var _ = Describe("Send Queue", func() { // the run loop exits if there is a write error testErr := errors.New("test error") - c.EXPECT().Write(gomock.Any(), gomock.Any()).Return(testErr) - q.Send(getPacket([]byte("foobar")), 6) + c.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any()).Return(testErr) + q.Send(getPacket([]byte("foobar")), 6, protocol.ECNNon) Eventually(done).Should(BeClosed()) sent := make(chan struct{}) go func() { defer GinkgoRecover() - q.Send(getPacket([]byte("raboof")), 6) - q.Send(getPacket([]byte("quux")), 4) + q.Send(getPacket([]byte("raboof")), 6, protocol.ECNNon) + q.Send(getPacket([]byte("quux")), 4, protocol.ECNNon) close(sent) }() @@ -147,7 +149,7 @@ var _ = Describe("Send Queue", func() { It("blocks Close() until the packet has been sent out", func() { written := make(chan []byte) - c.EXPECT().Write(gomock.Any(), gomock.Any()).Do(func(p []byte, _ uint16) { written <- p }) + c.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(p []byte, _ uint16, _ protocol.ECN) { written <- p }) done := make(chan struct{}) go func() { defer GinkgoRecover() @@ -155,7 +157,7 @@ var _ = Describe("Send Queue", func() { close(done) }() - q.Send(getPacket([]byte("foobar")), 6) + q.Send(getPacket([]byte("foobar")), 6, protocol.ECNNon) closed := make(chan struct{}) go func() { diff --git a/server.go b/server.go index 92b5e91a6c8..681e8956c63 100644 --- a/server.go +++ b/server.go @@ -745,7 +745,7 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info packe if s.tracer != nil { s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(buf.Data)), nil) } - _, err = s.conn.WritePacket(buf.Data, remoteAddr, info.OOB(), 0) + _, err = s.conn.WritePacket(buf.Data, remoteAddr, info.OOB(), 0, protocol.ECNNon) return err } @@ -844,7 +844,7 @@ func (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer han if s.tracer != nil { s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(b.Data)), []logging.Frame{ccf}) } - _, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB(), 0) + _, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB(), 0, protocol.ECNNon) return err } @@ -882,7 +882,7 @@ func (s *baseServer) maybeSendVersionNegotiationPacket(p receivedPacket) { if s.tracer != nil { s.tracer.SentVersionNegotiationPacket(p.remoteAddr, src, dest, s.config.Versions) } - if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0); err != nil { + if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNNon); err != nil { s.logger.Debugf("Error sending Version Negotiation: %s", err) } } diff --git a/sys_conn.go b/sys_conn.go index a72aead5813..4d7a65776f1 100644 --- a/sys_conn.go +++ b/sys_conn.go @@ -104,7 +104,7 @@ func (c *basicConn) ReadPacket() (receivedPacket, error) { }, nil } -func (c *basicConn) WritePacket(b []byte, addr net.Addr, _ []byte, gsoSize uint16) (n int, err error) { +func (c *basicConn) WritePacket(b []byte, addr net.Addr, _ []byte, gsoSize uint16, _ protocol.ECN) (n int, err error) { if gsoSize != 0 { panic("cannot use GSO with a basicConn") } diff --git a/sys_conn_df_windows.go b/sys_conn_df_windows.go index e56b7460781..e27635ec9c8 100644 --- a/sys_conn_df_windows.go +++ b/sys_conn_df_windows.go @@ -8,7 +8,6 @@ import ( "golang.org/x/sys/windows" - "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" ) @@ -53,6 +52,3 @@ func isRecvMsgSizeErr(err error) bool { // https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2 return errors.Is(err, windows.WSAEMSGSIZE) } - -func appendIPv4ECNMsg([]byte, protocol.ECN) []byte { return nil } -func appendIPv6ECNMsg([]byte, protocol.ECN) []byte { return nil } diff --git a/sys_conn_no_oob.go b/sys_conn_no_oob.go index c1fb6fb192d..2a1f807efd4 100644 --- a/sys_conn_no_oob.go +++ b/sys_conn_no_oob.go @@ -5,8 +5,6 @@ package quic import ( "net" "net/netip" - - "github.com/quic-go/quic-go/internal/protocol" ) func newConn(c net.PacketConn, supportsDF bool) (*basicConn, error) { @@ -16,9 +14,6 @@ func newConn(c net.PacketConn, supportsDF bool) (*basicConn, error) { func inspectReadBuffer(any) (int, error) { return 0, nil } func inspectWriteBuffer(any) (int, error) { return 0, nil } -func appendIPv4ECNMsg([]byte, protocol.ECN) []byte { return nil } -func appendIPv6ECNMsg([]byte, protocol.ECN) []byte { return nil } - type packetInfo struct { addr netip.Addr } diff --git a/sys_conn_oob.go b/sys_conn_oob.go index 6446d89384a..7b6052baf71 100644 --- a/sys_conn_oob.go +++ b/sys_conn_oob.go @@ -229,7 +229,7 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) { } // WritePacket writes a new packet. -func (c *oobConn) WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gsoSize uint16) (int, error) { +func (c *oobConn) WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gsoSize uint16, ecn protocol.ECN) (int, error) { oob := packetInfoOOB if gsoSize > 0 { if !c.capabilities().GSO { @@ -237,6 +237,13 @@ func (c *oobConn) WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gso } oob = appendUDPSegmentSizeMsg(oob, gsoSize) } + if remoteUDPAddr, ok := addr.(*net.UDPAddr); ok { + if remoteUDPAddr.IP.To4() != nil { + oob = appendIPv4ECNMsg(oob, ecn) + } else { + oob = appendIPv6ECNMsg(oob, ecn) + } + } n, _, err := c.OOBCapablePacketConn.WriteMsgUDP(b, oob, addr.(*net.UDPAddr)) return n, err } diff --git a/sys_conn_oob_test.go b/sys_conn_oob_test.go index 9d0f5e9d23c..40596421b2c 100644 --- a/sys_conn_oob_test.go +++ b/sys_conn_oob_test.go @@ -53,7 +53,7 @@ var _ = Describe("OOB Conn Test", func() { return udpConn, packetChan } - Context("ECN conn", func() { + Context("reading ECN-marked packets", func() { sendPacketWithECN := func(network string, addr *net.UDPAddr, setECN func(uintptr)) net.Addr { conn, err := net.DialUDP(network, nil, addr) ExpectWithOffset(1, err).ToNot(HaveOccurred()) @@ -289,6 +289,27 @@ var _ = Describe("OOB Conn Test", func() { }) }) + Context("sending ECN-marked packets", func() { + It("sets the ECN control message", func() { + addr, err := net.ResolveUDPAddr("udp", "localhost:0") + Expect(err).ToNot(HaveOccurred()) + udpConn, err := net.ListenUDP("udp", addr) + Expect(err).ToNot(HaveOccurred()) + c := &oobRecordingConn{UDPConn: udpConn} + oobConn, err := newConn(c, true) + Expect(err).ToNot(HaveOccurred()) + + oob := make([]byte, 0, 123) + oobConn.WritePacket([]byte("foobar"), addr, oob, 0, protocol.ECNCE) + Expect(c.oobs).To(HaveLen(1)) + oobMsg := c.oobs[0] + Expect(oobMsg).ToNot(BeEmpty()) + Expect(oobMsg).To(HaveCap(cap(oob))) // check that it appended to oob + expected := appendIPv4ECNMsg([]byte{}, protocol.ECNCE) + Expect(oobMsg).To(Equal(expected)) + }) + }) + if platformSupportsGSO { Context("GSO", func() { It("appends the GSO control message", func() { @@ -301,14 +322,15 @@ var _ = Describe("OOB Conn Test", func() { Expect(err).ToNot(HaveOccurred()) Expect(oobConn.capabilities().GSO).To(BeTrue()) - oob := make([]byte, 0, 42) - oobConn.WritePacket([]byte("foobar"), addr, oob, 3) + oob := make([]byte, 0, 123) + oobConn.WritePacket([]byte("foobar"), addr, oob, 3, protocol.ECNCE) Expect(c.oobs).To(HaveLen(1)) oobMsg := c.oobs[0] Expect(oobMsg).ToNot(BeEmpty()) Expect(oobMsg).To(HaveCap(cap(oob))) // check that it appended to oob expected := appendUDPSegmentSizeMsg([]byte{}, 3) - Expect(oobMsg).To(Equal(expected)) + // Check that the first control message is the OOB control message. + Expect(oobMsg[:len(expected)]).To(Equal(expected)) }) }) } diff --git a/transport.go b/transport.go index 41c9734710d..b841222ebea 100644 --- a/transport.go +++ b/transport.go @@ -228,7 +228,7 @@ func (t *Transport) WriteTo(b []byte, addr net.Addr) (int, error) { if err := t.init(false); err != nil { return 0, err } - return t.conn.WritePacket(b, addr, nil, 0) + return t.conn.WritePacket(b, addr, nil, 0, protocol.ECNNon) } func (t *Transport) enqueueClosePacket(p closePacket) { @@ -246,7 +246,7 @@ func (t *Transport) runSendQueue() { case <-t.listening: return case p := <-t.closeQueue: - t.conn.WritePacket(p.payload, p.addr, p.info.OOB(), 0) + t.conn.WritePacket(p.payload, p.addr, p.info.OOB(), 0, protocol.ECNNon) case p := <-t.statelessResetQueue: t.sendStatelessReset(p) } @@ -414,7 +414,7 @@ func (t *Transport) sendStatelessReset(p receivedPacket) { rand.Read(data) data[0] = (data[0] & 0x7f) | 0x40 data = append(data, token[:]...) - if _, err := t.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0); err != nil { + if _, err := t.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNNon); err != nil { t.logger.Debugf("Error sending Stateless Reset to %s: %s", p.remoteAddr, err) } } From b73a4de7eaa87773d9da570442752470b051ace6 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 31 Aug 2023 13:06:37 +0700 Subject: [PATCH 051/225] only add an ECN control message if ECN is supported --- connection.go | 4 +- internal/ackhandler/ackhandler.go | 3 +- .../ackhandler/received_packet_tracker.go | 2 +- internal/ackhandler/sent_packet_handler.go | 7 ++++ .../ackhandler/sent_packet_handler_test.go | 4 +- internal/protocol/protocol.go | 42 +++++++++++++++++-- internal/protocol/protocol_test.go | 17 ++++++-- packet_handler_map.go | 2 + server.go | 6 +-- sys_conn.go | 5 ++- sys_conn_oob.go | 21 ++++++---- transport.go | 6 +-- 12 files changed, 90 insertions(+), 29 deletions(-) diff --git a/connection.go b/connection.go index f234ea3f38e..1920bb2ade2 100644 --- a/connection.go +++ b/connection.go @@ -278,6 +278,7 @@ var newConnection = func( getMaxPacketSize(s.conn.RemoteAddr()), s.rttStats, clientAddressValidated, + s.conn.capabilities().ECN, s.perspective, s.tracer, s.logger, @@ -385,7 +386,8 @@ 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, diff --git a/internal/ackhandler/ackhandler.go b/internal/ackhandler/ackhandler.go index 2c7cc4fcf0b..036ed5ead90 100644 --- a/internal/ackhandler/ackhandler.go +++ b/internal/ackhandler/ackhandler.go @@ -14,10 +14,11 @@ func NewAckHandler( initialMaxDatagramSize protocol.ByteCount, rttStats *utils.RTTStats, clientAddressValidated bool, + enableECN bool, pers protocol.Perspective, 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) } diff --git a/internal/ackhandler/received_packet_tracker.go b/internal/ackhandler/received_packet_tracker.go index 0ed929fa5b5..7fd071e6833 100644 --- a/internal/ackhandler/received_packet_tracker.go +++ b/internal/ackhandler/received_packet_tracker.go @@ -62,8 +62,8 @@ func (h *receivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn pro 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: diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index 3b972b667be..da5d07184ae 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -92,6 +92,8 @@ type sentPacketHandler struct { // The alarm timeout alarm time.Time + enableECN bool + perspective protocol.Perspective tracer logging.ConnectionTracer @@ -110,6 +112,7 @@ func newSentPacketHandler( initialMaxDatagramSize protocol.ByteCount, rttStats *utils.RTTStats, clientAddressValidated bool, + enableECN bool, pers protocol.Perspective, tracer logging.ConnectionTracer, logger utils.Logger, @@ -130,6 +133,7 @@ func newSentPacketHandler( appDataPackets: newPacketNumberSpace(0, true), rttStats: rttStats, congestion: congestion, + enableECN: enableECN, perspective: pers, tracer: tracer, logger: logger, @@ -714,6 +718,9 @@ func (h *sentPacketHandler) GetLossDetectionTimeout() time.Time { } func (h *sentPacketHandler) ECNMode() protocol.ECN { + if !h.enableECN { + return protocol.ECNUnsupported + } // TODO: implement ECN logic return protocol.ECNNon } diff --git a/internal/ackhandler/sent_packet_handler_test.go b/internal/ackhandler/sent_packet_handler_test.go index 614b7c85756..a1e1f0d9a8c 100644 --- a/internal/ackhandler/sent_packet_handler_test.go +++ b/internal/ackhandler/sent_packet_handler_test.go @@ -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}, @@ -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() { diff --git a/internal/protocol/protocol.go b/internal/protocol/protocol.go index b8104882bcc..d056cb9deae 100644 --- a/internal/protocol/protocol.go +++ b/internal/protocol/protocol.go @@ -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: diff --git a/internal/protocol/protocol_test.go b/internal/protocol/protocol_test.go index e672d31e147..22359e6af96 100644 --- a/internal/protocol/protocol_test.go +++ b/internal/protocol/protocol_test.go @@ -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)")) diff --git a/packet_handler_map.go b/packet_handler_map.go index d7d92377c5e..ba30fb23b9e 100644 --- a/packet_handler_map.go +++ b/packet_handler_map.go @@ -21,6 +21,8 @@ type connCapabilities struct { DF bool // GSO (Generic Segmentation Offload) supported GSO bool + // ECN (Explicit Congestion Notifications) supported + ECN bool } // rawConn is a connection that allow reading of a receivedPackeh. diff --git a/server.go b/server.go index 681e8956c63..d41c6465ac4 100644 --- a/server.go +++ b/server.go @@ -745,7 +745,7 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info packe if s.tracer != nil { s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(buf.Data)), nil) } - _, err = s.conn.WritePacket(buf.Data, remoteAddr, info.OOB(), 0, protocol.ECNNon) + _, err = s.conn.WritePacket(buf.Data, remoteAddr, info.OOB(), 0, protocol.ECNUnsupported) return err } @@ -844,7 +844,7 @@ func (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer han if s.tracer != nil { s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(b.Data)), []logging.Frame{ccf}) } - _, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB(), 0, protocol.ECNNon) + _, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB(), 0, protocol.ECNUnsupported) return err } @@ -882,7 +882,7 @@ func (s *baseServer) maybeSendVersionNegotiationPacket(p receivedPacket) { if s.tracer != nil { s.tracer.SentVersionNegotiationPacket(p.remoteAddr, src, dest, s.config.Versions) } - if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNNon); err != nil { + if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported); err != nil { s.logger.Debugf("Error sending Version Negotiation: %s", err) } } diff --git a/sys_conn.go b/sys_conn.go index 4d7a65776f1..71cc46070ce 100644 --- a/sys_conn.go +++ b/sys_conn.go @@ -104,10 +104,13 @@ func (c *basicConn) ReadPacket() (receivedPacket, error) { }, nil } -func (c *basicConn) WritePacket(b []byte, addr net.Addr, _ []byte, gsoSize uint16, _ protocol.ECN) (n int, err error) { +func (c *basicConn) WritePacket(b []byte, addr net.Addr, _ []byte, gsoSize uint16, ecn protocol.ECN) (n int, err error) { if gsoSize != 0 { panic("cannot use GSO with a basicConn") } + if ecn != protocol.ECNUnsupported { + panic("cannot use ECN with a basicConn") + } return c.PacketConn.WriteTo(b, addr) } diff --git a/sys_conn_oob.go b/sys_conn_oob.go index 7b6052baf71..b9ddf3c18cf 100644 --- a/sys_conn_oob.go +++ b/sys_conn_oob.go @@ -141,6 +141,7 @@ func newConn(c OOBCapablePacketConn, supportsDF bool) (*oobConn, error) { cap: connCapabilities{ DF: supportsDF, GSO: isGSOSupported(rawConn), + ECN: true, }, } for i := 0; i < batchSize; i++ { @@ -189,7 +190,7 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) { if hdr.Level == unix.IPPROTO_IP { switch hdr.Type { case msgTypeIPTOS: - p.ecn = protocol.ECN(body[0] & ecnMask) + p.ecn = protocol.ParseECNHeaderBits(body[0] & ecnMask) case ipv4PKTINFO: ip, ifIndex, ok := parseIPv4PktInfo(body) if ok { @@ -206,7 +207,7 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) { if hdr.Level == unix.IPPROTO_IPV6 { switch hdr.Type { case unix.IPV6_TCLASS: - p.ecn = protocol.ECN(body[0] & ecnMask) + p.ecn = protocol.ParseECNHeaderBits(body[0] & ecnMask) case unix.IPV6_PKTINFO: // struct in6_pktinfo { // struct in6_addr ipi6_addr; /* src/dst IPv6 address */ @@ -237,11 +238,13 @@ func (c *oobConn) WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gso } oob = appendUDPSegmentSizeMsg(oob, gsoSize) } - if remoteUDPAddr, ok := addr.(*net.UDPAddr); ok { - if remoteUDPAddr.IP.To4() != nil { - oob = appendIPv4ECNMsg(oob, ecn) - } else { - oob = appendIPv6ECNMsg(oob, ecn) + if ecn != protocol.ECNUnsupported { + if remoteUDPAddr, ok := addr.(*net.UDPAddr); ok { + if remoteUDPAddr.IP.To4() != nil { + oob = appendIPv4ECNMsg(oob, ecn) + } else { + oob = appendIPv6ECNMsg(oob, ecn) + } } } n, _, err := c.OOBCapablePacketConn.WriteMsgUDP(b, oob, addr.(*net.UDPAddr)) @@ -298,7 +301,7 @@ func appendIPv4ECNMsg(b []byte, val protocol.ECN) []byte { // UnixRights uses the private `data` method, but I *think* this achieves the same goal. offset := startLen + unix.CmsgSpace(0) - b[offset] = uint8(val) + b[offset] = val.ToHeaderBits() return b } @@ -313,6 +316,6 @@ func appendIPv6ECNMsg(b []byte, val protocol.ECN) []byte { // UnixRights uses the private `data` method, but I *think* this achieves the same goal. offset := startLen + unix.CmsgSpace(0) - b[offset] = uint8(val) + b[offset] = val.ToHeaderBits() return b } diff --git a/transport.go b/transport.go index b841222ebea..c021be77d7a 100644 --- a/transport.go +++ b/transport.go @@ -228,7 +228,7 @@ func (t *Transport) WriteTo(b []byte, addr net.Addr) (int, error) { if err := t.init(false); err != nil { return 0, err } - return t.conn.WritePacket(b, addr, nil, 0, protocol.ECNNon) + return t.conn.WritePacket(b, addr, nil, 0, protocol.ECNUnsupported) } func (t *Transport) enqueueClosePacket(p closePacket) { @@ -246,7 +246,7 @@ func (t *Transport) runSendQueue() { case <-t.listening: return case p := <-t.closeQueue: - t.conn.WritePacket(p.payload, p.addr, p.info.OOB(), 0, protocol.ECNNon) + t.conn.WritePacket(p.payload, p.addr, p.info.OOB(), 0, protocol.ECNUnsupported) case p := <-t.statelessResetQueue: t.sendStatelessReset(p) } @@ -414,7 +414,7 @@ func (t *Transport) sendStatelessReset(p receivedPacket) { rand.Read(data) data[0] = (data[0] & 0x7f) | 0x40 data = append(data, token[:]...) - if _, err := t.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNNon); err != nil { + if _, err := t.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported); err != nil { t.logger.Debugf("Error sending Stateless Reset to %s: %s", p.remoteAddr, err) } } From 8df7624c079106f0fb0e238ccf4a91a007d47504 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 1 Sep 2023 09:18:14 +0700 Subject: [PATCH 052/225] add a QUIC_GO_DISABLE_ECN env to disable ECN support --- .github/workflows/integration.yml | 5 +++++ sys_conn_oob.go | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 90ed611b0c7..c661e09cc7e 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -41,6 +41,11 @@ jobs: env: QUIC_GO_DISABLE_GSO: true run: go run github.com/onsi/ginkgo/v2/ginkgo -r -v -randomize-all -randomize-suites -trace integrationtests/self -- -version=1 ${{ env.QLOGFLAG }} + - name: Run self tests, with ECN disabled + if: ${{ matrix.os == 'ubuntu' && (success() || failure()) }} # run this step even if the previous one failed + env: + QUIC_GO_DISABLE_ECN: true + run: go run github.com/onsi/ginkgo/v2/ginkgo -r -v -randomize-all -randomize-suites -trace integrationtests/self -- -version=1 ${{ env.QLOGFLAG }} - name: Run tests (32 bit) if: ${{ matrix.os != 'macos' && (success() || failure()) }} # run this step even if the previous one failed env: diff --git a/sys_conn_oob.go b/sys_conn_oob.go index b9ddf3c18cf..71a037d5aae 100644 --- a/sys_conn_oob.go +++ b/sys_conn_oob.go @@ -8,6 +8,8 @@ import ( "log" "net" "net/netip" + "os" + "strconv" "sync" "syscall" "time" @@ -57,6 +59,11 @@ func inspectWriteBuffer(c syscall.RawConn) (int, error) { return size, serr } +func isECNDisabled() bool { + disabled, err := strconv.ParseBool(os.Getenv("QUIC_GO_DISABLE_ECN")) + return err == nil && disabled +} + type oobConn struct { OOBCapablePacketConn batchConn batchConn @@ -141,7 +148,7 @@ func newConn(c OOBCapablePacketConn, supportsDF bool) (*oobConn, error) { cap: connCapabilities{ DF: supportsDF, GSO: isGSOSupported(rawConn), - ECN: true, + ECN: !isECNDisabled(), }, } for i := 0; i < batchSize; i++ { @@ -239,6 +246,9 @@ func (c *oobConn) WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gso oob = appendUDPSegmentSizeMsg(oob, gsoSize) } if ecn != protocol.ECNUnsupported { + if !c.capabilities().ECN { + panic("tried to send a ECN-marked packet although ECN is disabled") + } if remoteUDPAddr, ok := addr.(*net.UDPAddr); ok { if remoteUDPAddr.IP.To4() != nil { oob = appendIPv4ECNMsg(oob, ecn) From bed8ebbd4ca413d2a16d3a89439894813ee02a4c Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 1 Sep 2023 09:50:52 +0700 Subject: [PATCH 053/225] distinguish coalesced and 1-RTT packets when determining ECN mode --- connection.go | 23 ++++---- connection_test.go | 56 +++++++++---------- internal/ackhandler/interfaces.go | 3 +- internal/ackhandler/sent_packet_handler.go | 5 +- .../mocks/ackhandler/sent_packet_handler.go | 8 +-- packet_packer.go | 5 ++ packet_packer_test.go | 5 ++ 7 files changed, 59 insertions(+), 46 deletions(-) diff --git a/connection.go b/connection.go index 1920bb2ade2..d4e44be698d 100644 --- a/connection.go +++ b/connection.go @@ -1832,7 +1832,7 @@ func (s *connection) sendPackets(now time.Time) error { if err != nil { return err } - ecn := s.sentPacketHandler.ECNMode() + 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) @@ -1855,7 +1855,7 @@ func (s *connection) sendPackets(now time.Time) error { return err } s.sentFirstPacket = true - if err := s.sendPackedCoalescedPacket(packet, s.sentPacketHandler.ECNMode(), now); err != nil { + if err := s.sendPackedCoalescedPacket(packet, s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now); err != nil { return err } sendMode := s.sentPacketHandler.SendMode(now) @@ -1876,8 +1876,8 @@ func (s *connection) sendPackets(now time.Time) error { func (s *connection) sendPacketsWithoutGSO(now time.Time) error { for { buf := getPacketBuffer() - ecn := s.sentPacketHandler.ECNMode() - if _, err := s.appendOnePacket(buf, s.mtuDiscoverer.CurrentSize(), ecn, 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 @@ -1912,8 +1912,8 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error { for { var dontSendMore bool - ecn := s.sentPacketHandler.ECNMode() - size, err := s.appendOnePacket(buf, maxSize, ecn, now) + ecn := s.sentPacketHandler.ECNMode(true) + size, err := s.appendOneShortHeaderPacket(buf, maxSize, ecn, now) if err != nil { if err != errNothingToPack { return err @@ -1971,8 +1971,8 @@ func (s *connection) resetPacingDeadline() { } func (s *connection) maybeSendAckOnlyPacket(now time.Time) error { - ecn := s.sentPacketHandler.ECNMode() if !s.handshakeConfirmed { + ecn := s.sentPacketHandler.ECNMode(false) packet, err := s.packer.PackCoalescedPacket(true, s.mtuDiscoverer.CurrentSize(), s.version) if err != nil { return err @@ -1983,6 +1983,7 @@ func (s *connection) maybeSendAckOnlyPacket(now time.Time) error { 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 { @@ -2024,12 +2025,12 @@ 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, s.sentPacketHandler.ECNMode(), now) + return s.sendPackedCoalescedPacket(packet, s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now) } -// appendOnePacket 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) appendOnePacket(buf *packetBuffer, maxSize protocol.ByteCount, ecn protocol.ECN, 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 { @@ -2106,7 +2107,7 @@ func (s *connection) sendConnectionClose(e error) ([]byte, error) { if err != nil { return nil, err } - ecn := s.sentPacketHandler.ECNMode() + ecn := s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()) s.logCoalescedPacket(packet, ecn) return packet.buffer.Data, s.conn.Write(packet.buffer.Data, 0, ecn) } diff --git a/connection_test.go b/connection_test.go index 828f4ced1b2..c4e067af80d 100644 --- a/connection_test.go +++ b/connection_test.go @@ -613,7 +613,7 @@ var _ = Describe("Connection", func() { conn.sendQueue = newSendQueue(sconn) sph := mockackhandler.NewMockSentPacketHandler(mockCtrl) sph.EXPECT().GetLossDetectionTimeout().Return(time.Now().Add(time.Hour)).AnyTimes() - sph.EXPECT().ECNMode().Return(protocol.ECT1).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(), gomock.Any()) @@ -1206,7 +1206,7 @@ var _ = Describe("Connection", func() { AfterEach(func() { streamManager.EXPECT().CloseWithError(gomock.Any()) - sph.EXPECT().ECNMode().Return(protocol.ECNCE).MaxTimes(1) + 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() @@ -1234,7 +1234,7 @@ var _ = Describe("Connection", func() { sph.EXPECT().TimeUntilSend().AnyTimes() sph.EXPECT().GetLossDetectionTimeout().AnyTimes() sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes() - sph.EXPECT().ECNMode().Return(protocol.ECNNon).AnyTimes() + 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{ @@ -1262,7 +1262,7 @@ var _ = Describe("Connection", func() { conn.handshakeConfirmed = true sph.EXPECT().GetLossDetectionTimeout().AnyTimes() sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes() - sph.EXPECT().ECNMode().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) @@ -1274,7 +1274,7 @@ var _ = Describe("Connection", func() { sph.EXPECT().TimeUntilSend().AnyTimes() sph.EXPECT().GetLossDetectionTimeout().AnyTimes() sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAck) - sph.EXPECT().ECNMode().Return(protocol.ECT1).AnyTimes() + 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) }) runConn() @@ -1287,7 +1287,7 @@ var _ = Describe("Connection", func() { sph.EXPECT().TimeUntilSend().AnyTimes() sph.EXPECT().GetLossDetectionTimeout().AnyTimes() sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes() - sph.EXPECT().ECNMode().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(), gomock.Any()) fc := mocks.NewMockConnectionFlowController(mockCtrl) fc.EXPECT().IsNewlyBlocked().Return(true, protocol.ByteCount(1337)) @@ -1341,7 +1341,7 @@ var _ = Describe("Connection", func() { sph.EXPECT().SendMode(gomock.Any()).Return(sendMode) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone) sph.EXPECT().QueueProbePacket(encLevel) - sph.EXPECT().ECNMode() + 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(), protocol.PacketNumber(123), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()) @@ -1363,7 +1363,7 @@ var _ = Describe("Connection", func() { sph.EXPECT().TimeUntilSend().AnyTimes() sph.EXPECT().SendMode(gomock.Any()).Return(sendMode) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone) - sph.EXPECT().ECNMode() + sph.EXPECT().ECNMode(gomock.Any()) sph.EXPECT().QueueProbePacket(encLevel).Return(false) p := getCoalescedPacket(123, enc != protocol.Encryption1RTT) packer.EXPECT().MaybePackProbePacket(encLevel, gomock.Any(), conn.version).Return(p, nil) @@ -1407,7 +1407,7 @@ var _ = Describe("Connection", func() { AfterEach(func() { // make the go routine return - sph.EXPECT().ECNMode().MaxTimes(1) + 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() @@ -1422,7 +1422,7 @@ 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(), gomock.Any()).Times(2) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(2) - sph.EXPECT().ECNMode().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")) @@ -1447,7 +1447,7 @@ 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(), gomock.Any()).Times(2) - sph.EXPECT().ECNMode().Times(3) + sph.EXPECT().ECNMode(true).Times(3) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3) payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize()) rand.Read(payload1) @@ -1474,7 +1474,7 @@ var _ = Describe("Connection", func() { enableGSO() 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().Times(2) + sph.EXPECT().ECNMode(true).Times(2) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone) payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize()) rand.Read(payload1) @@ -1499,7 +1499,7 @@ 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(), gomock.Any()) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(2) - sph.EXPECT().ECNMode().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() @@ -1518,7 +1518,7 @@ var _ = Describe("Connection", func() { 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() + sph.EXPECT().ECNMode(gomock.Any()) packer.EXPECT().PackAckOnlyPacket(gomock.Any(), conn.version).Return(shortHeaderPacket{PacketNumber: 123}, getPacketBuffer(), nil) sender.EXPECT().WouldBlock().AnyTimes() @@ -1539,7 +1539,7 @@ var _ = Describe("Connection", func() { 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().Times(2) + 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(), gomock.Any()) @@ -1557,13 +1557,13 @@ var _ = Describe("Connection", func() { pacingDelay := scaleDuration(100 * time.Millisecond) gomock.InOrder( sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny), - sph.EXPECT().ECNMode(), + 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(), 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(), + 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(), gomock.Any()), sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited), @@ -1587,7 +1587,7 @@ 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(), gomock.Any()).Times(3) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3) - sph.EXPECT().ECNMode().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++ { @@ -1628,7 +1628,7 @@ var _ = Describe("Connection", func() { sender.EXPECT().WouldBlock().AnyTimes() 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().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(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { close(written) }) @@ -1653,7 +1653,7 @@ var _ = Describe("Connection", func() { conn.handlePacket(receivedPacket{buffer: getPacketBuffer()}) }) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes() - sph.EXPECT().ECNMode().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(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { close(written) }) @@ -1667,7 +1667,7 @@ 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(), gomock.Any()) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny) - sph.EXPECT().ECNMode() + sph.EXPECT().ECNMode(gomock.Any()) expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 1000}, []byte("packet1000")) written := make(chan struct{}, 1) sender.EXPECT().WouldBlock() @@ -1688,7 +1688,7 @@ var _ = Describe("Connection", func() { // 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(), gomock.Any()) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes() - sph.EXPECT().ECNMode().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) @@ -1703,7 +1703,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().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() @@ -1723,7 +1723,7 @@ var _ = Describe("Connection", func() { conn.config.DisablePathMTUDiscovery = false 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() + sph.EXPECT().ECNMode(true) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone) written := make(chan struct{}, 1) sender.EXPECT().WouldBlock().AnyTimes() @@ -1774,7 +1774,7 @@ var _ = Describe("Connection", func() { sph.EXPECT().GetLossDetectionTimeout().AnyTimes() sph.EXPECT().TimeUntilSend().AnyTimes() sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes() - sph.EXPECT().ECNMode().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(), gomock.Any()) conn.sentPacketHandler = sph @@ -1803,7 +1803,7 @@ var _ = Describe("Connection", func() { sph := mockackhandler.NewMockSentPacketHandler(mockCtrl) sph.EXPECT().GetLossDetectionTimeout().AnyTimes() sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes() - sph.EXPECT().ECNMode().AnyTimes() + 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) @@ -1855,7 +1855,7 @@ var _ = Describe("Connection", func() { sph.EXPECT().GetLossDetectionTimeout().AnyTimes() sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes() - sph.EXPECT().ECNMode().Return(protocol.ECT1).AnyTimes() + sph.EXPECT().ECNMode(false).Return(protocol.ECT1).AnyTimes() sph.EXPECT().TimeUntilSend().Return(time.Now()).AnyTimes() gomock.InOrder( sph.EXPECT().SentPacket(gomock.Any(), protocol.PacketNumber(13), gomock.Any(), gomock.Any(), gomock.Any(), protocol.EncryptionInitial, protocol.ECT1, protocol.ByteCount(123), gomock.Any()), @@ -1968,7 +1968,7 @@ 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().AnyTimes() + sph.EXPECT().ECNMode(gomock.Any()).AnyTimes() sph.EXPECT().GetLossDetectionTimeout().AnyTimes() sph.EXPECT().TimeUntilSend().AnyTimes() sph.EXPECT().SetHandshakeConfirmed() diff --git a/internal/ackhandler/interfaces.go b/internal/ackhandler/interfaces.go index ba224228a51..ba8cbbdae02 100644 --- a/internal/ackhandler/interfaces.go +++ b/internal/ackhandler/interfaces.go @@ -29,8 +29,7 @@ type SentPacketHandler interface { // only to be called once the handshake is complete QueueProbePacket(protocol.EncryptionLevel) bool /* was a packet queued */ - ECNMode() protocol.ECN - + 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 diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index da5d07184ae..53aba0dd132 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -717,10 +717,13 @@ func (h *sentPacketHandler) GetLossDetectionTimeout() time.Time { return h.alarm } -func (h *sentPacketHandler) ECNMode() protocol.ECN { +func (h *sentPacketHandler) ECNMode(isShortHeaderPacket bool) protocol.ECN { if !h.enableECN { return protocol.ECNUnsupported } + if !isShortHeaderPacket { + return protocol.ECNNon + } // TODO: implement ECN logic return protocol.ECNNon } diff --git a/internal/mocks/ackhandler/sent_packet_handler.go b/internal/mocks/ackhandler/sent_packet_handler.go index 3479d9e617c..137ac2efad8 100644 --- a/internal/mocks/ackhandler/sent_packet_handler.go +++ b/internal/mocks/ackhandler/sent_packet_handler.go @@ -50,17 +50,17 @@ func (mr *MockSentPacketHandlerMockRecorder) DropPackets(arg0 interface{}) *gomo } // ECNMode mocks base method. -func (m *MockSentPacketHandler) ECNMode() protocol.ECN { +func (m *MockSentPacketHandler) ECNMode(arg0 bool) protocol.ECN { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ECNMode") + 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() *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) ECNMode(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNMode", reflect.TypeOf((*MockSentPacketHandler)(nil).ECNMode)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNMode", reflect.TypeOf((*MockSentPacketHandler)(nil).ECNMode), arg0) } // GetLossDetectionTimeout mocks base method. diff --git a/packet_packer.go b/packet_packer.go index 0483f35bfb4..64081c6842b 100644 --- a/packet_packer.go +++ b/packet_packer.go @@ -71,6 +71,11 @@ type coalescedPacket struct { shortHdrPacket *shortHeaderPacket } +// IsOnlyShortHeaderPacket says if this packet only contains a short header packet (and no long header packets). +func (p *coalescedPacket) IsOnlyShortHeaderPacket() bool { + return len(p.longHdrPackets) == 0 && p.shortHdrPacket != nil +} + func (p *longHeaderPacket) EncryptionLevel() protocol.EncryptionLevel { //nolint:exhaustive // Will never be called for Retry packets (and they don't have encrypted data). switch p.header.Type { diff --git a/packet_packer_test.go b/packet_packer_test.go index 6dba31f9db4..e68906f39f1 100644 --- a/packet_packer_test.go +++ b/packet_packer_test.go @@ -655,6 +655,7 @@ var _ = Describe("Packet packer", func() { Expect(err).ToNot(HaveOccurred()) Expect(packet).ToNot(BeNil()) Expect(packet.longHdrPackets).To(HaveLen(1)) + Expect(packet.IsOnlyShortHeaderPacket()).To(BeFalse()) // cut off the tag that the mock sealer added // packet.buffer.Data = packet.buffer.Data[:packet.buffer.Len()-protocol.ByteCount(sealer.Overhead())] hdr, _, _, err := wire.ParsePacket(packet.buffer.Data) @@ -874,6 +875,7 @@ var _ = Describe("Packet packer", func() { p, err := packer.PackCoalescedPacket(false, maxPacketSize, protocol.Version1) Expect(err).ToNot(HaveOccurred()) Expect(p).ToNot(BeNil()) + Expect(p.IsOnlyShortHeaderPacket()).To(BeFalse()) parsePacket(p.buffer.Data) }) @@ -1047,6 +1049,7 @@ var _ = Describe("Packet packer", func() { packer.retransmissionQueue.addAppData(&wire.PingFrame{}) p, err := packer.PackCoalescedPacket(false, maxPacketSize, protocol.Version1) Expect(err).ToNot(HaveOccurred()) + Expect(p.IsOnlyShortHeaderPacket()).To(BeFalse()) Expect(p.buffer.Len()).To(BeEquivalentTo(maxPacketSize)) Expect(p.longHdrPackets).To(HaveLen(1)) Expect(p.longHdrPackets[0].EncryptionLevel()).To(Equal(protocol.EncryptionInitial)) @@ -1422,6 +1425,7 @@ var _ = Describe("Packet packer", func() { p, err := packer.MaybePackProbePacket(protocol.Encryption1RTT, maxPacketSize, protocol.Version1) Expect(err).ToNot(HaveOccurred()) Expect(p).ToNot(BeNil()) + Expect(p.IsOnlyShortHeaderPacket()).To(BeTrue()) Expect(p.longHdrPackets).To(BeEmpty()) Expect(p.shortHdrPacket).ToNot(BeNil()) packet := p.shortHdrPacket @@ -1448,6 +1452,7 @@ var _ = Describe("Packet packer", func() { p, err := packer.MaybePackProbePacket(protocol.Encryption1RTT, maxPacketSize, protocol.Version1) Expect(err).ToNot(HaveOccurred()) Expect(p).ToNot(BeNil()) + Expect(p.IsOnlyShortHeaderPacket()).To(BeTrue()) Expect(p.longHdrPackets).To(BeEmpty()) Expect(p.shortHdrPacket).ToNot(BeNil()) packet := p.shortHdrPacket From ad63e2a40af01c377cb02c5142111d99141a30bf Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 1 Sep 2023 11:47:05 +0700 Subject: [PATCH 054/225] trace and qlog the ECN marking on sent and received packets --- connection.go | 10 +-- connection_test.go | 70 +++++++++++---------- integrationtests/self/key_update_test.go | 6 +- integrationtests/self/self_suite_test.go | 8 ++- internal/mocks/logging/connection_tracer.go | 32 +++++----- logging/interface.go | 23 +++++-- logging/mock_connection_tracer_test.go | 32 +++++----- logging/multiplex.go | 16 ++--- logging/multiplex_test.go | 24 +++---- logging/null_tracer.go | 26 ++++---- qlog/event.go | 8 +++ qlog/qlog.go | 51 ++++++++++----- qlog/qlog_test.go | 8 +++ qlog/types.go | 18 ++++++ qlog/types_test.go | 8 +++ 15 files changed, 216 insertions(+), 124 deletions(-) diff --git a/connection.go b/connection.go index d4e44be698d..fdd056f123e 100644 --- a/connection.go +++ b/connection.go @@ -907,6 +907,7 @@ func (s *connection) handleShortHeaderPacket(p receivedPacket, destConnID protoc KeyPhase: keyPhase, }, p.Size(), + p.ecn, frames, ) } @@ -1192,7 +1193,7 @@ func (s *connection) handleUnpackedLongHeaderPacket( var log func([]logging.Frame) if s.tracer != 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) @@ -2112,7 +2113,7 @@ func (s *connection) sendConnectionClose(e error) ([]byte, error) { 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) @@ -2140,7 +2141,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) } } @@ -2194,6 +2195,7 @@ func (s *connection) logShortHeaderPacket( KeyPhase: kp, }, size, + ecn, ack, fs, ) @@ -2226,7 +2228,7 @@ func (s *connection) logCoalescedPacket(packet *coalescedPacket, ecn protocol.EC } } 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, ecn, p.Length, true) diff --git a/connection_test.go b/connection_test.go index c4e067af80d..4fe53910dff 100644 --- a/connection_test.go +++ b/connection_test.go @@ -590,7 +590,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(), ) @@ -617,7 +617,7 @@ var _ = Describe("Connection", func() { 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(), gomock.Any()) - tracer.EXPECT().SentShortHeaderPacket(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 +778,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 +796,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()) }) @@ -850,8 +855,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++ { @@ -886,8 +890,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++ { @@ -1021,7 +1024,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 +1057,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 +1097,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 +1130,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 +1156,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 +1182,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...) @@ -1253,7 +1257,7 @@ var _ = Describe("Connection", func() { 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()) }) @@ -1297,7 +1301,7 @@ var _ = Describe("Connection", func() { runConn() sent := make(chan struct{}) sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(sent) }) - tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), nil, []logging.Frame{}) + 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) @@ -1350,9 +1354,9 @@ var _ = Describe("Connection", func() { sent := make(chan struct{}) 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()) @@ -1363,7 +1367,7 @@ var _ = Describe("Connection", func() { sph.EXPECT().TimeUntilSend().AnyTimes() sph.EXPECT().SendMode(gomock.Any()).Return(sendMode) sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone) - sph.EXPECT().ECNMode(gomock.Any()) + 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) @@ -1372,9 +1376,9 @@ var _ = Describe("Connection", func() { sent := make(chan struct{}) 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()) @@ -1393,7 +1397,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 @@ -1792,7 +1796,7 @@ var _ = Describe("Connection", func() { // only EXPECT calls after scheduleSending is called written := make(chan struct{}) 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()).AnyTimes() + tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() conn.scheduleSending() Eventually(written).Should(BeClosed()) }) @@ -1814,7 +1818,7 @@ var _ = Describe("Connection", func() { written := make(chan struct{}) 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()).AnyTimes() + tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() go func() { defer GinkgoRecover() cryptoSetup.EXPECT().StartHandshake().MaxTimes(1) @@ -1862,10 +1866,10 @@ var _ = Describe("Connection", func() { 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)) }), ) @@ -1974,7 +1978,7 @@ var _ = Describe("Connection", func() { sph.EXPECT().SetHandshakeConfirmed() 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()) + tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()) conn.sentPacketHandler = sph done := make(chan struct{}) connRunner.EXPECT().Retire(clientDestConnID) @@ -2549,7 +2553,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() @@ -2593,7 +2597,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()) }) @@ -3105,7 +3109,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()) @@ -3132,7 +3136,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()) }) @@ -3144,7 +3148,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()) }) diff --git a/integrationtests/self/key_update_test.go b/integrationtests/self/key_update_test.go index c24bef27d2e..7975a77bb5a 100644 --- a/integrationtests/self/key_update_test.go +++ b/integrationtests/self/key_update_test.go @@ -42,11 +42,13 @@ type keyUpdateConnTracer struct { logging.NullConnectionTracer } -func (t *keyUpdateConnTracer) SentShortHeaderPacket(hdr *logging.ShortHeader, _ logging.ByteCount, _ *logging.AckFrame, _ []logging.Frame) { +var _ logging.ConnectionTracer = &keyUpdateConnTracer{} + +func (t *keyUpdateConnTracer) SentShortHeaderPacket(hdr *logging.ShortHeader, _ logging.ByteCount, _ logging.ECN, _ *logging.AckFrame, _ []logging.Frame) { sentHeaders = append(sentHeaders, hdr) } -func (t *keyUpdateConnTracer) ReceivedShortHeaderPacket(hdr *logging.ShortHeader, size logging.ByteCount, frames []logging.Frame) { +func (t *keyUpdateConnTracer) ReceivedShortHeaderPacket(hdr *logging.ShortHeader, _ logging.ByteCount, _ logging.ECN, _ []logging.Frame) { receivedHeaders = append(receivedHeaders, hdr) } diff --git a/integrationtests/self/self_suite_test.go b/integrationtests/self/self_suite_test.go index 4b7ee5ef328..6396d3a7aac 100644 --- a/integrationtests/self/self_suite_test.go +++ b/integrationtests/self/self_suite_test.go @@ -265,19 +265,21 @@ type packetTracer struct { rcvdLongHdr []packet } +var _ logging.ConnectionTracer = &packetTracer{} + func newPacketTracer() *packetTracer { return &packetTracer{closed: make(chan struct{})} } -func (t *packetTracer) ReceivedLongHeaderPacket(hdr *logging.ExtendedHeader, _ logging.ByteCount, frames []logging.Frame) { +func (t *packetTracer) ReceivedLongHeaderPacket(hdr *logging.ExtendedHeader, _ logging.ByteCount, _ logging.ECN, 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) { +func (t *packetTracer) ReceivedShortHeaderPacket(hdr *logging.ShortHeader, _ logging.ByteCount, _ logging.ECN, 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) { +func (t *packetTracer) SentShortHeaderPacket(hdr *logging.ShortHeader, _ logging.ByteCount, _ logging.ECN, ack *wire.AckFrame, frames []logging.Frame) { if ack != nil { frames = append(frames, ack) } diff --git a/internal/mocks/logging/connection_tracer.go b/internal/mocks/logging/connection_tracer.go index 1ca0895d530..ff18006282d 100644 --- a/internal/mocks/logging/connection_tracer.go +++ b/internal/mocks/logging/connection_tracer.go @@ -184,15 +184,15 @@ func (mr *MockConnectionTracerMockRecorder) NegotiatedVersion(arg0, arg1, arg2 i } // ReceivedLongHeaderPacket mocks base method. -func (m *MockConnectionTracer) ReceivedLongHeaderPacket(arg0 *wire.ExtendedHeader, arg1 protocol.ByteCount, arg2 []logging.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 interface{}) *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. @@ -208,15 +208,15 @@ func (mr *MockConnectionTracerMockRecorder) ReceivedRetry(arg0 interface{}) *gom } // ReceivedShortHeaderPacket mocks base method. -func (m *MockConnectionTracer) ReceivedShortHeaderPacket(arg0 *logging.ShortHeader, arg1 protocol.ByteCount, arg2 []logging.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 interface{}) *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. @@ -256,27 +256,27 @@ func (mr *MockConnectionTracerMockRecorder) RestoredTransportParameters(arg0 int } // SentLongHeaderPacket mocks base method. -func (m *MockConnectionTracer) SentLongHeaderPacket(arg0 *wire.ExtendedHeader, arg1 protocol.ByteCount, arg2 *wire.AckFrame, arg3 []logging.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 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) + 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 *logging.ShortHeader, arg1 protocol.ByteCount, arg2 *wire.AckFrame, arg3 []logging.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 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) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentShortHeaderPacket), arg0, arg1, arg2, arg3, arg4) } // SentTransportParameters mocks base method. diff --git a/logging/interface.go b/logging/interface.go index 2ce8582ecb9..a83fb507ef8 100644 --- a/logging/interface.go +++ b/logging/interface.go @@ -15,6 +15,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 +60,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 @@ -113,12 +128,12 @@ type ConnectionTracer interface { 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) + SentLongHeaderPacket(*ExtendedHeader, ByteCount, ECN, *AckFrame, []Frame) + SentShortHeaderPacket(*ShortHeader, ByteCount, ECN, *AckFrame, []Frame) ReceivedVersionNegotiationPacket(dest, src ArbitraryLenConnectionID, _ []VersionNumber) ReceivedRetry(*Header) - ReceivedLongHeaderPacket(hdr *ExtendedHeader, size ByteCount, frames []Frame) - ReceivedShortHeaderPacket(hdr *ShortHeader, size ByteCount, frames []Frame) + ReceivedLongHeaderPacket(*ExtendedHeader, ByteCount, ECN, []Frame) + ReceivedShortHeaderPacket(*ShortHeader, ByteCount, ECN, []Frame) BufferedPacket(PacketType, ByteCount) DroppedPacket(PacketType, ByteCount, PacketDropReason) UpdatedMetrics(rttStats *RTTStats, cwnd, bytesInFlight ByteCount, packetsInFlight int) diff --git a/logging/mock_connection_tracer_test.go b/logging/mock_connection_tracer_test.go index f4f7648a399..f2b8cc8a979 100644 --- a/logging/mock_connection_tracer_test.go +++ b/logging/mock_connection_tracer_test.go @@ -183,15 +183,15 @@ func (mr *MockConnectionTracerMockRecorder) NegotiatedVersion(arg0, arg1, arg2 i } // 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 []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 interface{}) *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. @@ -207,15 +207,15 @@ func (mr *MockConnectionTracerMockRecorder) ReceivedRetry(arg0 interface{}) *gom } // ReceivedShortHeaderPacket mocks base method. -func (m *MockConnectionTracer) ReceivedShortHeaderPacket(arg0 *ShortHeader, arg1 protocol.ByteCount, arg2 []Frame) { +func (m *MockConnectionTracer) ReceivedShortHeaderPacket(arg0 *ShortHeader, arg1 protocol.ByteCount, arg2 protocol.ECN, arg3 []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 interface{}) *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. @@ -255,27 +255,27 @@ func (mr *MockConnectionTracerMockRecorder) RestoredTransportParameters(arg0 int } // 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 []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 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) + 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 *ShortHeader, arg1 protocol.ByteCount, arg2 protocol.ECN, arg3 *wire.AckFrame, arg4 []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 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) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentShortHeaderPacket), arg0, arg1, arg2, arg3, arg4) } // SentTransportParameters mocks base method. diff --git a/logging/multiplex.go b/logging/multiplex.go index 672a5cdbd86..0aecc9c2cbf 100644 --- a/logging/multiplex.go +++ b/logging/multiplex.go @@ -93,15 +93,15 @@ func (m *connTracerMultiplexer) RestoredTransportParameters(tp *TransportParamet } } -func (m *connTracerMultiplexer) SentLongHeaderPacket(hdr *ExtendedHeader, size ByteCount, ack *AckFrame, frames []Frame) { +func (m *connTracerMultiplexer) SentLongHeaderPacket(hdr *ExtendedHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame) { for _, t := range m.tracers { - t.SentLongHeaderPacket(hdr, size, ack, frames) + t.SentLongHeaderPacket(hdr, size, ecn, ack, frames) } } -func (m *connTracerMultiplexer) SentShortHeaderPacket(hdr *ShortHeader, size ByteCount, ack *AckFrame, frames []Frame) { +func (m *connTracerMultiplexer) SentShortHeaderPacket(hdr *ShortHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame) { for _, t := range m.tracers { - t.SentShortHeaderPacket(hdr, size, ack, frames) + t.SentShortHeaderPacket(hdr, size, ecn, ack, frames) } } @@ -117,15 +117,15 @@ func (m *connTracerMultiplexer) ReceivedRetry(hdr *Header) { } } -func (m *connTracerMultiplexer) ReceivedLongHeaderPacket(hdr *ExtendedHeader, size ByteCount, frames []Frame) { +func (m *connTracerMultiplexer) ReceivedLongHeaderPacket(hdr *ExtendedHeader, size ByteCount, ecn ECN, frames []Frame) { for _, t := range m.tracers { - t.ReceivedLongHeaderPacket(hdr, size, frames) + t.ReceivedLongHeaderPacket(hdr, size, ecn, frames) } } -func (m *connTracerMultiplexer) ReceivedShortHeaderPacket(hdr *ShortHeader, size ByteCount, frames []Frame) { +func (m *connTracerMultiplexer) ReceivedShortHeaderPacket(hdr *ShortHeader, size ByteCount, ecn ECN, frames []Frame) { for _, t := range m.tracers { - t.ReceivedShortHeaderPacket(hdr, size, frames) + t.ReceivedShortHeaderPacket(hdr, size, ecn, frames) } } diff --git a/logging/multiplex_test.go b/logging/multiplex_test.go index d22204999cb..572ced6a427 100644 --- a/logging/multiplex_test.go +++ b/logging/multiplex_test.go @@ -119,18 +119,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 +151,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() { diff --git a/logging/null_tracer.go b/logging/null_tracer.go index de970385796..731039e32ed 100644 --- a/logging/null_tracer.go +++ b/logging/null_tracer.go @@ -27,19 +27,23 @@ func (n NullConnectionTracer) StartedConnection(local, remote net.Addr, srcConnI 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) ClosedConnection(err error) {} +func (n NullConnectionTracer) SentTransportParameters(*TransportParameters) {} +func (n NullConnectionTracer) ReceivedTransportParameters(*TransportParameters) {} +func (n NullConnectionTracer) RestoredTransportParameters(*TransportParameters) {} +func (n NullConnectionTracer) SentLongHeaderPacket(*ExtendedHeader, ByteCount, ECN, *AckFrame, []Frame) { +} + +func (n NullConnectionTracer) SentShortHeaderPacket(*ShortHeader, ByteCount, ECN, *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) ReceivedRetry(*Header) {} +func (n NullConnectionTracer) ReceivedLongHeaderPacket(*ExtendedHeader, ByteCount, ECN, []Frame) {} +func (n NullConnectionTracer) ReceivedShortHeaderPacket(*ShortHeader, ByteCount, ECN, []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) { } diff --git a/qlog/event.go b/qlog/event.go index 9dae7444100..1a76df95799 100644 --- a/qlog/event.go +++ b/qlog/event.go @@ -158,6 +158,7 @@ type eventPacketSent struct { PayloadLength logging.ByteCount Frames frames IsCoalesced bool + ECN logging.ECN Trigger string } @@ -172,6 +173,9 @@ func (e eventPacketSent) MarshalJSONObject(enc *gojay.Encoder) { enc.ObjectKey("raw", rawInfo{Length: e.Length, PayloadLength: e.PayloadLength}) enc.ArrayKeyOmitEmpty("frames", e.Frames) enc.BoolKeyOmitEmpty("is_coalesced", e.IsCoalesced) + if e.ECN != logging.ECNUnsupported { + enc.StringKey("ecn", ecn(e.ECN).String()) + } enc.StringKeyOmitEmpty("trigger", e.Trigger) } @@ -180,6 +184,7 @@ type eventPacketReceived struct { Length logging.ByteCount PayloadLength logging.ByteCount Frames frames + ECN logging.ECN IsCoalesced bool Trigger string } @@ -195,6 +200,9 @@ func (e eventPacketReceived) MarshalJSONObject(enc *gojay.Encoder) { enc.ObjectKey("raw", rawInfo{Length: e.Length, PayloadLength: e.PayloadLength}) enc.ArrayKeyOmitEmpty("frames", e.Frames) enc.BoolKeyOmitEmpty("is_coalesced", e.IsCoalesced) + if e.ECN != logging.ECNUnsupported { + enc.StringKey("ecn", ecn(e.ECN).String()) + } enc.StringKeyOmitEmpty("trigger", e.Trigger) } diff --git a/qlog/qlog.go b/qlog/qlog.go index 4c480e26056..6d2ece072a4 100644 --- a/qlog/qlog.go +++ b/qlog/qlog.go @@ -253,15 +253,33 @@ func (t *connectionTracer) toTransportParameters(tp *wire.TransportParameters) * } } -func (t *connectionTracer) SentLongHeaderPacket(hdr *logging.ExtendedHeader, packetSize logging.ByteCount, ack *logging.AckFrame, frames []logging.Frame) { - t.sentPacket(*transformLongHeader(hdr), packetSize, hdr.Length, ack, frames) -} - -func (t *connectionTracer) SentShortHeaderPacket(hdr *logging.ShortHeader, packetSize logging.ByteCount, ack *logging.AckFrame, frames []logging.Frame) { - t.sentPacket(*transformShortHeader(hdr), packetSize, 0, ack, frames) -} - -func (t *connectionTracer) sentPacket(hdr gojay.MarshalerJSONObject, packetSize, payloadLen logging.ByteCount, ack *logging.AckFrame, frames []logging.Frame) { +func (t *connectionTracer) SentLongHeaderPacket( + hdr *logging.ExtendedHeader, + size logging.ByteCount, + ecn logging.ECN, + ack *logging.AckFrame, + frames []logging.Frame, +) { + t.sentPacket(*transformLongHeader(hdr), size, hdr.Length, ecn, ack, frames) +} + +func (t *connectionTracer) SentShortHeaderPacket( + hdr *logging.ShortHeader, + size logging.ByteCount, + ecn logging.ECN, + ack *logging.AckFrame, + frames []logging.Frame, +) { + t.sentPacket(*transformShortHeader(hdr), size, 0, ecn, ack, frames) +} + +func (t *connectionTracer) sentPacket( + hdr gojay.MarshalerJSONObject, + size, payloadLen logging.ByteCount, + ecn logging.ECN, + ack *logging.AckFrame, + frames []logging.Frame, +) { numFrames := len(frames) if ack != nil { numFrames++ @@ -276,14 +294,15 @@ func (t *connectionTracer) sentPacket(hdr gojay.MarshalerJSONObject, packetSize, t.mutex.Lock() t.recordEvent(time.Now(), &eventPacketSent{ Header: hdr, - Length: packetSize, + Length: size, PayloadLength: payloadLen, + ECN: ecn, Frames: fs, }) t.mutex.Unlock() } -func (t *connectionTracer) ReceivedLongHeaderPacket(hdr *logging.ExtendedHeader, packetSize logging.ByteCount, frames []logging.Frame) { +func (t *connectionTracer) ReceivedLongHeaderPacket(hdr *logging.ExtendedHeader, size logging.ByteCount, ecn logging.ECN, frames []logging.Frame) { fs := make([]frame, len(frames)) for i, f := range frames { fs[i] = frame{Frame: f} @@ -292,14 +311,15 @@ func (t *connectionTracer) ReceivedLongHeaderPacket(hdr *logging.ExtendedHeader, t.mutex.Lock() t.recordEvent(time.Now(), &eventPacketReceived{ Header: header, - Length: packetSize, + Length: size, PayloadLength: hdr.Length, + ECN: ecn, Frames: fs, }) t.mutex.Unlock() } -func (t *connectionTracer) ReceivedShortHeaderPacket(hdr *logging.ShortHeader, packetSize logging.ByteCount, frames []logging.Frame) { +func (t *connectionTracer) ReceivedShortHeaderPacket(hdr *logging.ShortHeader, size logging.ByteCount, ecn logging.ECN, frames []logging.Frame) { fs := make([]frame, len(frames)) for i, f := range frames { fs[i] = frame{Frame: f} @@ -308,8 +328,9 @@ func (t *connectionTracer) ReceivedShortHeaderPacket(hdr *logging.ShortHeader, p t.mutex.Lock() t.recordEvent(time.Now(), &eventPacketReceived{ Header: header, - Length: packetSize, - PayloadLength: packetSize - wire.ShortHeaderLen(hdr.DestConnectionID, hdr.PacketNumberLen), + Length: size, + PayloadLength: size - wire.ShortHeaderLen(hdr.DestConnectionID, hdr.PacketNumberLen), + ECN: ecn, Frames: fs, }) t.mutex.Unlock() diff --git a/qlog/qlog_test.go b/qlog/qlog_test.go index dc0d2dc1823..d7634464d3e 100644 --- a/qlog/qlog_test.go +++ b/qlog/qlog_test.go @@ -419,6 +419,7 @@ var _ = Describe("Tracing", func() { PacketNumber: 1337, }, 987, + logging.ECNCE, nil, []logging.Frame{ &logging.MaxStreamDataFrame{StreamID: 42, MaximumStreamData: 987}, @@ -439,6 +440,7 @@ var _ = Describe("Tracing", func() { Expect(hdr).To(HaveKeyWithValue("packet_number", float64(1337))) Expect(hdr).To(HaveKeyWithValue("scid", "04030201")) Expect(ev).To(HaveKey("frames")) + Expect(ev).To(HaveKeyWithValue("ecn", "CE")) frames := ev["frames"].([]interface{}) Expect(frames).To(HaveLen(2)) Expect(frames[0].(map[string]interface{})).To(HaveKeyWithValue("frame_type", "max_stream_data")) @@ -452,6 +454,7 @@ var _ = Describe("Tracing", func() { PacketNumber: 1337, }, 123, + logging.ECNUnsupported, &logging.AckFrame{AckRanges: []logging.AckRange{{Smallest: 1, Largest: 10}}}, []logging.Frame{&logging.MaxDataFrame{MaximumData: 987}}, ) @@ -461,6 +464,7 @@ var _ = Describe("Tracing", func() { Expect(raw).To(HaveKeyWithValue("length", float64(123))) Expect(raw).ToNot(HaveKey("payload_length")) Expect(ev).To(HaveKey("header")) + Expect(ev).ToNot(HaveKey("ecn")) hdr := ev["header"].(map[string]interface{}) Expect(hdr).To(HaveKeyWithValue("packet_type", "1RTT")) Expect(hdr).To(HaveKeyWithValue("packet_number", float64(1337))) @@ -485,6 +489,7 @@ var _ = Describe("Tracing", func() { PacketNumber: 1337, }, 789, + logging.ECT0, []logging.Frame{ &logging.MaxStreamDataFrame{StreamID: 42, MaximumStreamData: 987}, &logging.StreamFrame{StreamID: 123, Offset: 1234, Length: 6, Fin: true}, @@ -498,6 +503,7 @@ var _ = Describe("Tracing", func() { raw := ev["raw"].(map[string]interface{}) Expect(raw).To(HaveKeyWithValue("length", float64(789))) Expect(raw).To(HaveKeyWithValue("payload_length", float64(1234))) + Expect(ev).To(HaveKeyWithValue("ecn", "ECT(0)")) Expect(ev).To(HaveKey("header")) hdr := ev["header"].(map[string]interface{}) Expect(hdr).To(HaveKeyWithValue("packet_type", "initial")) @@ -520,6 +526,7 @@ var _ = Describe("Tracing", func() { tracer.ReceivedShortHeaderPacket( shdr, 789, + logging.ECT1, []logging.Frame{ &logging.MaxStreamDataFrame{StreamID: 42, MaximumStreamData: 987}, &logging.StreamFrame{StreamID: 123, Offset: 1234, Length: 6, Fin: true}, @@ -533,6 +540,7 @@ var _ = Describe("Tracing", func() { raw := ev["raw"].(map[string]interface{}) Expect(raw).To(HaveKeyWithValue("length", float64(789))) Expect(raw).To(HaveKeyWithValue("payload_length", float64(789-(1+8+3)))) + Expect(ev).To(HaveKeyWithValue("ecn", "ECT(1)")) Expect(ev).To(HaveKey("header")) hdr := ev["header"].(map[string]interface{}) Expect(hdr).To(HaveKeyWithValue("packet_type", "1RTT")) diff --git a/qlog/types.go b/qlog/types.go index c47ad481ea5..34104e61a4b 100644 --- a/qlog/types.go +++ b/qlog/types.go @@ -312,3 +312,21 @@ func (s congestionState) String() string { return "unknown congestion state" } } + +type ecn logging.ECN + +func (e ecn) String() string { + //nolint:exhaustive // The unsupported value is never logged. + switch logging.ECN(e) { + case logging.ECTNot: + return "Not-ECT" + case logging.ECT0: + return "ECT(0)" + case logging.ECT1: + return "ECT(1)" + case logging.ECNCE: + return "CE" + default: + return "unknown ECN" + } +} diff --git a/qlog/types_test.go b/qlog/types_test.go index 9213ad311a7..6918b0826d3 100644 --- a/qlog/types_test.go +++ b/qlog/types_test.go @@ -127,4 +127,12 @@ var _ = Describe("Types", func() { Expect(congestionState(logging.CongestionStateApplicationLimited).String()).To(Equal("application_limited")) Expect(congestionState(logging.CongestionStateRecovery).String()).To(Equal("recovery")) }) + + It("has a string representation for the ECN bits", func() { + Expect(ecn(logging.ECT0).String()).To(Equal("ECT(0)")) + Expect(ecn(logging.ECT1).String()).To(Equal("ECT(1)")) + Expect(ecn(logging.ECNCE).String()).To(Equal("CE")) + Expect(ecn(logging.ECTNot).String()).To(Equal("Not-ECT")) + Expect(ecn(42).String()).To(Equal("unknown ECN")) + }) }) From ffe6546833341205076b6c3631df129c4043d2b0 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 1 Sep 2023 14:17:59 +0700 Subject: [PATCH 055/225] add tracing and qlogging of state transitions for ECN validation --- internal/mocks/logging/connection_tracer.go | 12 +++++++ logging/interface.go | 1 + logging/mock_connection_tracer_test.go | 12 +++++++ logging/multiplex.go | 6 ++++ logging/null_tracer.go | 27 ++++++++------- logging/types.go | 32 +++++++++++++++++ qlog/event.go | 14 ++++++++ qlog/qlog.go | 6 ++++ qlog/qlog_test.go | 21 ++++++++++++ qlog/types.go | 38 +++++++++++++++++++++ qlog/types_test.go | 18 ++++++++++ 11 files changed, 174 insertions(+), 13 deletions(-) diff --git a/internal/mocks/logging/connection_tracer.go b/internal/mocks/logging/connection_tracer.go index ff18006282d..811d1e99370 100644 --- a/internal/mocks/logging/connection_tracer.go +++ b/internal/mocks/logging/connection_tracer.go @@ -135,6 +135,18 @@ func (mr *MockConnectionTracerMockRecorder) DroppedPacket(arg0, arg1, arg2 inter 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 interface{}) *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() diff --git a/logging/interface.go b/logging/interface.go index a83fb507ef8..62028ebc07b 100644 --- a/logging/interface.go +++ b/logging/interface.go @@ -148,6 +148,7 @@ type ConnectionTracer interface { SetLossTimer(TimerType, EncryptionLevel, time.Time) LossTimerExpired(TimerType, EncryptionLevel) LossTimerCanceled() + ECNStateUpdated(state ECNState, trigger ECNStateTrigger) // Close is called when the connection is closed. Close() Debug(name, msg string) diff --git a/logging/mock_connection_tracer_test.go b/logging/mock_connection_tracer_test.go index f2b8cc8a979..94722509254 100644 --- a/logging/mock_connection_tracer_test.go +++ b/logging/mock_connection_tracer_test.go @@ -134,6 +134,18 @@ func (mr *MockConnectionTracerMockRecorder) DroppedPacket(arg0, arg1, arg2 inter 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 ECNState, arg1 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 interface{}) *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() diff --git a/logging/multiplex.go b/logging/multiplex.go index 0aecc9c2cbf..ef91f3f2b96 100644 --- a/logging/multiplex.go +++ b/logging/multiplex.go @@ -213,6 +213,12 @@ func (m *connTracerMultiplexer) LossTimerCanceled() { } } +func (m *connTracerMultiplexer) ECNStateUpdated(state ECNState, trigger ECNStateTrigger) { + for _, t := range m.tracers { + t.ECNStateUpdated(state, trigger) + } +} + func (m *connTracerMultiplexer) Debug(name, msg string) { for _, t := range m.tracers { t.Debug(name, msg) diff --git a/logging/null_tracer.go b/logging/null_tracer.go index 731039e32ed..3e3458f7e6d 100644 --- a/logging/null_tracer.go +++ b/logging/null_tracer.go @@ -47,16 +47,17 @@ func (n NullConnectionTracer) DroppedPacket(PacketType, ByteCount, PacketDropRea 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) {} +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, EncryptionLevel) {} +func (n NullConnectionTracer) LossTimerCanceled() {} +func (n NullConnectionTracer) ECNStateUpdated(ECNState, ECNStateTrigger) {} +func (n NullConnectionTracer) Close() {} +func (n NullConnectionTracer) Debug(name, msg string) {} diff --git a/logging/types.go b/logging/types.go index ad800692353..bfee91c324c 100644 --- a/logging/types.go +++ b/logging/types.go @@ -92,3 +92,35 @@ 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 contains fewer ECT(0) / ECT(1) counts than it acknowledges packets + ECNFailedTooFewECNCounts +) diff --git a/qlog/event.go b/qlog/event.go index 1a76df95799..740d3c2e19f 100644 --- a/qlog/event.go +++ b/qlog/event.go @@ -524,6 +524,20 @@ func (e eventCongestionStateUpdated) MarshalJSONObject(enc *gojay.Encoder) { enc.StringKey("new", e.state.String()) } +type eventECNStateUpdated struct { + state logging.ECNState + trigger logging.ECNStateTrigger +} + +func (e eventECNStateUpdated) Category() category { return categoryRecovery } +func (e eventECNStateUpdated) Name() string { return "ecn_state_updated" } +func (e eventECNStateUpdated) IsNil() bool { return false } + +func (e eventECNStateUpdated) MarshalJSONObject(enc *gojay.Encoder) { + enc.StringKey("new", ecnState(e.state).String()) + enc.StringKeyOmitEmpty("trigger", ecnStateTrigger(e.trigger).String()) +} + type eventGeneric struct { name string msg string diff --git a/qlog/qlog.go b/qlog/qlog.go index 6d2ece072a4..943bbc3d11b 100644 --- a/qlog/qlog.go +++ b/qlog/qlog.go @@ -503,6 +503,12 @@ func (t *connectionTracer) LossTimerCanceled() { t.mutex.Unlock() } +func (t *connectionTracer) ECNStateUpdated(state logging.ECNState, trigger logging.ECNStateTrigger) { + t.mutex.Lock() + t.recordEvent(time.Now(), &eventECNStateUpdated{state: state, trigger: trigger}) + t.mutex.Unlock() +} + func (t *connectionTracer) Debug(name, msg string) { t.mutex.Lock() t.recordEvent(time.Now(), &eventGeneric{ diff --git a/qlog/qlog_test.go b/qlog/qlog_test.go index d7634464d3e..c19a0d3e1da 100644 --- a/qlog/qlog_test.go +++ b/qlog/qlog_test.go @@ -865,6 +865,27 @@ var _ = Describe("Tracing", func() { Expect(ev).To(HaveKeyWithValue("event_type", "cancelled")) }) + It("records an ECN state transition, without a trigger", func() { + tracer.ECNStateUpdated(logging.ECNStateUnknown, logging.ECNTriggerNoTrigger) + entry := exportAndParseSingle() + Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) + Expect(entry.Name).To(Equal("recovery:ecn_state_updated")) + ev := entry.Event + Expect(ev).To(HaveLen(1)) + Expect(ev).To(HaveKeyWithValue("new", "unknown")) + }) + + It("records an ECN state transition, with a trigger", func() { + tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedNoECNCounts) + entry := exportAndParseSingle() + Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) + Expect(entry.Name).To(Equal("recovery:ecn_state_updated")) + ev := entry.Event + Expect(ev).To(HaveLen(2)) + Expect(ev).To(HaveKeyWithValue("new", "failed")) + Expect(ev).To(HaveKeyWithValue("trigger", "ACK doesn't contain ECN marks")) + }) + It("records a generic event", func() { tracer.Debug("foo", "bar") entry := exportAndParseSingle() diff --git a/qlog/types.go b/qlog/types.go index 34104e61a4b..49b4853a6de 100644 --- a/qlog/types.go +++ b/qlog/types.go @@ -330,3 +330,41 @@ func (e ecn) String() string { return "unknown ECN" } } + +type ecnState logging.ECNState + +func (e ecnState) String() string { + switch logging.ECNState(e) { + case logging.ECNStateTesting: + return "testing" + case logging.ECNStateUnknown: + return "unknown" + case logging.ECNStateCapable: + return "capable" + case logging.ECNStateFailed: + return "failed" + default: + return "unknown ECN state" + } +} + +type ecnStateTrigger logging.ECNStateTrigger + +func (e ecnStateTrigger) String() string { + switch logging.ECNStateTrigger(e) { + case logging.ECNTriggerNoTrigger: + return "" + case logging.ECNFailedNoECNCounts: + return "ACK doesn't contain ECN marks" + case logging.ECNFailedDecreasedECNCounts: + return "ACK decreases ECN counts" + case logging.ECNFailedLostAllTestingPackets: + return "all ECN testing packets declared lost" + case logging.ECNFailedMoreECNCountsThanSent: + return "ACK contains more ECN counts than ECN-marked packets sent" + case logging.ECNFailedTooFewECNCounts: + return "ACK contains fewer new ECN counts than acknowledged ECN-marked packets" + default: + return "unknown ECN state trigger" + } +} diff --git a/qlog/types_test.go b/qlog/types_test.go index 6918b0826d3..d08eb739221 100644 --- a/qlog/types_test.go +++ b/qlog/types_test.go @@ -135,4 +135,22 @@ var _ = Describe("Types", func() { Expect(ecn(logging.ECTNot).String()).To(Equal("Not-ECT")) Expect(ecn(42).String()).To(Equal("unknown ECN")) }) + + It("has a string representation for the ECN state", func() { + Expect(ecnState(logging.ECNStateTesting).String()).To(Equal("testing")) + Expect(ecnState(logging.ECNStateUnknown).String()).To(Equal("unknown")) + Expect(ecnState(logging.ECNStateFailed).String()).To(Equal("failed")) + Expect(ecnState(logging.ECNStateCapable).String()).To(Equal("capable")) + Expect(ecnState(42).String()).To(Equal("unknown ECN state")) + }) + + It("has a string representation for the ECN state trigger", func() { + Expect(ecnStateTrigger(logging.ECNTriggerNoTrigger).String()).To(Equal("")) + Expect(ecnStateTrigger(logging.ECNFailedNoECNCounts).String()).To(Equal("ACK doesn't contain ECN marks")) + Expect(ecnStateTrigger(logging.ECNFailedDecreasedECNCounts).String()).To(Equal("ACK decreases ECN counts")) + Expect(ecnStateTrigger(logging.ECNFailedLostAllTestingPackets).String()).To(Equal("all ECN testing packets declared lost")) + Expect(ecnStateTrigger(logging.ECNFailedMoreECNCountsThanSent).String()).To(Equal("ACK contains more ECN counts than ECN-marked packets sent")) + Expect(ecnStateTrigger(logging.ECNFailedTooFewECNCounts).String()).To(Equal("ACK contains fewer new ECN counts than acknowledged ECN-marked packets")) + Expect(ecnStateTrigger(42).String()).To(Equal("unknown ECN state trigger")) + }) }) From f9cfa248da6ceadf6c999111e1be214ead7698ac Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 1 Sep 2023 14:43:51 +0700 Subject: [PATCH 056/225] implement ECN path validation logic, send ECN-marked 1-RTT packets --- internal/ackhandler/ecn.go | 258 +++++++++++++++++++++ internal/ackhandler/ecn_test.go | 192 +++++++++++++++ internal/ackhandler/sent_packet_handler.go | 37 ++- 3 files changed, 479 insertions(+), 8 deletions(-) create mode 100644 internal/ackhandler/ecn.go create mode 100644 internal/ackhandler/ecn_test.go diff --git a/internal/ackhandler/ecn.go b/internal/ackhandler/ecn.go new file mode 100644 index 00000000000..0fd39098c04 --- /dev/null +++ b/internal/ackhandler/ecn.go @@ -0,0 +1,258 @@ +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 + +// 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 +} + +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(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(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++ + if e.numLostTesting >= e.numSentTesting { + e.logger.Debugf("Disabling ECN. All testing packets were lost.") + if e.tracer != nil { + e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedLostAllTestingPackets) + } + e.state = ecnStateFailed + } +} + +// 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(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(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(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(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(logging.ECNStateFailed, logging.ECNFailedTooFewECNCounts) + } + 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(logging.ECNStateCapable, logging.ECNTriggerNoTrigger) + } + e.state = ecnStateCapable + } + } + + // update our counters + e.numAckedECT0 = ect0 + e.numAckedECT1 = ect1 + e.numAckedECNCE = ecnce + + return newECNCE > 0 +} + +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) +} diff --git a/internal/ackhandler/ecn_test.go b/internal/ackhandler/ecn_test.go new file mode 100644 index 00000000000..74fff094497 --- /dev/null +++ b/internal/ackhandler/ecn_test.go @@ -0,0 +1,192 @@ +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() { + tracer = mocklogging.NewMockConnectionTracer(mockCtrl) + ecnTracker = newECNTracker(utils.DefaultLogger, tracer) + }) + + 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("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("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()) + }) +}) diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index 53aba0dd132..7d3d46617a4 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -92,7 +92,8 @@ type sentPacketHandler struct { // The alarm timeout alarm time.Time - enableECN bool + enableECN bool + ecnTracker *ecnTracker perspective protocol.Perspective @@ -125,7 +126,7 @@ func newSentPacketHandler( tracer, ) - return &sentPacketHandler{ + h := &sentPacketHandler{ peerCompletedAddressValidation: pers == protocol.PerspectiveServer, peerAddressValidated: pers == protocol.PerspectiveClient || clientAddressValidated, initialPackets: newPacketNumberSpace(initialPN, false), @@ -133,11 +134,15 @@ func newSentPacketHandler( appDataPackets: newPacketNumberSpace(0, true), rttStats: rttStats, congestion: congestion, - enableECN: enableECN, perspective: pers, tracer: tracer, logger: logger, } + if enableECN { + h.enableECN = true + h.ecnTracker = newECNTracker(logger, tracer) + } + return h } func (h *sentPacketHandler) removeFromBytesInFlight(p *packet) { @@ -232,7 +237,7 @@ func (h *sentPacketHandler) SentPacket( streamFrames []StreamFrame, frames []Frame, encLevel protocol.EncryptionLevel, - _ protocol.ECN, + ecn protocol.ECN, size protocol.ByteCount, isPathMTUProbePacket bool, ) { @@ -257,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 { @@ -307,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) { @@ -338,6 +345,18 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En h.congestion.MaybeExitSlowStart() } } + + var ecnCongestionDetected bool + // 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 { + ecnCongestionDetected = h.ecnTracker.HandleNewlyAcked(ackedPackets, int64(ack.ECT0), int64(ack.ECT1), int64(ack.ECNCE)) + } + + pnSpace.largestAcked = utils.Max(pnSpace.largestAcked, largestAcked) + + // TODO: inform the congestion controller + _ = ecnCongestionDetected + if err := h.detectLostPackets(rcvTime, encLevel); err != nil { return false, err } @@ -642,6 +661,9 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E if !p.IsPathMTUProbePacket { h.congestion.OnPacketLost(p.PacketNumber, p.Length, priorInFlight) } + if encLevel == protocol.Encryption1RTT && h.ecnTracker != nil { + h.ecnTracker.LostPacket(p.PacketNumber) + } } } return true, nil @@ -724,8 +746,7 @@ func (h *sentPacketHandler) ECNMode(isShortHeaderPacket bool) protocol.ECN { if !isShortHeaderPacket { return protocol.ECNNon } - // TODO: implement ECN logic - return protocol.ECNNon + return h.ecnTracker.Mode() } func (h *sentPacketHandler) PeekPacketNumber(encLevel protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen) { From b6ce91bfe7ff63b353f555bc29b2c9f66efea4c8 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 1 Sep 2023 18:12:22 +0700 Subject: [PATCH 057/225] stop appending to a GSO batch when the ECN marking changes --- connection.go | 10 +++++++--- connection_test.go | 47 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/connection.go b/connection.go index fdd056f123e..10a36ba005e 100644 --- a/connection.go +++ b/connection.go @@ -1911,9 +1911,9 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error { buf := getLargePacketBuffer() maxSize := s.mtuDiscoverer.CurrentSize() + ecn := s.sentPacketHandler.ECNMode(true) for { var dontSendMore bool - ecn := s.sentPacketHandler.ECNMode(true) size, err := s.appendOneShortHeaderPacket(buf, maxSize, ecn, now) if err != nil { if err != errNothingToPack { @@ -1936,11 +1936,15 @@ 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 } diff --git a/connection_test.go b/connection_test.go index 4fe53910dff..67b02443b7d 100644 --- a/connection_test.go +++ b/connection_test.go @@ -1451,7 +1451,7 @@ 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(), gomock.Any()).Times(2) - sph.EXPECT().ECNMode(true).Times(3) + 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) @@ -1476,20 +1476,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(), gomock.Any()).Times(2) - sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(2) - sph.EXPECT().ECNMode(true).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(), 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) From 797e275293e27a0c12f0bb79633086dacf1f0bd0 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 1 Sep 2023 22:07:12 +0700 Subject: [PATCH 058/225] congestion: rename OnPacketLost to OnCongestionEvent --- internal/ackhandler/sent_packet_handler.go | 2 +- .../ackhandler/sent_packet_handler_test.go | 12 +++++----- internal/congestion/cubic_sender.go | 2 +- internal/congestion/cubic_sender_test.go | 4 ++-- internal/congestion/interface.go | 2 +- internal/mocks/congestion.go | 24 +++++++++---------- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index 7d3d46617a4..90f8042239f 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -659,7 +659,7 @@ 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) diff --git a/internal/ackhandler/sent_packet_handler_test.go b/internal/ackhandler/sent_packet_handler_test.go index a1e1f0d9a8c..acadcf373ef 100644 --- a/internal/ackhandler/sent_packet_handler_test.go +++ b/internal/ackhandler/sent_packet_handler_test.go @@ -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}}} diff --git a/internal/congestion/cubic_sender.go b/internal/congestion/cubic_sender.go index 2e5084751a9..10eb4667dfa 100644 --- a/internal/congestion/cubic_sender.go +++ b/internal/congestion/cubic_sender.go @@ -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 { diff --git a/internal/congestion/cubic_sender_test.go b/internal/congestion/cubic_sender_test.go index 85d81167879..d02ec3e8a82 100644 --- a/internal/congestion/cubic_sender_test.go +++ b/internal/congestion/cubic_sender_test.go @@ -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 } diff --git a/internal/congestion/interface.go b/internal/congestion/interface.go index 484bd5f8135..881f453b69a 100644 --- a/internal/congestion/interface.go +++ b/internal/congestion/interface.go @@ -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) } diff --git a/internal/mocks/congestion.go b/internal/mocks/congestion.go index d27113a7c2a..4d38d1db6d1 100644 --- a/internal/mocks/congestion.go +++ b/internal/mocks/congestion.go @@ -117,28 +117,28 @@ func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) MaybeExitSlowStart() *gom return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaybeExitSlowStart", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).MaybeExitSlowStart)) } -// OnPacketAcked mocks base method. -func (m *MockSendAlgorithmWithDebugInfos) OnPacketAcked(arg0 protocol.PacketNumber, arg1, arg2 protocol.ByteCount, arg3 time.Time) { +// OnCongestionEvent mocks base method. +func (m *MockSendAlgorithmWithDebugInfos) OnCongestionEvent(arg0 protocol.PacketNumber, arg1, arg2 protocol.ByteCount) { m.ctrl.T.Helper() - m.ctrl.Call(m, "OnPacketAcked", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "OnCongestionEvent", arg0, arg1, arg2) } -// OnPacketAcked indicates an expected call of OnPacketAcked. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketAcked(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +// OnCongestionEvent indicates an expected call of OnCongestionEvent. +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnCongestionEvent(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketAcked", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketAcked), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnCongestionEvent", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnCongestionEvent), arg0, arg1, arg2) } -// OnPacketLost mocks base method. -func (m *MockSendAlgorithmWithDebugInfos) OnPacketLost(arg0 protocol.PacketNumber, arg1, arg2 protocol.ByteCount) { +// OnPacketAcked mocks base method. +func (m *MockSendAlgorithmWithDebugInfos) OnPacketAcked(arg0 protocol.PacketNumber, arg1, arg2 protocol.ByteCount, arg3 time.Time) { m.ctrl.T.Helper() - m.ctrl.Call(m, "OnPacketLost", arg0, arg1, arg2) + m.ctrl.Call(m, "OnPacketAcked", arg0, arg1, arg2, arg3) } -// OnPacketLost indicates an expected call of OnPacketLost. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketLost(arg0, arg1, arg2 interface{}) *gomock.Call { +// OnPacketAcked indicates an expected call of OnPacketAcked. +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketAcked(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketLost", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketLost), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketAcked", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketAcked), arg0, arg1, arg2, arg3) } // OnPacketSent mocks base method. From d6ac6300a443a636804399a1cd690ebafddc603d Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 2 Sep 2023 09:26:49 +0700 Subject: [PATCH 059/225] feed ECN feedback into the congestion controller --- internal/ackhandler/ecn.go | 9 ++ internal/ackhandler/mock_ecn_handler_test.go | 87 +++++++++++ internal/ackhandler/mockgen.go | 3 + internal/ackhandler/sent_packet_handler.go | 11 +- .../ackhandler/sent_packet_handler_test.go | 147 ++++++++++++++++++ 5 files changed, 251 insertions(+), 6 deletions(-) create mode 100644 internal/ackhandler/mock_ecn_handler_test.go diff --git a/internal/ackhandler/ecn.go b/internal/ackhandler/ecn.go index 0fd39098c04..ff0dfe652bd 100644 --- a/internal/ackhandler/ecn.go +++ b/internal/ackhandler/ecn.go @@ -21,6 +21,13 @@ const ( // 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. @@ -42,6 +49,8 @@ type ecnTracker struct { logger utils.Logger } +var _ ecnHandler = &ecnTracker{} + func newECNTracker(logger utils.Logger, tracer logging.ConnectionTracer) *ecnTracker { return &ecnTracker{ firstTestingPacket: protocol.InvalidPacketNumber, diff --git a/internal/ackhandler/mock_ecn_handler_test.go b/internal/ackhandler/mock_ecn_handler_test.go new file mode 100644 index 00000000000..28f350c1709 --- /dev/null +++ b/internal/ackhandler/mock_ecn_handler_test.go @@ -0,0 +1,87 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/quic-go/quic-go/internal/ackhandler (interfaces: 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 interface{}) *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 interface{}) *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 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockECNHandler)(nil).SentPacket), arg0, arg1) +} diff --git a/internal/ackhandler/mockgen.go b/internal/ackhandler/mockgen.go index b9eb8a88e0c..dbf6ee2d1e7 100644 --- a/internal/ackhandler/mockgen.go +++ b/internal/ackhandler/mockgen.go @@ -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/quic-go/quic-go/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 diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index 90f8042239f..b498ce4b77d 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -93,7 +93,7 @@ type sentPacketHandler struct { alarm time.Time enableECN bool - ecnTracker *ecnTracker + ecnTracker ecnHandler perspective protocol.Perspective @@ -346,17 +346,16 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En } } - var ecnCongestionDetected bool // 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 { - ecnCongestionDetected = h.ecnTracker.HandleNewlyAcked(ackedPackets, int64(ack.ECT0), int64(ack.ECT1), int64(ack.ECNCE)) + 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) - // TODO: inform the congestion controller - _ = ecnCongestionDetected - if err := h.detectLostPackets(rcvTime, encLevel); err != nil { return false, err } diff --git a/internal/ackhandler/sent_packet_handler_test.go b/internal/ackhandler/sent_packet_handler_test.go index acadcf373ef..63f1b8341b2 100644 --- a/internal/ackhandler/sent_packet_handler_test.go +++ b/internal/ackhandler/sent_packet_handler_test.go @@ -1429,4 +1429,151 @@ var _ = Describe("SentPacketHandler", func() { 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()) + }) + }) }) From d1f6ea997cba051841632758ea22679817da90ba Mon Sep 17 00:00:00 2001 From: Ameagari <47713057+tanghaowillow@users.noreply.github.com> Date: Mon, 11 Sep 2023 23:05:31 +0800 Subject: [PATCH 060/225] save the RTT in non-0-RTT session tickets (#4042) * also send session ticket when 0-RTT is disabled for go1.21 * allow session ticket without transport parameters * do not include transport parameters for non-0RTT session ticket * remove the test assertion because it is not supported for go1.20 * Update internal/handshake/session_ticket.go Co-authored-by: Marten Seemann * add a 0-RTT argument to unmarshaling session tickets * bump sessionTicketRevision to 4 * check if non-0-RTT session ticket has expected length * change parameter order * add test checks --------- Co-authored-by: Marten Seemann --- internal/handshake/crypto_setup.go | 28 ++++++++------ internal/handshake/crypto_setup_test.go | 12 +++++- internal/handshake/session_ticket.go | 19 +++++++--- internal/handshake/session_ticket_test.go | 46 +++++++++++++++++++---- internal/qtls/go120.go | 8 ++-- internal/qtls/go121.go | 24 ++++++------ 6 files changed, 95 insertions(+), 42 deletions(-) diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index 332dbd7ef56..b5fb404bf6d 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -127,7 +127,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 @@ -347,10 +347,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. @@ -379,12 +382,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) @@ -397,7 +404,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 } diff --git a/internal/handshake/crypto_setup_test.go b/internal/handshake/crypto_setup_test.go index e40db500e1c..9b2844f703b 100644 --- a/internal/handshake/crypto_setup_test.go +++ b/internal/handshake/crypto_setup_test.go @@ -8,6 +8,8 @@ import ( "crypto/x509/pkix" "math/big" "net" + "runtime" + "strings" "time" mocktls "github.com/quic-go/quic-go/internal/mocks/tls" @@ -417,11 +419,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, ) @@ -434,9 +438,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, ) @@ -446,6 +451,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() { diff --git a/internal/handshake/session_ticket.go b/internal/handshake/session_ticket.go index d3efeb2941c..9481af563e9 100644 --- a/internal/handshake/session_ticket.go +++ b/internal/handshake/session_ticket.go @@ -10,7 +10,7 @@ import ( "github.com/quic-go/quic-go/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 } diff --git a/internal/handshake/session_ticket_test.go b/internal/handshake/session_ticket_test.go index 6f004de973d..8e209d3aaef 100644 --- a/internal/handshake/session_ticket_test.go +++ b/internal/handshake/session_ticket_test.go @@ -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")) + }) }) diff --git a/internal/qtls/go120.go b/internal/qtls/go120.go index 3b50441c47c..898f03526c8 100644 --- a/internal/qtls/go120.go +++ b/internal/qtls/go120.go @@ -39,13 +39,15 @@ const ( QUICHandshakeDone = qtls.QUICHandshakeDone ) -func SetupConfigForServer(conf *QUICConfig, enable0RTT bool, getDataForSessionTicket func() []byte, accept0RTT func([]byte) bool) { +func SetupConfigForServer(conf *QUICConfig, enable0RTT bool, getDataForSessionTicket func() []byte, handleSessionTicket func([]byte, bool) bool) { qtls.InitSessionTicketKeys(conf.TLSConfig) conf.TLSConfig = conf.TLSConfig.Clone() conf.TLSConfig.MinVersion = tls.VersionTLS13 conf.ExtraConfig = &qtls.ExtraConfig{ - Enable0RTT: enable0RTT, - Accept0RTT: accept0RTT, + Enable0RTT: enable0RTT, + Accept0RTT: func(data []byte) bool { + return handleSessionTicket(data, true) + }, GetAppDataForSessionTicket: getDataForSessionTicket, } } diff --git a/internal/qtls/go121.go b/internal/qtls/go121.go index 4aebc4a14c3..65a274ac0a7 100644 --- a/internal/qtls/go121.go +++ b/internal/qtls/go121.go @@ -41,7 +41,7 @@ const ( func QUICServer(config *QUICConfig) *QUICConn { return tls.QUICServer(config) } func QUICClient(config *QUICConfig) *QUICConn { return tls.QUICClient(config) } -func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, 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. @@ -55,11 +55,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) } @@ -83,14 +81,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 } } From 2a8dc12a530bfbe4ee9e4d6d54d26ececbfeed79 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 12 Sep 2023 13:12:13 +0700 Subject: [PATCH 061/225] remove duplicate mocks for the Tracer and the ConnectionTracer (#4076) They were introduced to avoid an import loop in the tests in the logging package, but the same can be achieved by having a dedicated package for the tests (logging_test). --- logging/logging_suite_test.go | 2 +- logging/mock_connection_tracer_test.go | 387 ------------------------- logging/mock_tracer_test.go | 73 ----- logging/mockgen.go | 4 - logging/multiplex_test.go | 22 +- logging/packet_header_test.go | 3 +- 6 files changed, 15 insertions(+), 476 deletions(-) delete mode 100644 logging/mock_connection_tracer_test.go delete mode 100644 logging/mock_tracer_test.go delete mode 100644 logging/mockgen.go diff --git a/logging/logging_suite_test.go b/logging/logging_suite_test.go index d808adfec08..e595313de53 100644 --- a/logging/logging_suite_test.go +++ b/logging/logging_suite_test.go @@ -1,4 +1,4 @@ -package logging +package logging_test import ( "testing" diff --git a/logging/mock_connection_tracer_test.go b/logging/mock_connection_tracer_test.go deleted file mode 100644 index 94722509254..00000000000 --- a/logging/mock_connection_tracer_test.go +++ /dev/null @@ -1,387 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/quic-go/quic-go/logging (interfaces: ConnectionTracer) - -// Package logging is a generated GoMock package. -package logging - -import ( - net "net" - reflect "reflect" - time "time" - - protocol "github.com/quic-go/quic-go/internal/protocol" - utils "github.com/quic-go/quic-go/internal/utils" - wire "github.com/quic-go/quic-go/internal/wire" - gomock "go.uber.org/mock/gomock" -) - -// MockConnectionTracer is a mock of ConnectionTracer interface. -type MockConnectionTracer struct { - ctrl *gomock.Controller - recorder *MockConnectionTracerMockRecorder -} - -// 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 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 PacketType, arg1 protocol.ByteCount, arg2 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) -} - -// ECNStateUpdated mocks base method. -func (m *MockConnectionTracer) ECNStateUpdated(arg0 ECNState, arg1 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 interface{}) *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() - 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 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 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 protocol.ECN, arg3 []Frame) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ReceivedLongHeaderPacket", arg0, arg1, arg2, arg3) -} - -// ReceivedLongHeaderPacket indicates an expected call of ReceivedLongHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) ReceivedLongHeaderPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedLongHeaderPacket), arg0, arg1, arg2, arg3) -} - -// 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 *ShortHeader, arg1 protocol.ByteCount, arg2 protocol.ECN, arg3 []Frame) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ReceivedShortHeaderPacket", arg0, arg1, arg2, arg3) -} - -// ReceivedShortHeaderPacket indicates an expected call of ReceivedShortHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) ReceivedShortHeaderPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedShortHeaderPacket), arg0, arg1, arg2, arg3) -} - -// 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 protocol.ECN, arg3 *wire.AckFrame, arg4 []Frame) { - m.ctrl.T.Helper() - 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, arg4 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, arg4) -} - -// SentShortHeaderPacket mocks base method. -func (m *MockConnectionTracer) SentShortHeaderPacket(arg0 *ShortHeader, arg1 protocol.ByteCount, arg2 protocol.ECN, arg3 *wire.AckFrame, arg4 []Frame) { - m.ctrl.T.Helper() - 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, arg4 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, arg4) -} - -// 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 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 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) -} diff --git a/logging/mock_tracer_test.go b/logging/mock_tracer_test.go deleted file mode 100644 index 61eb47ea095..00000000000 --- a/logging/mock_tracer_test.go +++ /dev/null @@ -1,73 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/quic-go/quic-go/logging (interfaces: Tracer) - -// Package logging is a generated GoMock package. -package logging - -import ( - net "net" - reflect "reflect" - - protocol "github.com/quic-go/quic-go/internal/protocol" - wire "github.com/quic-go/quic-go/internal/wire" - gomock "go.uber.org/mock/gomock" -) - -// MockTracer is a mock of Tracer interface. -type MockTracer struct { - ctrl *gomock.Controller - recorder *MockTracerMockRecorder -} - -// 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 PacketType, arg2 protocol.ByteCount, arg3 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 []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) -} diff --git a/logging/mockgen.go b/logging/mockgen.go deleted file mode 100644 index e44c15e1667..00000000000 --- a/logging/mockgen.go +++ /dev/null @@ -1,4 +0,0 @@ -package logging - -//go:generate sh -c "go run go.uber.org/mock/mockgen -package logging -self_package github.com/quic-go/quic-go/logging -destination mock_connection_tracer_test.go github.com/quic-go/quic-go/logging ConnectionTracer" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package logging -self_package github.com/quic-go/quic-go/logging -destination mock_tracer_test.go github.com/quic-go/quic-go/logging Tracer" diff --git a/logging/multiplex_test.go b/logging/multiplex_test.go index 572ced6a427..c0f784ec276 100644 --- a/logging/multiplex_test.go +++ b/logging/multiplex_test.go @@ -1,12 +1,14 @@ -package logging +package logging_test import ( "errors" "net" "time" + 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/wire" + . "github.com/quic-go/quic-go/logging" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -19,20 +21,20 @@ var _ = Describe("Tracing", func() { }) It("returns the raw tracer if only one tracer is passed in", func() { - tr := NewMockTracer(mockCtrl) + tr := mocklogging.NewMockTracer(mockCtrl) tracer := NewMultiplexedTracer(tr) - Expect(tracer).To(BeAssignableToTypeOf(&MockTracer{})) + Expect(tracer).To(BeAssignableToTypeOf(&mocklogging.MockTracer{})) }) Context("tracing events", func() { var ( tracer Tracer - tr1, tr2 *MockTracer + tr1, tr2 *mocklogging.MockTracer ) BeforeEach(func() { - tr1 = NewMockTracer(mockCtrl) - tr2 = NewMockTracer(mockCtrl) + tr1 = mocklogging.NewMockTracer(mockCtrl) + tr2 = mocklogging.NewMockTracer(mockCtrl) tracer = NewMultiplexedTracer(tr1, tr2) }) @@ -67,13 +69,13 @@ var _ = Describe("Tracing", func() { Context("Connection Tracer", func() { var ( tracer ConnectionTracer - tr1 *MockConnectionTracer - tr2 *MockConnectionTracer + tr1 *mocklogging.MockConnectionTracer + tr2 *mocklogging.MockConnectionTracer ) BeforeEach(func() { - tr1 = NewMockConnectionTracer(mockCtrl) - tr2 = NewMockConnectionTracer(mockCtrl) + tr1 = mocklogging.NewMockConnectionTracer(mockCtrl) + tr2 = mocklogging.NewMockConnectionTracer(mockCtrl) tracer = NewMultiplexedConnectionTracer(tr1, tr2) }) diff --git a/logging/packet_header_test.go b/logging/packet_header_test.go index 6df41925bf2..66810a9c940 100644 --- a/logging/packet_header_test.go +++ b/logging/packet_header_test.go @@ -1,8 +1,9 @@ -package logging +package logging_test import ( "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/wire" + . "github.com/quic-go/quic-go/logging" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" From d52e9f35bc58864196226c8d9f7129f14315ee4d Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 12 Sep 2023 13:18:33 +0700 Subject: [PATCH 062/225] ackhandler: detect ECN mangling (#4080) * ackhandler: detect ECN mangling Mangling means that a path is re-marking all ECN-marked packets as CE. * ackhandler: only detect ECN mangling once all testing packets were sent --- internal/ackhandler/ecn.go | 23 +++++++++++++++++------ internal/ackhandler/ecn_test.go | 30 ++++++++++++++++++++++++++++++ logging/types.go | 4 +++- qlog/types.go | 2 ++ qlog/types_test.go | 1 + 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/internal/ackhandler/ecn.go b/internal/ackhandler/ecn.go index ff0dfe652bd..bb8b37f8331 100644 --- a/internal/ackhandler/ecn.go +++ b/internal/ackhandler/ecn.go @@ -218,7 +218,21 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 return false } + // update our counters + e.numAckedECT0 = ect0 + e.numAckedECT1 = ect1 + e.numAckedECNCE = ecnce + if e.state == ecnStateTesting || e.state == ecnStateUnknown { + // Detect mangling (a path remarking all ECN-marked testing packets as CE). + if e.numSentECT0+e.numSentECT1 == e.numAckedECNCE && e.numAckedECNCE >= numECNTestingPackets { + if e.tracer != nil { + e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected) + } + e.state = ecnStateFailed + return false + } + var ackedTestingPacket bool for _, p := range packets { if e.isTestingPacket(p.PacketNumber) { @@ -236,12 +250,9 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 } } - // update our counters - e.numAckedECT0 = ect0 - e.numAckedECT1 = ect1 - e.numAckedECNCE = ecnce - - return newECNCE > 0 + // 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 } func (e *ecnTracker) ecnMarking(pn protocol.PacketNumber) protocol.ECN { diff --git a/internal/ackhandler/ecn_test.go b/internal/ackhandler/ecn_test.go index 74fff094497..984a97a9660 100644 --- a/internal/ackhandler/ecn_test.go +++ b/internal/ackhandler/ecn_test.go @@ -175,6 +175,36 @@ var _ = Describe("ECN tracker", func() { Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(4, 5, 6, 15), 3, 0, 2)).To(BeFalse()) }) + It("detects ECN mangling", 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("declares congestion", func() { sendAllTestingPackets() for i := 10; i < 20; i++ { diff --git a/logging/types.go b/logging/types.go index bfee91c324c..0d79b0a90a4 100644 --- a/logging/types.go +++ b/logging/types.go @@ -121,6 +121,8 @@ const ( ECNFailedLostAllTestingPackets // ECNFailedMoreECNCountsThanSent is emitted when an ACK contains more ECN counts than ECN-marked packets were sent ECNFailedMoreECNCountsThanSent - // ECNFailedTooFewECNCounts is emitted when contains fewer ECT(0) / ECT(1) counts than it acknowledges packets + // 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 ) diff --git a/qlog/types.go b/qlog/types.go index 49b4853a6de..e0c0b24349e 100644 --- a/qlog/types.go +++ b/qlog/types.go @@ -364,6 +364,8 @@ func (e ecnStateTrigger) String() string { return "ACK contains more ECN counts than ECN-marked packets sent" case logging.ECNFailedTooFewECNCounts: return "ACK contains fewer new ECN counts than acknowledged ECN-marked packets" + case logging.ECNFailedManglingDetected: + return "ECN mangling detected" default: return "unknown ECN state trigger" } diff --git a/qlog/types_test.go b/qlog/types_test.go index d08eb739221..d6be3e68a4e 100644 --- a/qlog/types_test.go +++ b/qlog/types_test.go @@ -151,6 +151,7 @@ var _ = Describe("Types", func() { Expect(ecnStateTrigger(logging.ECNFailedLostAllTestingPackets).String()).To(Equal("all ECN testing packets declared lost")) Expect(ecnStateTrigger(logging.ECNFailedMoreECNCountsThanSent).String()).To(Equal("ACK contains more ECN counts than ECN-marked packets sent")) Expect(ecnStateTrigger(logging.ECNFailedTooFewECNCounts).String()).To(Equal("ACK contains fewer new ECN counts than acknowledged ECN-marked packets")) + Expect(ecnStateTrigger(logging.ECNFailedManglingDetected).String()).To(Equal("ECN mangling detected")) Expect(ecnStateTrigger(42).String()).To(Equal("unknown ECN state trigger")) }) }) From 7599f81faf622e3cd72560d425b593c2411ff0a8 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 12 Sep 2023 18:37:12 +0700 Subject: [PATCH 063/225] ci: clean up Codecov ignore list (#4081) --- codecov.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/codecov.yml b/codecov.yml index 69435150974..0b95a1032b5 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,17 +1,9 @@ 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/ From 37a3c417a7c56167f9eeff462ddb1ed4258025b8 Mon Sep 17 00:00:00 2001 From: Benedikt Spies Date: Thu, 14 Sep 2023 08:55:49 +0200 Subject: [PATCH 064/225] expose GSO usage through ConnectionState (#4083) --- connection.go | 1 + interface.go | 2 ++ 2 files changed, 3 insertions(+) diff --git a/connection.go b/connection.go index 10a36ba005e..d6cc886d941 100644 --- a/connection.go +++ b/connection.go @@ -673,6 +673,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 } diff --git a/interface.go b/interface.go index 8faf0eb8e27..746ad12e201 100644 --- a/interface.go +++ b/interface.go @@ -345,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 } From 862e64c7b928cec7a37f7c383e2cfeb10efd86fa Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 15 Sep 2023 18:33:57 +0700 Subject: [PATCH 065/225] add a Transport config option for the key used to encrypt tokens (#4066) * add a Transport config option for the key used to encrypt tokens * handshake: remove unused error return values --- connection_test.go | 3 +- fuzzing/tokens/fuzz.go | 14 +++--- interface.go | 3 ++ internal/handshake/token_generator.go | 13 ++--- internal/handshake/token_generator_test.go | 6 +-- internal/handshake/token_protector.go | 33 +++++-------- internal/handshake/token_protector_test.go | 55 +++++++++++----------- server.go | 12 ++--- transport.go | 20 ++++++-- 9 files changed, 76 insertions(+), 83 deletions(-) diff --git a/connection_test.go b/connection_test.go index 67b02443b7d..44564f84325 100644 --- a/connection_test.go +++ b/connection_test.go @@ -100,8 +100,7 @@ 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()) + tokenGenerator := handshake.NewTokenGenerator([32]byte{0xa, 0xb, 0xc}) tracer = mocklogging.NewMockConnectionTracer(mockCtrl) tracer.EXPECT().NegotiatedVersion(gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1) tracer.EXPECT().SentTransportParameters(gomock.Any()) diff --git a/fuzzing/tokens/fuzz.go b/fuzzing/tokens/fuzz.go index ea261fb6d77..d0043ead0d4 100644 --- a/fuzzing/tokens/fuzz.go +++ b/fuzzing/tokens/fuzz.go @@ -2,24 +2,22 @@ package tokens import ( "encoding/binary" - "math/rand" "net" "time" + "github.com/quic-go/quic-go" "github.com/quic-go/quic-go/internal/handshake" "github.com/quic-go/quic-go/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 } diff --git a/interface.go b/interface.go index 746ad12e201..f5ee28d8d72 100644 --- a/interface.go +++ b/interface.go @@ -212,6 +212,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. diff --git a/internal/handshake/token_generator.go b/internal/handshake/token_generator.go index e5e90bb3ba8..2d91e6b2597 100644 --- a/internal/handshake/token_generator.go +++ b/internal/handshake/token_generator.go @@ -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 diff --git a/internal/handshake/token_generator_test.go b/internal/handshake/token_generator_test.go index 870ba3edcc6..7abc53b45e7 100644 --- a/internal/handshake/token_generator_test.go +++ b/internal/handshake/token_generator_test.go @@ -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() { diff --git a/internal/handshake/token_protector.go b/internal/handshake/token_protector.go index 650f230b20d..6dcf7f7736d 100644 --- a/internal/handshake/token_protector.go +++ b/internal/handshake/token_protector.go @@ -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 diff --git a/internal/handshake/token_protector_test.go b/internal/handshake/token_protector_test.go index 03cd5320c2c..74eb1f0cdbe 100644 --- a/internal/handshake/token_protector_test.go +++ b/internal/handshake/token_protector_test.go @@ -7,55 +7,54 @@ 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{}) + It("encodes and decodes tokens", func() { + token, err := tp.NewToken([]byte("foobar")) Expect(err).ToNot(HaveOccurred()) - tp2, err := newTokenProtector(&zeroReader{}) + Expect(token).ToNot(ContainSubstring("foobar")) + decoded, err := tp.DecodeToken(token) Expect(err).ToNot(HaveOccurred()) + Expect(decoded).To(Equal([]byte("foobar"))) + }) + + 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()) - 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")) + _, err = tp1.DecodeToken(t1) Expect(err).ToNot(HaveOccurred()) - Expect(token).ToNot(ContainSubstring("foobar")) - decoded, err := tp.DecodeToken(token) + _, 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()) - Expect(decoded).To(Equal([]byte("foobar"))) + _, err = tp3.DecodeToken(t2) + Expect(err).To(HaveOccurred()) }) - It("fails deconding invalid tokens", func() { + 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")) }) diff --git a/server.go b/server.go index d41c6465ac4..671ae9714cf 100644 --- a/server.go +++ b/server.go @@ -2,7 +2,6 @@ package quic import ( "context" - "crypto/rand" "crypto/tls" "errors" "fmt" @@ -227,18 +226,15 @@ func newServer( config *Config, tracer logging.Tracer, onClose func(), + tokenGeneratorKey TokenGeneratorKey, disableVersionNegotiation bool, acceptEarly bool, -) (*baseServer, error) { - tokenGenerator, err := handshake.NewTokenGenerator(rand.Reader) - if err != nil { - return nil, err - } +) *baseServer { s := &baseServer{ conn: conn, tlsConf: tlsConf, config: config, - tokenGenerator: tokenGenerator, + tokenGenerator: handshake.NewTokenGenerator(tokenGeneratorKey), connIDGenerator: connIDGenerator, connHandler: connHandler, connQueue: make(chan quicConn), @@ -260,7 +256,7 @@ func newServer( go s.run() go s.runSendQueue() s.logger.Debugf("Listening for %s connections on %s", conn.LocalAddr().Network(), conn.LocalAddr().String()) - return s, nil + return s } func (s *baseServer) run() { diff --git a/transport.go b/transport.go index c021be77d7a..b585532962b 100644 --- a/transport.go +++ b/transport.go @@ -57,6 +57,12 @@ type Transport struct { // See section 10.3 of RFC 9000 for details. StatelessResetKey *StatelessResetKey + // The TokenGeneratorKey is used to encrypt session resumption tokens. + // If no key is configured, a random key will be generated. + // If multiple servers are authoritative for the same domain, they should use the same key, + // see section 8.1.3 of RFC 9000 for details. + TokenGeneratorKey *TokenGeneratorKey + // 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 clients. @@ -136,7 +142,7 @@ func (t *Transport) createServer(tlsConf *tls.Config, conf *Config, allow0RTT bo if err := t.init(false); err != nil { return nil, err } - s, err := newServer( + s := newServer( t.conn, t.handlerMap, t.connIDGenerator, @@ -144,12 +150,10 @@ func (t *Transport) createServer(tlsConf *tls.Config, conf *Config, allow0RTT bo conf, t.Tracer, t.closeServer, + *t.TokenGeneratorKey, t.DisableVersionNegotiationPackets, allow0RTT, ) - if err != nil { - return nil, err - } t.server = s return s, nil } @@ -203,6 +207,14 @@ func (t *Transport) init(allowZeroLengthConnIDs bool) error { t.closeQueue = make(chan closePacket, 4) t.statelessResetQueue = make(chan receivedPacket, 4) + if t.TokenGeneratorKey == nil { + var key TokenGeneratorKey + if _, err := rand.Read(key[:]); err != nil { + t.initErr = err + return + } + t.TokenGeneratorKey = &key + } if t.ConnectionIDGenerator != nil { t.connIDGenerator = t.ConnectionIDGenerator From c1ce4a8e9209fca2a16ab362ab93a2e94eec1c27 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 15 Sep 2023 18:35:09 +0700 Subject: [PATCH 066/225] http09: increase the startup timeout in tests (#4071) --- interop/http09/http_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interop/http09/http_test.go b/interop/http09/http_test.go index f2d48994872..03f39263853 100644 --- a/interop/http09/http_test.go +++ b/interop/http09/http_test.go @@ -7,6 +7,7 @@ import ( "net" "net/http" "net/http/httptest" + "time" "github.com/quic-go/quic-go" "github.com/quic-go/quic-go/internal/testdata" @@ -42,7 +43,7 @@ var _ = Describe("HTTP 0.9 integration tests", func() { defer server.mutex.Unlock() ln = server.listener return server.listener - }).ShouldNot(BeNil()) + }, 5*time.Second).ShouldNot(BeNil()) saddr = ln.Addr() saddr.(*net.UDPAddr).IP = net.IP{127, 0, 0, 1} }) From 5b25d8b5be05f6e81c7db4934f0276ba924e6c05 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 15 Sep 2023 18:35:53 +0700 Subject: [PATCH 067/225] ci: fail if any Go files contain an ignore directive (#4055) --- .github/workflows/lint.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1c74c53b28f..ee56f6e4303 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,6 +11,13 @@ jobs: go-version: "1.20.x" - name: Check that no non-test files import Ginkgo or Gomega run: .github/workflows/no_ginkgo.sh + - name: Check for //go:build ignore in .go files + run: | + IGNORED_FILES=$(grep -rl '//go:build ignore' . --include='*.go') || true + if [ -n "$IGNORED_FILES" ]; then + echo "::error::Found ignored Go files: $IGNORED_FILES" + exit 1 + fi - name: Check that go.mod is tidied run: | cp go.mod go.mod.orig From 22eac50276dd6e2d794e1dff72b3f0e25b1f43ab Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 15 Sep 2023 23:56:20 +0700 Subject: [PATCH 068/225] ci: combine the go generate workflow with the linting workflow (#4053) * ci: combine the go generate workflow with the linting workflow * reorder --- .github/workflows/go-generate.yml | 13 ------------- .github/workflows/lint.yml | 5 +++++ 2 files changed, 5 insertions(+), 13 deletions(-) delete mode 100644 .github/workflows/go-generate.yml diff --git a/.github/workflows/go-generate.yml b/.github/workflows/go-generate.yml deleted file mode 100644 index 4add84e3a7b..00000000000 --- a/.github/workflows/go-generate.yml +++ /dev/null @@ -1,13 +0,0 @@ -on: [push, pull_request] -jobs: - gogenerate: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 - with: - go-version: "1.20.x" - - name: Install dependencies - run: go build - - name: Run code generators - run: .github/workflows/go-generate.sh diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ee56f6e4303..1d56486144e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,13 +19,18 @@ jobs: exit 1 fi - name: Check that go.mod is tidied + if: success() || failure() # run this step even if the previous one failed run: | cp go.mod go.mod.orig cp go.sum go.sum.orig go mod tidy diff go.mod go.mod.orig diff go.sum go.sum.orig + - name: Run code generators + if: success() || failure() # run this step even if the previous one failed + run: .github/workflows/go-generate.sh - name: Check that go mod vendor works + if: success() || failure() # run this step even if the previous one failed run: | cd integrationtests/gomodvendor go mod vendor From ab1c1be9a9d07920b55418fbf1f37ffa2b3ff9a2 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 15 Sep 2023 23:57:13 +0700 Subject: [PATCH 069/225] basic ClusterFuzzLite integration (#4034) --- .clusterfuzzlite/Dockerfile | 21 ++++++++++ .clusterfuzzlite/build.sh | 9 +++++ .clusterfuzzlite/project.yaml | 1 + .github/workflows/clusterfuzz-lite-pr.yml | 48 +++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 .clusterfuzzlite/Dockerfile create mode 100755 .clusterfuzzlite/build.sh create mode 100644 .clusterfuzzlite/project.yaml create mode 100644 .github/workflows/clusterfuzz-lite-pr.yml diff --git a/.clusterfuzzlite/Dockerfile b/.clusterfuzzlite/Dockerfile new file mode 100644 index 00000000000..b57da8caa99 --- /dev/null +++ b/.clusterfuzzlite/Dockerfile @@ -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/ diff --git a/.clusterfuzzlite/build.sh b/.clusterfuzzlite/build.sh new file mode 100755 index 00000000000..92a24169ee0 --- /dev/null +++ b/.clusterfuzzlite/build.sh @@ -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 diff --git a/.clusterfuzzlite/project.yaml b/.clusterfuzzlite/project.yaml new file mode 100644 index 00000000000..4f2ee4d9733 --- /dev/null +++ b/.clusterfuzzlite/project.yaml @@ -0,0 +1 @@ +language: go diff --git a/.github/workflows/clusterfuzz-lite-pr.yml b/.github/workflows/clusterfuzz-lite-pr.yml new file mode 100644 index 00000000000..c902db19d03 --- /dev/null +++ b/.github/workflows/clusterfuzz-lite-pr.yml @@ -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". From d8cc4cb3ef5bff86cdde8c8c5b0a24c8e9180e91 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 16 Sep 2023 18:57:50 +0700 Subject: [PATCH 070/225] http3: introduce an HTTP/3 error type (#4039) * http3: introduce an HTTP/3 error type * http3: use a pointer receiver for the Error --- http3/body.go | 5 +-- http3/client.go | 4 +-- http3/error.go | 58 ++++++++++++++++++++++++++++++ http3/error_codes.go | 10 +++++- http3/error_test.go | 41 +++++++++++++++++++++ http3/response_writer.go | 7 ++-- integrationtests/self/http_test.go | 12 ++++--- 7 files changed, 125 insertions(+), 12 deletions(-) create mode 100644 http3/error.go create mode 100644 http3/error_test.go diff --git a/http3/body.go b/http3/body.go index 63ff4366451..dc168e9e839 100644 --- a/http3/body.go +++ b/http3/body.go @@ -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() { diff --git a/http3/client.go b/http3/client.go index cc2400e2c0d..8aca4807868 100644 --- a/http3/client.go +++ b/http3/client.go @@ -318,13 +318,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. diff --git a/http3/error.go b/http3/error.go new file mode 100644 index 00000000000..b96ebeec093 --- /dev/null +++ b/http3/error.go @@ -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 +} diff --git a/http3/error_codes.go b/http3/error_codes.go index e8428d0a5b5..ae646586a71 100644 --- a/http3/error_codes.go +++ b/http3/error_codes.go @@ -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 "" } } diff --git a/http3/error_test.go b/http3/error_test.go new file mode 100644 index 00000000000..7156712857d --- /dev/null +++ b/http3/error_test.go @@ -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)")) + }) +}) diff --git a/http3/response_writer.go b/http3/response_writer.go index 90a30497ae6..0d93147827d 100644 --- a/http3/response_writer.go +++ b/http3/response_writer.go @@ -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 } diff --git a/integrationtests/self/http_test.go b/integrationtests/self/http_test.go index a1067070275..ac16ffa5131 100644 --- a/integrationtests/self/http_test.go +++ b/integrationtests/self/http_test.go @@ -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() { From 9b8219657899fd188678f0ca6c5751aa701faa43 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 16 Sep 2023 18:58:51 +0700 Subject: [PATCH 071/225] make the logging.Tracer and logging.ConnectionTracer a struct (#4082) --- client.go | 4 +- client_test.go | 21 +- codecov.yml | 1 - config_test.go | 2 +- connection.go | 82 +-- connection_test.go | 10 +- example/client/main.go | 2 +- example/main.go | 2 +- integrationtests/self/key_update_test.go | 23 +- integrationtests/self/packetization_test.go | 8 +- integrationtests/self/self_suite_test.go | 67 +-- integrationtests/self/timeout_test.go | 6 +- integrationtests/self/tracer_test.go | 12 +- integrationtests/self/zero_rtt_oldgo_test.go | 56 +- integrationtests/self/zero_rtt_test.go | 68 ++- integrationtests/tools/qlog.go | 4 +- .../versionnegotiation/handshake_test.go | 86 ++-- .../versionnegotiation_suite_test.go | 2 +- interface.go | 2 +- internal/ackhandler/ackhandler.go | 2 +- internal/ackhandler/ecn.go | 24 +- internal/ackhandler/ecn_test.go | 5 +- internal/ackhandler/sent_packet_handler.go | 46 +- internal/congestion/cubic_sender.go | 10 +- internal/handshake/crypto_setup.go | 22 +- internal/handshake/updatable_aead.go | 12 +- internal/handshake/updatable_aead_test.go | 6 +- internal/mocks/logging/connection_tracer.go | 480 ++++-------------- .../logging/internal/connection_tracer.go | 388 ++++++++++++++ internal/mocks/logging/internal/tracer.go | 74 +++ internal/mocks/logging/mockgen.go | 51 ++ internal/mocks/logging/tracer.go | 87 +--- internal/mocks/mockgen.go | 28 +- interop/utils/logging.go | 2 +- logging/connection_tracer.go | 255 ++++++++++ logging/interface.go | 44 -- logging/multiplex.go | 232 --------- logging/multiplex_test.go | 33 +- logging/null_tracer.go | 63 --- logging/tracer.go | 43 ++ qlog/qlog.go | 85 +++- qlog/qlog_test.go | 2 +- server.go | 48 +- server_test.go | 34 +- transport.go | 6 +- transport_test.go | 10 +- 46 files changed, 1390 insertions(+), 1160 deletions(-) create mode 100644 internal/mocks/logging/internal/connection_tracer.go create mode 100644 internal/mocks/logging/internal/tracer.go create mode 100644 internal/mocks/logging/mockgen.go create mode 100644 logging/connection_tracer.go delete mode 100644 logging/multiplex.go delete mode 100644 logging/null_tracer.go create mode 100644 logging/tracer.go diff --git a/client.go b/client.go index 61cd7526526..670e7a7c678 100644 --- a/client.go +++ b/client.go @@ -34,7 +34,7 @@ type client struct { conn quicConn - tracer logging.ConnectionTracer + tracer *logging.ConnectionTracer tracingID uint64 logger utils.Logger } @@ -153,7 +153,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) } if err := c.dial(ctx); err != nil { diff --git a/client_test.go b/client_test.go index e908b82f139..3fa5fb5a22b 100644 --- a/client_test.go +++ b/client_test.go @@ -43,7 +43,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, @@ -54,10 +54,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}, } @@ -70,7 +71,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 @@ -121,7 +122,7 @@ var _ = Describe("Client", func() { _ protocol.PacketNumber, enable0RTT bool, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -158,7 +159,7 @@ var _ = Describe("Client", func() { _ protocol.PacketNumber, enable0RTT bool, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -195,7 +196,7 @@ var _ = Describe("Client", func() { _ protocol.PacketNumber, _ bool, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -280,7 +281,7 @@ var _ = Describe("Client", func() { _ protocol.PacketNumber, _ bool, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, versionP protocol.VersionNumber, @@ -323,7 +324,7 @@ var _ = Describe("Client", func() { pn protocol.PacketNumber, _ bool, hasNegotiatedVersion bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, versionP protocol.VersionNumber, diff --git a/codecov.yml b/codecov.yml index 0b95a1032b5..a24c7a15e0d 100644 --- a/codecov.yml +++ b/codecov.yml @@ -5,7 +5,6 @@ coverage: - interop/ - internal/handshake/cipher_suite.go - internal/utils/linkedlist/linkedlist.go - - logging/null_tracer.go - fuzzing/ - metrics/ status: diff --git a/config_test.go b/config_test.go index 9cb665a30b8..c5701608fea 100644 --- a/config_test.go +++ b/config_test.go @@ -125,7 +125,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 }, diff --git a/connection.go b/connection.go index d6cc886d941..09b522a9eb7 100644 --- a/connection.go +++ b/connection.go @@ -208,7 +208,7 @@ type connection struct { connState ConnectionState logID string - tracer logging.ConnectionTracer + tracer *logging.ConnectionTracer logger utils.Logger } @@ -232,7 +232,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, @@ -311,7 +311,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 +345,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, @@ -418,7 +418,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( @@ -642,8 +642,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() @@ -801,14 +803,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) @@ -819,7 +821,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 @@ -832,7 +834,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) @@ -891,14 +893,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{ @@ -937,7 +939,7 @@ func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header) // 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) @@ -945,7 +947,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 @@ -964,7 +966,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 @@ -980,7 +982,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()) @@ -996,7 +998,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) @@ -1004,7 +1006,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) @@ -1019,14 +1021,14 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P 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.") @@ -1034,7 +1036,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime ti } 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.") @@ -1049,7 +1051,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime ti 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.") @@ -1061,7 +1063,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime ti (&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 @@ -1082,7 +1084,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime ti 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 @@ -1090,7 +1092,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) @@ -1099,7 +1101,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. @@ -1109,7 +1111,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) @@ -1121,7 +1123,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) } @@ -1141,7 +1143,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: @@ -1168,7 +1170,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(), @@ -1192,7 +1194,7 @@ 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, ecn, frames) } @@ -1340,7 +1342,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) } } @@ -1620,7 +1622,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) } @@ -1647,7 +1649,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) @@ -1682,7 +1684,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 { @@ -2134,7 +2136,7 @@ func (s *connection) logLongHeaderPacket(p *longHeaderPacket, ecn protocol.ECN) } // 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)) @@ -2180,7 +2182,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)) @@ -2302,14 +2304,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) diff --git a/connection_test.go b/connection_test.go index 44564f84325..e2cca32e08c 100644 --- a/connection_test.go +++ b/connection_test.go @@ -101,7 +101,8 @@ var _ = Describe("Connection", func() { mconn.EXPECT().RemoteAddr().Return(remoteAddr).AnyTimes() mconn.EXPECT().LocalAddr().Return(localAddr).AnyTimes() tokenGenerator := handshake.NewTokenGenerator([32]byte{0xa, 0xb, 0xc}) - 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() @@ -120,7 +121,7 @@ var _ = Describe("Connection", func() { &tls.Config{}, tokenGenerator, false, - tracer, + tr, 1234, utils.DefaultLogger, protocol.Version1, @@ -2540,7 +2541,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() @@ -2556,7 +2558,7 @@ var _ = Describe("Client Connection", func() { 42, // initial packet number false, false, - tracer, + tr, 1234, utils.DefaultLogger, protocol.Version1, diff --git a/example/client/main.go b/example/client/main.go index 83f810fd1a7..5b86faa37c8 100644 --- a/example/client/main.go +++ b/example/client/main.go @@ -58,7 +58,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 { diff --git a/example/main.go b/example/main.go index 058144050e8..c2fb574d49d 100644 --- a/example/main.go +++ b/example/main.go @@ -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 { diff --git a/integrationtests/self/key_update_test.go b/integrationtests/self/key_update_test.go index 7975a77bb5a..3704f96eb82 100644 --- a/integrationtests/self/key_update_test.go +++ b/integrationtests/self/key_update_test.go @@ -38,18 +38,13 @@ func countKeyPhases() (sent, received int) { return } -type keyUpdateConnTracer struct { - logging.NullConnectionTracer -} - -var _ logging.ConnectionTracer = &keyUpdateConnTracer{} - -func (t *keyUpdateConnTracer) SentShortHeaderPacket(hdr *logging.ShortHeader, _ logging.ByteCount, _ logging.ECN, _ *logging.AckFrame, _ []logging.Frame) { - sentHeaders = append(sentHeaders, hdr) -} - -func (t *keyUpdateConnTracer) ReceivedShortHeaderPacket(hdr *logging.ShortHeader, _ logging.ByteCount, _ logging.ECN, _ []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() { @@ -77,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()) diff --git a/integrationtests/self/packetization_test.go b/integrationtests/self/packetization_test.go index 740956c5492..8c59bc0b1a1 100644 --- a/integrationtests/self/packetization_test.go +++ b/integrationtests/self/packetization_test.go @@ -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( diff --git a/integrationtests/self/self_suite_test.go b/integrationtests/self/self_suite_test.go index 6396d3a7aac..582575f56e8 100644 --- a/integrationtests/self/self_suite_test.go +++ b/integrationtests/self/self_suite_test.go @@ -86,7 +86,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 @@ -177,10 +177,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), @@ -242,8 +248,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 { @@ -258,51 +264,46 @@ type shortHeaderPacket struct { frames []logging.Frame } -type packetTracer struct { - logging.NullConnectionTracer +type packetCounter struct { closed chan struct{} sentShortHdr, rcvdShortHdr []shortHeaderPacket rcvdLongHdr []packet } -var _ logging.ConnectionTracer = &packetTracer{} - -func newPacketTracer() *packetTracer { - return &packetTracer{closed: make(chan struct{})} -} - -func (t *packetTracer) ReceivedLongHeaderPacket(hdr *logging.ExtendedHeader, _ logging.ByteCount, _ logging.ECN, 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, _ logging.ECN, 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, _ logging.ECN, 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") diff --git a/integrationtests/self/timeout_test.go b/integrationtests/self/timeout_test.go index 47569b77e74..ddd0b973846 100644 --- a/integrationtests/self/timeout_test.go +++ b/integrationtests/self/timeout_test.go @@ -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, diff --git a/integrationtests/self/tracer_test.go b/integrationtests/self/tracer_test.go index 3bfae3c6b8a..5179646e99a 100644 --- a/integrationtests/self/tracer_test.go +++ b/integrationtests/self/tracer_test.go @@ -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) diff --git a/integrationtests/self/zero_rtt_oldgo_test.go b/integrationtests/self/zero_rtt_oldgo_test.go index 3e9277b937a..eb2302d3d85 100644 --- a/integrationtests/self/zero_rtt_oldgo_test.go +++ b/integrationtests/self/zero_rtt_oldgo_test.go @@ -202,7 +202,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 { @@ -219,7 +219,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, @@ -244,7 +244,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++ @@ -260,7 +260,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))) }) @@ -273,7 +273,7 @@ var _ = Describe("0-RTT", func() { zeroRTTData := GeneratePRData(5 << 10) oneRTTData := PRData - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -330,7 +330,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 } @@ -355,7 +355,7 @@ var _ = Describe("0-RTT", func() { tlsConf, clientConf := dialAndReceiveSessionTicket(nil) - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -406,7 +406,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() { @@ -430,7 +430,7 @@ var _ = Describe("0-RTT", func() { return } - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -480,7 +480,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))) }) @@ -491,14 +491,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()) @@ -536,7 +534,7 @@ var _ = Describe("0-RTT", func() { MaxIncomingStreams: maxStreams, })) - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -556,7 +554,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() { @@ -565,7 +563,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, @@ -585,14 +583,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, @@ -612,12 +610,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) @@ -669,7 +667,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 { @@ -695,7 +693,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, @@ -764,14 +762,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, @@ -796,8 +794,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))) }) @@ -807,7 +805,7 @@ var _ = Describe("0-RTT", func() { EnableDatagrams: true, })) - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -856,7 +854,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(zeroRTTPackets).To(HaveLen(1)) }) @@ -865,7 +863,7 @@ var _ = Describe("0-RTT", func() { EnableDatagrams: true, })) - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -911,6 +909,6 @@ 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()) }) }) diff --git a/integrationtests/self/zero_rtt_test.go b/integrationtests/self/zero_rtt_test.go index c9bdeff6990..1f750d3ac25 100644 --- a/integrationtests/self/zero_rtt_test.go +++ b/integrationtests/self/zero_rtt_test.go @@ -232,7 +232,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 { @@ -251,7 +251,7 @@ var _ = Describe("0-RTT", func() { clientTLSConf := getTLSClientConfig() dialAndReceiveSessionTicket(tlsConf, nil, clientTLSConf) - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -276,7 +276,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++ @@ -292,7 +292,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))) }) @@ -307,7 +307,7 @@ var _ = Describe("0-RTT", func() { zeroRTTData := GeneratePRData(5 << 10) oneRTTData := PRData - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -364,7 +364,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 } @@ -391,7 +391,7 @@ var _ = Describe("0-RTT", func() { clientConf := getTLSClientConfig() dialAndReceiveSessionTicket(tlsConf, nil, clientConf) - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -442,7 +442,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() { @@ -468,7 +468,7 @@ var _ = Describe("0-RTT", func() { return } - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -518,7 +518,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))) }) @@ -531,14 +531,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()) @@ -578,7 +576,7 @@ var _ = Describe("0-RTT", func() { MaxIncomingStreams: maxStreams, }), clientConf) - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -599,7 +597,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() { @@ -612,7 +610,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, @@ -632,7 +630,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() { @@ -641,7 +639,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, @@ -661,12 +659,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() @@ -720,7 +718,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 { @@ -748,7 +746,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, @@ -817,7 +815,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()) }) } @@ -826,7 +824,7 @@ var _ = Describe("0-RTT", func() { clientConf := getTLSClientConfig() dialAndReceiveSessionTicket(tlsConf, nil, clientConf) - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -851,8 +849,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))) }) @@ -878,14 +876,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() @@ -916,14 +910,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() @@ -946,7 +936,7 @@ var _ = Describe("0-RTT", func() { EnableDatagrams: true, }), clientTLSConf) - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -994,7 +984,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(zeroRTTPackets).To(HaveLen(1)) }) @@ -1005,7 +995,7 @@ var _ = Describe("0-RTT", func() { EnableDatagrams: true, }), clientTLSConf) - tracer := newPacketTracer() + counter, tracer := newPacketTracer() ln, err := quic.ListenAddrEarly( "localhost:0", tlsConf, @@ -1051,6 +1041,6 @@ 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()) }) }) diff --git a/integrationtests/tools/qlog.go b/integrationtests/tools/qlog.go index 352e0a613d3..ea37456e8b1 100644 --- a/integrationtests/tools/qlog.go +++ b/integrationtests/tools/qlog.go @@ -14,8 +14,8 @@ import ( "github.com/quic-go/quic-go/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" diff --git a/integrationtests/versionnegotiation/handshake_test.go b/integrationtests/versionnegotiation/handshake_test.go index a079f6e12d2..eefcd8e7cd3 100644 --- a/integrationtests/versionnegotiation/handshake_test.go +++ b/integrationtests/versionnegotiation/handshake_test.go @@ -21,29 +21,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() { @@ -86,54 +86,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, // 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 }, }), @@ -141,22 +141,22 @@ 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 := &versionNegotiationTracer{} + _, 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 } conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}) @@ -170,14 +170,14 @@ var _ = Describe("Handshake tests", func() { defer ln.Close() clientVersions := []protocol.VersionNumber{7, 8, 9, protocol.SupportedVersions[0], 10} - clientTracer := &versionNegotiationTracer{} + 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 { + Tracer: func(context.Context, logging.Perspective, quic.ConnectionID) *logging.ConnectionTracer { return clientTracer }, HandshakeIdleTimeout: 100 * time.Millisecond, @@ -187,7 +187,7 @@ var _ = Describe("Handshake tests", func() { var nerr net.Error Expect(errors.As(err, &nerr)).To(BeTrue()) Expect(nerr.Timeout()).To(BeTrue()) - Expect(clientTracer.receivedVersionNegotiation).To(BeFalse()) + Expect(clientResult.receivedVersionNegotiation).To(BeFalse()) }) } }) diff --git a/integrationtests/versionnegotiation/versionnegotiation_suite_test.go b/integrationtests/versionnegotiation/versionnegotiation_suite_test.go index a01ac1f8a58..150181f257c 100644 --- a/integrationtests/versionnegotiation/versionnegotiation_suite_test.go +++ b/integrationtests/versionnegotiation/versionnegotiation_suite_test.go @@ -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), diff --git a/interface.go b/interface.go index f5ee28d8d72..c7e53bdc962 100644 --- a/interface.go +++ b/interface.go @@ -328,7 +328,7 @@ type Config struct { 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 { diff --git a/internal/ackhandler/ackhandler.go b/internal/ackhandler/ackhandler.go index 036ed5ead90..cb28582a337 100644 --- a/internal/ackhandler/ackhandler.go +++ b/internal/ackhandler/ackhandler.go @@ -16,7 +16,7 @@ func NewAckHandler( clientAddressValidated bool, enableECN bool, pers protocol.Perspective, - tracer logging.ConnectionTracer, + tracer *logging.ConnectionTracer, logger utils.Logger, ) (SentPacketHandler, ReceivedPacketHandler) { sph := newSentPacketHandler(initialPacketNumber, initialMaxDatagramSize, rttStats, clientAddressValidated, enableECN, pers, tracer, logger) diff --git a/internal/ackhandler/ecn.go b/internal/ackhandler/ecn.go index bb8b37f8331..43cc3dd6e10 100644 --- a/internal/ackhandler/ecn.go +++ b/internal/ackhandler/ecn.go @@ -45,13 +45,13 @@ type ecnTracker struct { numSentECT0, numSentECT1 int64 numAckedECT0, numAckedECT1, numAckedECNCE int64 - tracer logging.ConnectionTracer + tracer *logging.ConnectionTracer logger utils.Logger } var _ ecnHandler = &ecnTracker{} -func newECNTracker(logger utils.Logger, tracer logging.ConnectionTracer) *ecnTracker { +func newECNTracker(logger utils.Logger, tracer *logging.ConnectionTracer) *ecnTracker { return &ecnTracker{ firstTestingPacket: protocol.InvalidPacketNumber, lastTestingPacket: protocol.InvalidPacketNumber, @@ -92,7 +92,7 @@ func (e *ecnTracker) SentPacket(pn protocol.PacketNumber, ecn protocol.ECN) { e.firstTestingPacket = pn } if e.numSentECT0+e.numSentECT1 >= numECNTestingPackets { - if e.tracer != nil { + if e.tracer != nil && e.tracer.ECNStateUpdated != nil { e.tracer.ECNStateUpdated(logging.ECNStateUnknown, logging.ECNTriggerNoTrigger) } e.state = ecnStateUnknown @@ -103,7 +103,7 @@ func (e *ecnTracker) SentPacket(pn protocol.PacketNumber, ecn protocol.ECN) { func (e *ecnTracker) Mode() protocol.ECN { switch e.state { case ecnStateInitial: - if e.tracer != nil { + if e.tracer != nil && e.tracer.ECNStateUpdated != nil { e.tracer.ECNStateUpdated(logging.ECNStateTesting, logging.ECNTriggerNoTrigger) } e.state = ecnStateTesting @@ -127,7 +127,7 @@ func (e *ecnTracker) LostPacket(pn protocol.PacketNumber) { e.numLostTesting++ if e.numLostTesting >= e.numSentTesting { e.logger.Debugf("Disabling ECN. All testing packets were lost.") - if e.tracer != nil { + if e.tracer != nil && e.tracer.ECNStateUpdated != nil { e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedLostAllTestingPackets) } e.state = ecnStateFailed @@ -146,7 +146,7 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // 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 { + if e.tracer != nil && e.tracer.ECNStateUpdated != nil { e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedMoreECNCountsThanSent) } e.state = ecnStateFailed @@ -172,7 +172,7 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // * 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 { + if e.tracer != nil && e.tracer.ECNStateUpdated != nil { e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedNoECNCounts) } e.state = ecnStateFailed @@ -189,7 +189,7 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // 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 { + if e.tracer != nil && e.tracer.ECNStateUpdated != nil { e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedDecreasedECNCounts) } e.state = ecnStateFailed @@ -201,7 +201,7 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // 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 { + if e.tracer != nil && e.tracer.ECNStateUpdated != nil { e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedTooFewECNCounts) } e.state = ecnStateFailed @@ -211,7 +211,7 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // 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 { + if e.tracer != nil && e.tracer.ECNStateUpdated != nil { e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedTooFewECNCounts) } e.state = ecnStateFailed @@ -226,7 +226,7 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 if e.state == ecnStateTesting || e.state == ecnStateUnknown { // Detect mangling (a path remarking all ECN-marked testing packets as CE). if e.numSentECT0+e.numSentECT1 == e.numAckedECNCE && e.numAckedECNCE >= numECNTestingPackets { - if e.tracer != nil { + if e.tracer != nil && e.tracer.ECNStateUpdated != nil { e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected) } e.state = ecnStateFailed @@ -243,7 +243,7 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // 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 { + if e.tracer != nil && e.tracer.ECNStateUpdated != nil { e.tracer.ECNStateUpdated(logging.ECNStateCapable, logging.ECNTriggerNoTrigger) } e.state = ecnStateCapable diff --git a/internal/ackhandler/ecn_test.go b/internal/ackhandler/ecn_test.go index 984a97a9660..26d54eed5f3 100644 --- a/internal/ackhandler/ecn_test.go +++ b/internal/ackhandler/ecn_test.go @@ -23,8 +23,9 @@ var _ = Describe("ECN tracker", func() { } BeforeEach(func() { - tracer = mocklogging.NewMockConnectionTracer(mockCtrl) - ecnTracker = newECNTracker(utils.DefaultLogger, tracer) + var tr *logging.ConnectionTracer + tr, tracer = mocklogging.NewMockConnectionTracer(mockCtrl) + ecnTracker = newECNTracker(utils.DefaultLogger, tr) }) It("sends exactly 10 testing packets", func() { diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index b498ce4b77d..c8265a78d93 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -97,7 +97,7 @@ type sentPacketHandler struct { perspective protocol.Perspective - tracer logging.ConnectionTracer + tracer *logging.ConnectionTracer logger utils.Logger } @@ -115,7 +115,7 @@ func newSentPacketHandler( clientAddressValidated bool, enableECN bool, pers protocol.Perspective, - tracer logging.ConnectionTracer, + tracer *logging.ConnectionTracer, logger utils.Logger, ) *sentPacketHandler { congestion := congestion.NewCubicSender( @@ -196,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 @@ -286,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() @@ -376,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()) } @@ -462,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) } } @@ -555,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 @@ -566,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() } } @@ -578,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() } } @@ -591,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) } } @@ -629,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) } } @@ -639,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) } } @@ -676,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 @@ -713,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. @@ -890,7 +894,7 @@ func (h *sentPacketHandler) ResetForRetry(now time.Time) error { 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()) } } @@ -899,8 +903,10 @@ func (h *sentPacketHandler) ResetForRetry(now time.Time) 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() } } diff --git a/internal/congestion/cubic_sender.go b/internal/congestion/cubic_sender.go index 10eb4667dfa..ee558f2d5ab 100644 --- a/internal/congestion/cubic_sender.go +++ b/internal/congestion/cubic_sender.go @@ -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) } @@ -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) diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index b5fb404bf6d..cae02873c83 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -43,7 +43,7 @@ type cryptoSetup struct { rttStats *utils.RTTStats - tracer logging.ConnectionTracer + tracer *logging.ConnectionTracer logger utils.Logger perspective protocol.Perspective @@ -77,7 +77,7 @@ func NewCryptoSetupClient( tlsConf *tls.Config, enable0RTT bool, rttStats *utils.RTTStats, - tracer logging.ConnectionTracer, + tracer *logging.ConnectionTracer, logger utils.Logger, version protocol.VersionNumber, ) CryptoSetup { @@ -111,7 +111,7 @@ func NewCryptoSetupServer( tlsConf *tls.Config, allow0RTT bool, rttStats *utils.RTTStats, - tracer logging.ConnectionTracer, + tracer *logging.ConnectionTracer, logger utils.Logger, version protocol.VersionNumber, ) CryptoSetup { @@ -165,13 +165,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) } @@ -193,7 +193,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) } @@ -457,7 +457,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()) } } @@ -479,7 +479,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. @@ -503,7 +503,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) } } @@ -511,7 +511,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) } } @@ -651,7 +651,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) } } diff --git a/internal/handshake/updatable_aead.go b/internal/handshake/updatable_aead.go index 919b8a5bcf0..a583f27732d 100644 --- a/internal/handshake/updatable_aead.go +++ b/internal/handshake/updatable_aead.go @@ -57,7 +57,7 @@ type updatableAEAD struct { rttStats *utils.RTTStats - tracer logging.ConnectionTracer + tracer *logging.ConnectionTracer logger utils.Logger version protocol.VersionNumber @@ -70,7 +70,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, @@ -86,7 +86,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{} @@ -182,7 +182,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) } } @@ -216,7 +216,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 @@ -308,7 +308,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) } } diff --git a/internal/handshake/updatable_aead_test.go b/internal/handshake/updatable_aead_test.go index a4a91f01044..a57030bf73e 100644 --- a/internal/handshake/updatable_aead_test.go +++ b/internal/handshake/updatable_aead_test.go @@ -11,6 +11,7 @@ import ( "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/utils" + "github.com/quic-go/quic-go/logging" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -62,7 +63,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) @@ -70,7 +72,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) diff --git a/internal/mocks/logging/connection_tracer.go b/internal/mocks/logging/connection_tracer.go index 811d1e99370..a2c74b1eb39 100644 --- a/internal/mocks/logging/connection_tracer.go +++ b/internal/mocks/logging/connection_tracer.go @@ -1,388 +1,108 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/quic-go/quic-go/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/quic-go/quic-go/internal/protocol" - utils "github.com/quic-go/quic-go/internal/utils" - wire "github.com/quic-go/quic-go/internal/wire" - logging "github.com/quic-go/quic-go/logging" - gomock "go.uber.org/mock/gomock" -) - -// MockConnectionTracer is a mock of ConnectionTracer interface. -type MockConnectionTracer struct { - ctrl *gomock.Controller - recorder *MockConnectionTracerMockRecorder -} - -// 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) -} + "github.com/quic-go/quic-go/internal/mocks/logging/internal" + "github.com/quic-go/quic-go/logging" -// 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) -} - -// 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 interface{}) *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() - 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 protocol.ECN, arg3 []logging.Frame) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ReceivedLongHeaderPacket", arg0, arg1, arg2, arg3) -} - -// ReceivedLongHeaderPacket indicates an expected call of ReceivedLongHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) ReceivedLongHeaderPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedLongHeaderPacket), arg0, arg1, arg2, arg3) -} - -// 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 protocol.ECN, arg3 []logging.Frame) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ReceivedShortHeaderPacket", arg0, arg1, arg2, arg3) -} - -// ReceivedShortHeaderPacket indicates an expected call of ReceivedShortHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) ReceivedShortHeaderPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedShortHeaderPacket), arg0, arg1, arg2, arg3) -} - -// 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 protocol.ECN, arg3 *wire.AckFrame, arg4 []logging.Frame) { - m.ctrl.T.Helper() - 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, arg4 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, arg4) -} - -// SentShortHeaderPacket mocks base method. -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, arg4) -} - -// SentShortHeaderPacket indicates an expected call of SentShortHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) SentShortHeaderPacket(arg0, arg1, arg2, arg3, arg4 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, arg4) -} - -// 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) -} + "go.uber.org/mock/gomock" +) -// 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) +type MockConnectionTracer = internal.MockConnectionTracer + +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 } diff --git a/internal/mocks/logging/internal/connection_tracer.go b/internal/mocks/logging/internal/connection_tracer.go new file mode 100644 index 00000000000..1cc0bd2e25e --- /dev/null +++ b/internal/mocks/logging/internal/connection_tracer.go @@ -0,0 +1,388 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/quic-go/quic-go/internal/mocks/logging (interfaces: ConnectionTracer) + +// Package internal is a generated GoMock package. +package internal + +import ( + net "net" + reflect "reflect" + time "time" + + protocol "github.com/quic-go/quic-go/internal/protocol" + utils "github.com/quic-go/quic-go/internal/utils" + wire "github.com/quic-go/quic-go/internal/wire" + logging "github.com/quic-go/quic-go/logging" + gomock "go.uber.org/mock/gomock" +) + +// MockConnectionTracer is a mock of ConnectionTracer interface. +type MockConnectionTracer struct { + ctrl *gomock.Controller + recorder *MockConnectionTracerMockRecorder +} + +// 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) +} + +// 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 interface{}) *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() + 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 protocol.ECN, arg3 []logging.Frame) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ReceivedLongHeaderPacket", arg0, arg1, arg2, arg3) +} + +// ReceivedLongHeaderPacket indicates an expected call of ReceivedLongHeaderPacket. +func (mr *MockConnectionTracerMockRecorder) ReceivedLongHeaderPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedLongHeaderPacket), arg0, arg1, arg2, arg3) +} + +// 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 protocol.ECN, arg3 []logging.Frame) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ReceivedShortHeaderPacket", arg0, arg1, arg2, arg3) +} + +// ReceivedShortHeaderPacket indicates an expected call of ReceivedShortHeaderPacket. +func (mr *MockConnectionTracerMockRecorder) ReceivedShortHeaderPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedShortHeaderPacket), arg0, arg1, arg2, arg3) +} + +// 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 protocol.ECN, arg3 *wire.AckFrame, arg4 []logging.Frame) { + m.ctrl.T.Helper() + 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, arg4 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, arg4) +} + +// SentShortHeaderPacket mocks base method. +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, arg4) +} + +// SentShortHeaderPacket indicates an expected call of SentShortHeaderPacket. +func (mr *MockConnectionTracerMockRecorder) SentShortHeaderPacket(arg0, arg1, arg2, arg3, arg4 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, arg4) +} + +// 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) +} diff --git a/internal/mocks/logging/internal/tracer.go b/internal/mocks/logging/internal/tracer.go new file mode 100644 index 00000000000..15dbcaed47e --- /dev/null +++ b/internal/mocks/logging/internal/tracer.go @@ -0,0 +1,74 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/quic-go/quic-go/internal/mocks/logging (interfaces: Tracer) + +// Package internal is a generated GoMock package. +package internal + +import ( + net "net" + reflect "reflect" + + protocol "github.com/quic-go/quic-go/internal/protocol" + wire "github.com/quic-go/quic-go/internal/wire" + logging "github.com/quic-go/quic-go/logging" + gomock "go.uber.org/mock/gomock" +) + +// MockTracer is a mock of Tracer interface. +type MockTracer struct { + ctrl *gomock.Controller + recorder *MockTracerMockRecorder +} + +// 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) +} diff --git a/internal/mocks/logging/mockgen.go b/internal/mocks/logging/mockgen.go new file mode 100644 index 00000000000..8bf08dc8ecc --- /dev/null +++ b/internal/mocks/logging/mockgen.go @@ -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) +} diff --git a/internal/mocks/logging/tracer.go b/internal/mocks/logging/tracer.go index 2cdd2335701..115f578a2c7 100644 --- a/internal/mocks/logging/tracer.go +++ b/internal/mocks/logging/tracer.go @@ -1,74 +1,29 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/quic-go/quic-go/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/quic-go/quic-go/internal/protocol" - wire "github.com/quic-go/quic-go/internal/wire" - logging "github.com/quic-go/quic-go/logging" - gomock "go.uber.org/mock/gomock" -) - -// MockTracer is a mock of Tracer interface. -type MockTracer struct { - ctrl *gomock.Controller - recorder *MockTracerMockRecorder -} - -// MockTracerMockRecorder is the mock recorder for MockTracer. -type MockTracerMockRecorder struct { - mock *MockTracer -} + "github.com/quic-go/quic-go/internal/mocks/logging/internal" + "github.com/quic-go/quic-go/logging" -// 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) -} + "go.uber.org/mock/gomock" +) -// 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) +type MockTracer = internal.MockTracer + +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 } diff --git a/internal/mocks/mockgen.go b/internal/mocks/mockgen.go index 9bee4270f94..23bcda009f5 100644 --- a/internal/mocks/mockgen.go +++ b/internal/mocks/mockgen.go @@ -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/quic-go/quic-go Stream" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package mockquic -destination quic/early_conn_tmp.go github.com/quic-go/quic-go 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/quic-go/quic-go/logging Tracer" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocklogging -destination logging/connection_tracer.go github.com/quic-go/quic-go/logging ConnectionTracer" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination short_header_sealer.go github.com/quic-go/quic-go/internal/handshake ShortHeaderSealer" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination short_header_opener.go github.com/quic-go/quic-go/internal/handshake ShortHeaderOpener" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination long_header_opener.go github.com/quic-go/quic-go/internal/handshake LongHeaderOpener" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination crypto_setup_tmp.go github.com/quic-go/quic-go/internal/handshake CryptoSetup && sed -E 's~github.com/quic-go/qtls[[:alnum:]_-]*~github.com/quic-go/quic-go/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/quic-go/quic-go/internal/flowcontrol StreamFlowController" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination congestion.go github.com/quic-go/quic-go/internal/congestion SendAlgorithmWithDebugInfos" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocks -destination connection_flow_controller.go github.com/quic-go/quic-go/internal/flowcontrol ConnectionFlowController" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package mockackhandler -destination ackhandler/sent_packet_handler.go github.com/quic-go/quic-go/internal/ackhandler SentPacketHandler" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package mockackhandler -destination ackhandler/received_packet_handler.go github.com/quic-go/quic-go/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/quic-go/quic-go 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/quic-go/quic-go 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/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/internal/handshake CryptoSetup && sed -E 's~github.com/quic-go/qtls[[:alnum:]_-]*~github.com/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/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" diff --git a/interop/utils/logging.go b/interop/utils/logging.go index 30e3f663f7a..3cb42244b0f 100644 --- a/interop/utils/logging.go +++ b/interop/utils/logging.go @@ -29,7 +29,7 @@ func GetSSLKeyLog() (io.WriteCloser, error) { } // NewQLOGConnectionTracer create a qlog file in QLOGDIR -func NewQLOGConnectionTracer(_ context.Context, p logging.Perspective, connID quic.ConnectionID) logging.ConnectionTracer { +func NewQLOGConnectionTracer(_ context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer { qlogDir := os.Getenv("QLOGDIR") if len(qlogDir) == 0 { return nil diff --git a/logging/connection_tracer.go b/logging/connection_tracer.go new file mode 100644 index 00000000000..e3f322d91d1 --- /dev/null +++ b/logging/connection_tracer.go @@ -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) + } + } + }, + } +} diff --git a/logging/interface.go b/logging/interface.go index 62028ebc07b..10ac038fb2f 100644 --- a/logging/interface.go +++ b/logging/interface.go @@ -3,9 +3,6 @@ package logging import ( - "net" - "time" - "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/utils" @@ -112,44 +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(*ExtendedHeader, ByteCount, ECN, *AckFrame, []Frame) - SentShortHeaderPacket(*ShortHeader, ByteCount, ECN, *AckFrame, []Frame) - ReceivedVersionNegotiationPacket(dest, src ArbitraryLenConnectionID, _ []VersionNumber) - ReceivedRetry(*Header) - ReceivedLongHeaderPacket(*ExtendedHeader, ByteCount, ECN, []Frame) - ReceivedShortHeaderPacket(*ShortHeader, ByteCount, ECN, []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() - ECNStateUpdated(state ECNState, trigger ECNStateTrigger) - // Close is called when the connection is closed. - Close() - Debug(name, msg string) -} diff --git a/logging/multiplex.go b/logging/multiplex.go deleted file mode 100644 index ef91f3f2b96..00000000000 --- a/logging/multiplex.go +++ /dev/null @@ -1,232 +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, ecn ECN, ack *AckFrame, frames []Frame) { - for _, t := range m.tracers { - t.SentLongHeaderPacket(hdr, size, ecn, ack, frames) - } -} - -func (m *connTracerMultiplexer) SentShortHeaderPacket(hdr *ShortHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame) { - for _, t := range m.tracers { - t.SentShortHeaderPacket(hdr, size, ecn, 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, ecn ECN, frames []Frame) { - for _, t := range m.tracers { - t.ReceivedLongHeaderPacket(hdr, size, ecn, frames) - } -} - -func (m *connTracerMultiplexer) ReceivedShortHeaderPacket(hdr *ShortHeader, size ByteCount, ecn ECN, frames []Frame) { - for _, t := range m.tracers { - t.ReceivedShortHeaderPacket(hdr, size, ecn, 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) ECNStateUpdated(state ECNState, trigger ECNStateTrigger) { - for _, t := range m.tracers { - t.ECNStateUpdated(state, trigger) - } -} - -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() - } -} diff --git a/logging/multiplex_test.go b/logging/multiplex_test.go index c0f784ec276..69606346262 100644 --- a/logging/multiplex_test.go +++ b/logging/multiplex_test.go @@ -21,21 +21,22 @@ var _ = Describe("Tracing", func() { }) It("returns the raw tracer if only one tracer is passed in", func() { - tr := mocklogging.NewMockTracer(mockCtrl) + tr := &Tracer{} tracer := NewMultiplexedTracer(tr) - Expect(tracer).To(BeAssignableToTypeOf(&mocklogging.MockTracer{})) + Expect(tracer).To(Equal(tr)) }) Context("tracing events", func() { var ( - tracer Tracer + tracer *Tracer tr1, tr2 *mocklogging.MockTracer ) BeforeEach(func() { - tr1 = mocklogging.NewMockTracer(mockCtrl) - tr2 = mocklogging.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() { @@ -68,18 +69,19 @@ var _ = Describe("Tracing", func() { Context("Connection Tracer", func() { var ( - tracer ConnectionTracer + tracer *ConnectionTracer tr1 *mocklogging.MockConnectionTracer tr2 *mocklogging.MockConnectionTracer ) BeforeEach(func() { - tr1 = mocklogging.NewMockConnectionTracer(mockCtrl) - tr2 = mocklogging.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}) @@ -89,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) diff --git a/logging/null_tracer.go b/logging/null_tracer.go deleted file mode 100644 index 3e3458f7e6d..00000000000 --- a/logging/null_tracer.go +++ /dev/null @@ -1,63 +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, ECN, *AckFrame, []Frame) { -} - -func (n NullConnectionTracer) SentShortHeaderPacket(*ShortHeader, ByteCount, ECN, *AckFrame, []Frame) { -} - -func (n NullConnectionTracer) ReceivedVersionNegotiationPacket(dest, src ArbitraryLenConnectionID, _ []VersionNumber) { -} -func (n NullConnectionTracer) ReceivedRetry(*Header) {} -func (n NullConnectionTracer) ReceivedLongHeaderPacket(*ExtendedHeader, ByteCount, ECN, []Frame) {} -func (n NullConnectionTracer) ReceivedShortHeaderPacket(*ShortHeader, ByteCount, ECN, []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, EncryptionLevel) {} -func (n NullConnectionTracer) LossTimerCanceled() {} -func (n NullConnectionTracer) ECNStateUpdated(ECNState, ECNStateTrigger) {} -func (n NullConnectionTracer) Close() {} -func (n NullConnectionTracer) Debug(name, msg string) {} diff --git a/logging/tracer.go b/logging/tracer.go new file mode 100644 index 00000000000..5918f30f842 --- /dev/null +++ b/logging/tracer.go @@ -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) + } + } + }, + } +} diff --git a/qlog/qlog.go b/qlog/qlog.go index 943bbc3d11b..7801b646358 100644 --- a/qlog/qlog.go +++ b/qlog/qlog.go @@ -63,11 +63,9 @@ type connectionTracer struct { lastMetrics *metrics } -var _ logging.ConnectionTracer = &connectionTracer{} - // NewConnectionTracer creates a new tracer to record a qlog for a connection. -func NewConnectionTracer(w io.WriteCloser, p protocol.Perspective, odcid protocol.ConnectionID) logging.ConnectionTracer { - t := &connectionTracer{ +func NewConnectionTracer(w io.WriteCloser, p protocol.Perspective, odcid protocol.ConnectionID) *logging.ConnectionTracer { + t := connectionTracer{ w: w, perspective: p, odcid: odcid, @@ -76,7 +74,84 @@ func NewConnectionTracer(w io.WriteCloser, p protocol.Perspective, odcid protoco referenceTime: time.Now(), } go t.run() - return t + 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 *wire.TransportParameters) { t.SentTransportParameters(tp) }, + ReceivedTransportParameters: func(tp *wire.TransportParameters) { t.ReceivedTransportParameters(tp) }, + RestoredTransportParameters: func(tp *wire.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) + }, + 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) + }, + ReceivedRetry: func(hdr *wire.Header) { + t.ReceivedRetry(hdr) + }, + ReceivedVersionNegotiationPacket: func(dest, src logging.ArbitraryLenConnectionID, versions []logging.VersionNumber) { + t.ReceivedVersionNegotiationPacket(dest, src, versions) + }, + BufferedPacket: func(pt logging.PacketType, size protocol.ByteCount) { + t.BufferedPacket(pt, size) + }, + DroppedPacket: func(pt logging.PacketType, size protocol.ByteCount, reason logging.PacketDropReason) { + t.DroppedPacket(pt, size, reason) + }, + UpdatedMetrics: func(rttStats *utils.RTTStats, cwnd, bytesInFlight protocol.ByteCount, packetsInFlight int) { + t.UpdatedMetrics(rttStats, cwnd, bytesInFlight, packetsInFlight) + }, + LostPacket: func(encLevel protocol.EncryptionLevel, pn protocol.PacketNumber, lossReason logging.PacketLossReason) { + t.LostPacket(encLevel, pn, lossReason) + }, + UpdatedCongestionState: func(state logging.CongestionState) { + t.UpdatedCongestionState(state) + }, + UpdatedPTOCount: func(value uint32) { + t.UpdatedPTOCount(value) + }, + UpdatedKeyFromTLS: func(encLevel protocol.EncryptionLevel, pers protocol.Perspective) { + t.UpdatedKeyFromTLS(encLevel, pers) + }, + UpdatedKey: func(generation protocol.KeyPhase, remote bool) { + t.UpdatedKey(generation, remote) + }, + DroppedEncryptionLevel: func(encLevel protocol.EncryptionLevel) { + t.DroppedEncryptionLevel(encLevel) + }, + DroppedKey: func(generation protocol.KeyPhase) { + t.DroppedKey(generation) + }, + SetLossTimer: func(tt logging.TimerType, encLevel protocol.EncryptionLevel, timeout time.Time) { + t.SetLossTimer(tt, encLevel, timeout) + }, + LossTimerExpired: func(tt logging.TimerType, encLevel protocol.EncryptionLevel) { + t.LossTimerExpired(tt, encLevel) + }, + LossTimerCanceled: func() { + t.LossTimerCanceled() + }, + ECNStateUpdated: func(state logging.ECNState, trigger logging.ECNStateTrigger) { + t.ECNStateUpdated(state, trigger) + }, + Debug: func(name, msg string) { + t.Debug(name, msg) + }, + Close: func() { + t.Close() + }, + } } func (t *connectionTracer) run() { diff --git a/qlog/qlog_test.go b/qlog/qlog_test.go index c19a0d3e1da..a58f02780c8 100644 --- a/qlog/qlog_test.go +++ b/qlog/qlog_test.go @@ -70,7 +70,7 @@ var _ = Describe("Tracing", func() { Context("connection tracer", func() { var ( - tracer logging.ConnectionTracer + tracer *logging.ConnectionTracer buf *bytes.Buffer ) diff --git a/server.go b/server.go index 671ae9714cf..ebfb6afeba5 100644 --- a/server.go +++ b/server.go @@ -92,7 +92,7 @@ type baseServer struct { *tls.Config, *handshake.TokenGenerator, bool, /* client address validated by an address validation token */ - logging.ConnectionTracer, + *logging.ConnectionTracer, uint64, utils.Logger, protocol.VersionNumber, @@ -108,7 +108,7 @@ type baseServer struct { connQueue chan quicConn connQueueLen int32 // to be used as an atomic - tracer logging.Tracer + tracer *logging.Tracer logger utils.Logger } @@ -224,7 +224,7 @@ func newServer( connIDGenerator ConnectionIDGenerator, tlsConf *tls.Config, config *Config, - tracer logging.Tracer, + tracer *logging.Tracer, onClose func(), tokenGeneratorKey TokenGeneratorKey, disableVersionNegotiation bool, @@ -349,7 +349,7 @@ func (s *baseServer) handlePacket(p receivedPacket) { case s.receivedPackets <- p: default: s.logger.Debugf("Dropping packet from %s (%d bytes). Server receive queue full.", p.remoteAddr, p.Size()) - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention) } } @@ -362,7 +362,7 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st if wire.IsVersionNegotiationPacket(p.data) { s.logger.Debugf("Dropping Version Negotiation packet.") - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedPacket) } return false @@ -375,7 +375,7 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st // drop the packet if we failed to parse the protocol version if err != nil { s.logger.Debugf("Dropping a packet with an unknown version") - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket) } return false @@ -388,7 +388,7 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st if p.Size() < protocol.MinUnknownVersionPacketSize { s.logger.Debugf("Dropping a packet with an unsupported version number %d that is too small (%d bytes)", v, p.Size()) - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket) } return false @@ -398,7 +398,7 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st if wire.Is0RTTPacket(p.data) { if !s.acceptEarlyConns { - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropUnexpectedPacket) } return false @@ -410,7 +410,7 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st // The header will then be parsed again. hdr, _, _, err := wire.ParsePacket(p.data) if err != nil { - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError) } s.logger.Debugf("Error parsing packet: %s", err) @@ -418,7 +418,7 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st } if hdr.Type == protocol.PacketTypeInitial && p.Size() < protocol.MinInitialPacketSize { s.logger.Debugf("Dropping a packet that is too small to be a valid Initial (%d bytes)", p.Size()) - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropUnexpectedPacket) } return false @@ -429,7 +429,7 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st // There's little point in sending a Stateless Reset, since the client // might not have received the token yet. s.logger.Debugf("Dropping long header packet of type %s (%d bytes)", hdr.Type, len(p.data)) - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropUnexpectedPacket) } return false @@ -448,7 +448,7 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st func (s *baseServer) handle0RTTPacket(p receivedPacket) bool { connID, err := wire.ParseConnectionID(p.data, 0) if err != nil { - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropHeaderParseError) } return false @@ -462,7 +462,7 @@ func (s *baseServer) handle0RTTPacket(p receivedPacket) bool { if q, ok := s.zeroRTTQueues[connID]; ok { if len(q.packets) >= protocol.Max0RTTQueueLen { - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention) } return false @@ -472,7 +472,7 @@ func (s *baseServer) handle0RTTPacket(p receivedPacket) bool { } if len(s.zeroRTTQueues) >= protocol.Max0RTTQueues { - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention) } return false @@ -500,7 +500,7 @@ func (s *baseServer) cleanupZeroRTTQueues(now time.Time) { continue } for _, p := range q.packets { - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention) } p.buffer.Release() @@ -536,7 +536,7 @@ func (s *baseServer) validateToken(token *handshake.Token, addr net.Addr) bool { func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error { if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial { p.buffer.Release() - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropUnexpectedPacket) } return errors.New("too short connection ID") @@ -621,7 +621,7 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error } config = populateConfig(conf) } - var tracer logging.ConnectionTracer + var tracer *logging.ConnectionTracer if config.Tracer != nil { // Use the same connection ID that is passed to the client's GetLogWriter callback. connID := hdr.DestConnectionID @@ -738,7 +738,7 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info packe // append the Retry integrity tag tag := handshake.GetRetryIntegrityTag(buf.Data, hdr.DestConnectionID, hdr.Version) buf.Data = append(buf.Data, tag[:]...) - if s.tracer != nil { + if s.tracer != nil && s.tracer.SentPacket != nil { s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(buf.Data)), nil) } _, err = s.conn.WritePacket(buf.Data, remoteAddr, info.OOB(), 0, protocol.ECNUnsupported) @@ -759,7 +759,7 @@ func (s *baseServer) maybeSendInvalidToken(p receivedPacket) { hdr, _, _, err := wire.ParsePacket(p.data) if err != nil { - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError) } s.logger.Debugf("Error parsing packet: %s", err) @@ -774,14 +774,14 @@ func (s *baseServer) maybeSendInvalidToken(p receivedPacket) { // Only send INVALID_TOKEN if we can unprotect the packet. // This makes sure that we won't send it for packets that were corrupted. if err != nil { - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropHeaderParseError) } return } hdrLen := extHdr.ParsedLen() if _, err := opener.Open(data[hdrLen:hdrLen], data[hdrLen:], extHdr.PacketNumber, data[:hdrLen]); err != nil { - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropPayloadDecryptError) } return @@ -837,7 +837,7 @@ func (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer han replyHdr.Log(s.logger) wire.LogFrame(s.logger, ccf, true) - if s.tracer != nil { + if s.tracer != nil && s.tracer.SentPacket != nil { s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(b.Data)), []logging.Frame{ccf}) } _, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB(), 0, protocol.ECNUnsupported) @@ -866,7 +866,7 @@ func (s *baseServer) maybeSendVersionNegotiationPacket(p receivedPacket) { _, src, dest, err := wire.ParseArbitraryLenConnectionIDs(p.data) if err != nil { // should never happen s.logger.Debugf("Dropping a packet with an unknown version for which we failed to parse connection IDs") - if s.tracer != nil { + if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket) } return @@ -875,7 +875,7 @@ func (s *baseServer) maybeSendVersionNegotiationPacket(p receivedPacket) { s.logger.Debugf("Client offered version %s, sending Version Negotiation", v) data := wire.ComposeVersionNegotiation(dest, src, s.config.Versions) - if s.tracer != nil { + if s.tracer != nil && s.tracer.SentVersionNegotiationPacket != nil { s.tracer.SentVersionNegotiationPacket(p.remoteAddr, src, dest, s.config.Versions) } if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported); err != nil { diff --git a/server_test.go b/server_test.go index 31a977648d8..71c968bd739 100644 --- a/server_test.go +++ b/server_test.go @@ -177,8 +177,9 @@ var _ = Describe("Server", func() { ) BeforeEach(func() { - tracer = mocklogging.NewMockTracer(mockCtrl) - tr = &Transport{Conn: conn, Tracer: tracer} + var t *logging.Tracer + t, tracer = mocklogging.NewMockTracer(mockCtrl) + tr = &Transport{Conn: conn, Tracer: t} ln, err := tr.Listen(tlsConf, nil) Expect(err).ToNot(HaveOccurred()) serv = ln.baseServer @@ -291,7 +292,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -493,7 +494,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -552,7 +553,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -605,7 +606,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -641,7 +642,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -712,7 +713,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -1022,7 +1023,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -1099,7 +1100,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -1172,7 +1173,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -1215,7 +1216,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -1279,7 +1280,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, @@ -1329,8 +1330,9 @@ var _ = Describe("Server", func() { ) BeforeEach(func() { - tracer = mocklogging.NewMockTracer(mockCtrl) - tr = &Transport{Conn: conn, Tracer: tracer} + var t *logging.Tracer + t, tracer = mocklogging.NewMockTracer(mockCtrl) + tr = &Transport{Conn: conn, Tracer: t} ln, err := tr.ListenEarly(tlsConf, nil) Expect(err).ToNot(HaveOccurred()) phm = NewMockPacketHandlerManager(mockCtrl) @@ -1404,7 +1406,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ logging.ConnectionTracer, + _ *logging.ConnectionTracer, _ uint64, _ utils.Logger, _ protocol.VersionNumber, diff --git a/transport.go b/transport.go index b585532962b..0119d62978f 100644 --- a/transport.go +++ b/transport.go @@ -69,7 +69,7 @@ type Transport struct { DisableVersionNegotiationPackets bool // A Tracer traces events that don't belong to a single QUIC connection. - Tracer logging.Tracer + Tracer *logging.Tracer handlerMap packetHandlerManager @@ -363,7 +363,7 @@ func (t *Transport) handlePacket(p receivedPacket) { connID, err := wire.ParseConnectionID(p.data, t.connIDLen) if err != nil { t.logger.Debugf("error parsing connection ID on packet from %s: %s", p.remoteAddr, err) - if t.Tracer != nil { + if t.Tracer != nil && t.Tracer.DroppedPacket != nil { t.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError) } p.buffer.MaybeRelease() @@ -458,7 +458,7 @@ func (t *Transport) handleNonQUICPacket(p receivedPacket) { select { case t.nonQUICPackets <- p: default: - if t.Tracer != nil { + if t.Tracer != nil && t.Tracer.DroppedPacket != nil { t.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention) } } diff --git a/transport_test.go b/transport_test.go index 14c6fdbbcf8..2501971982e 100644 --- a/transport_test.go +++ b/transport_test.go @@ -126,11 +126,11 @@ var _ = Describe("Transport", func() { It("drops unparseable QUIC packets", func() { addr := &net.UDPAddr{IP: net.IPv4(9, 8, 7, 6), Port: 1234} packetChan := make(chan packetToRead) - tracer := mocklogging.NewMockTracer(mockCtrl) + t, tracer := mocklogging.NewMockTracer(mockCtrl) tr := &Transport{ Conn: newMockPacketConn(packetChan), ConnectionIDLength: 10, - Tracer: tracer, + Tracer: t, } tr.init(true) dropped := make(chan struct{}) @@ -328,11 +328,9 @@ var _ = Describe("Transport", func() { It("allows receiving non-QUIC packets", func() { remoteAddr := &net.UDPAddr{IP: net.IPv4(9, 8, 7, 6), Port: 1234} packetChan := make(chan packetToRead) - tracer := mocklogging.NewMockTracer(mockCtrl) tr := &Transport{ Conn: newMockPacketConn(packetChan), ConnectionIDLength: 10, - Tracer: tracer, } tr.init(true) receivedPacketChan := make(chan []byte) @@ -362,11 +360,11 @@ var _ = Describe("Transport", func() { It("drops non-QUIC packet if the application doesn't process them quickly enough", func() { remoteAddr := &net.UDPAddr{IP: net.IPv4(9, 8, 7, 6), Port: 1234} packetChan := make(chan packetToRead) - tracer := mocklogging.NewMockTracer(mockCtrl) + t, tracer := mocklogging.NewMockTracer(mockCtrl) tr := &Transport{ Conn: newMockPacketConn(packetChan), ConnectionIDLength: 10, - Tracer: tracer, + Tracer: t, } tr.init(true) From 1affe38703fdb78ccaa3716d6f44fbec0063c7ce Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 16 Sep 2023 19:10:20 +0700 Subject: [PATCH 072/225] move MaxTokenAge configuration option to the Transport (#4084) --- config.go | 4 ---- config_test.go | 2 -- interface.go | 4 ---- internal/handshake/token_protector.go | 2 +- server.go | 5 ++++- server_test.go | 2 +- transport.go | 8 ++++++++ 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/config.go b/config.go index dea118b3932..49b9fc3f049 100644 --- a/config.go +++ b/config.go @@ -53,9 +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.RequireAddressValidation == nil { config.RequireAddressValidation = func(net.Addr) bool { return false } } @@ -114,7 +111,6 @@ func populateConfig(config *Config) *Config { Versions: versions, HandshakeIdleTimeout: handshakeIdleTimeout, MaxIdleTimeout: idleTimeout, - MaxTokenAge: config.MaxTokenAge, RequireAddressValidation: config.RequireAddressValidation, KeepAlivePeriod: config.KeepAlivePeriod, InitialStreamReceiveWindow: initialStreamReceiveWindow, diff --git a/config_test.go b/config_test.go index c5701608fea..e40c1cfcc5a 100644 --- a/config_test.go +++ b/config_test.go @@ -78,8 +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 "TokenStore": f.Set(reflect.ValueOf(NewLRUTokenStore(2, 3))) case "InitialStreamReceiveWindow": diff --git a/interface.go b/interface.go index c7e53bdc962..6eac385dfce 100644 --- a/interface.go +++ b/interface.go @@ -268,10 +268,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 - // 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 diff --git a/internal/handshake/token_protector.go b/internal/handshake/token_protector.go index 6dcf7f7736d..f3a99e4110e 100644 --- a/internal/handshake/token_protector.go +++ b/internal/handshake/token_protector.go @@ -61,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.key[:], 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 diff --git a/server.go b/server.go index ebfb6afeba5..119289b3970 100644 --- a/server.go +++ b/server.go @@ -67,6 +67,7 @@ type baseServer struct { conn rawConn tokenGenerator *handshake.TokenGenerator + maxTokenAge time.Duration connIDGenerator ConnectionIDGenerator connHandler packetHandlerManager @@ -227,6 +228,7 @@ func newServer( tracer *logging.Tracer, onClose func(), tokenGeneratorKey TokenGeneratorKey, + maxTokenAge time.Duration, disableVersionNegotiation bool, acceptEarly bool, ) *baseServer { @@ -235,6 +237,7 @@ func newServer( tlsConf: tlsConf, config: config, tokenGenerator: handshake.NewTokenGenerator(tokenGeneratorKey), + maxTokenAge: maxTokenAge, connIDGenerator: connIDGenerator, connHandler: connHandler, connQueue: make(chan quicConn), @@ -524,7 +527,7 @@ func (s *baseServer) validateToken(token *handshake.Token, addr net.Addr) bool { if !token.ValidateRemoteAddr(addr) { return false } - if !token.IsRetryToken && time.Since(token.SentTime) > s.config.MaxTokenAge { + if !token.IsRetryToken && time.Since(token.SentTime) > s.maxTokenAge { return false } if token.IsRetryToken && time.Since(token.SentTime) > s.config.maxRetryTokenAge() { diff --git a/server_test.go b/server_test.go index 71c968bd739..6e50de82926 100644 --- a/server_test.go +++ b/server_test.go @@ -901,7 +901,7 @@ var _ = Describe("Server", func() { It("sends an INVALID_TOKEN error, if an expired non-retry token is received", func() { serv.config.RequireAddressValidation = func(net.Addr) bool { return true } - serv.config.MaxTokenAge = time.Millisecond + serv.maxTokenAge = time.Millisecond raddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337} token, err := serv.tokenGenerator.NewToken(raddr) Expect(err).ToNot(HaveOccurred()) diff --git a/transport.go b/transport.go index 0119d62978f..14d6b1fd7f7 100644 --- a/transport.go +++ b/transport.go @@ -63,6 +63,13 @@ type Transport struct { // see section 8.1.3 of RFC 9000 for details. TokenGeneratorKey *TokenGeneratorKey + // MaxTokenAge is the maximum age of the resumption token presented during the handshake. + // These tokens allow skipping address resumption when resuming a QUIC connection, + // and are especially useful when using 0-RTT. + // If not set, it defaults to 24 hours. + // See section 8.1.3 of RFC 9000 for details. + MaxTokenAge time.Duration + // 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 clients. @@ -151,6 +158,7 @@ func (t *Transport) createServer(tlsConf *tls.Config, conf *Config, allow0RTT bo t.Tracer, t.closeServer, *t.TokenGeneratorKey, + t.MaxTokenAge, t.DisableVersionNegotiationPackets, allow0RTT, ) From 55eebd49ff040846a90d818f5d513d48ee2d2c82 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 16 Sep 2023 19:37:58 +0700 Subject: [PATCH 073/225] return the cancellation cause for cancelled dials (#4078) --- client.go | 2 +- integrationtests/self/handshake_test.go | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/client.go b/client.go index 670e7a7c678..e0ae5d3cb70 100644 --- a/client.go +++ b/client.go @@ -233,7 +233,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: diff --git a/integrationtests/self/handshake_test.go b/integrationtests/self/handshake_test.go index f90ac2fd690..d4f65a12b82 100644 --- a/integrationtests/self/handshake_test.go +++ b/integrationtests/self/handshake_test.go @@ -82,6 +82,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, From 22fb59ee6f2962e9987a7dede7a91821fbffd0b0 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 17 Sep 2023 05:18:43 -0700 Subject: [PATCH 074/225] create FUNDING.yml --- .github/FUNDING.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000000..7de30a1d744 --- /dev/null +++ b/.github/FUNDING.yml @@ -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'] From 9010cfd2bbc9da8c16a839a4b9494bfe3b6b9d41 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 17 Sep 2023 19:20:13 +0700 Subject: [PATCH 075/225] remove unused unknownPacketHandler interface (#4093) --- mock_unknown_packet_handler_test.go | 58 ----------------------------- mockgen.go | 3 -- packet_handler_map.go | 8 ---- transport.go | 4 +- 4 files changed, 3 insertions(+), 70 deletions(-) delete mode 100644 mock_unknown_packet_handler_test.go diff --git a/mock_unknown_packet_handler_test.go b/mock_unknown_packet_handler_test.go deleted file mode 100644 index 6f29101a3b3..00000000000 --- a/mock_unknown_packet_handler_test.go +++ /dev/null @@ -1,58 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/quic-go/quic-go (interfaces: UnknownPacketHandler) - -// Package quic is a generated GoMock package. -package quic - -import ( - reflect "reflect" - - gomock "go.uber.org/mock/gomock" -) - -// MockUnknownPacketHandler is a mock of UnknownPacketHandler interface. -type MockUnknownPacketHandler struct { - ctrl *gomock.Controller - recorder *MockUnknownPacketHandlerMockRecorder -} - -// MockUnknownPacketHandlerMockRecorder is the mock recorder for MockUnknownPacketHandler. -type MockUnknownPacketHandlerMockRecorder struct { - mock *MockUnknownPacketHandler -} - -// NewMockUnknownPacketHandler creates a new mock instance. -func NewMockUnknownPacketHandler(ctrl *gomock.Controller) *MockUnknownPacketHandler { - mock := &MockUnknownPacketHandler{ctrl: ctrl} - mock.recorder = &MockUnknownPacketHandlerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockUnknownPacketHandler) EXPECT() *MockUnknownPacketHandlerMockRecorder { - return m.recorder -} - -// handlePacket mocks base method. -func (m *MockUnknownPacketHandler) handlePacket(arg0 receivedPacket) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "handlePacket", arg0) -} - -// handlePacket indicates an expected call of handlePacket. -func (mr *MockUnknownPacketHandlerMockRecorder) handlePacket(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handlePacket", reflect.TypeOf((*MockUnknownPacketHandler)(nil).handlePacket), arg0) -} - -// setCloseError mocks base method. -func (m *MockUnknownPacketHandler) setCloseError(arg0 error) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "setCloseError", arg0) -} - -// setCloseError indicates an expected call of setCloseError. -func (mr *MockUnknownPacketHandlerMockRecorder) setCloseError(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "setCloseError", reflect.TypeOf((*MockUnknownPacketHandler)(nil).setCloseError), arg0) -} diff --git a/mockgen.go b/mockgen.go index ea0aa58bedd..eb24738631a 100644 --- a/mockgen.go +++ b/mockgen.go @@ -62,9 +62,6 @@ type QUICConn = quicConn //go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_test.go github.com/quic-go/quic-go PacketHandler" type PacketHandler = packetHandler -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_unknown_packet_handler_test.go github.com/quic-go/quic-go UnknownPacketHandler" -type UnknownPacketHandler = unknownPacketHandler - //go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager" type PacketHandlerManager = packetHandlerManager diff --git a/packet_handler_map.go b/packet_handler_map.go index ba30fb23b9e..006eadf9218 100644 --- a/packet_handler_map.go +++ b/packet_handler_map.go @@ -4,7 +4,6 @@ import ( "crypto/hmac" "crypto/rand" "crypto/sha256" - "errors" "hash" "io" "net" @@ -45,13 +44,6 @@ type closePacket struct { info packetInfo } -type unknownPacketHandler interface { - handlePacket(receivedPacket) - setCloseError(error) -} - -var errListenerAlreadySet = errors.New("listener already set") - type packetHandlerMap struct { mutex sync.Mutex handlers map[protocol.ConnectionID]packetHandler diff --git a/transport.go b/transport.go index 14d6b1fd7f7..60d44a43e84 100644 --- a/transport.go +++ b/transport.go @@ -16,6 +16,8 @@ import ( "github.com/quic-go/quic-go/logging" ) +var errListenerAlreadySet = errors.New("listener already set") + // The Transport is the central point to manage incoming and outgoing QUIC connections. // QUIC demultiplexes connections based on their QUIC Connection IDs, not based on the 4-tuple. // This means that a single UDP socket can be used for listening for incoming connections, as well as @@ -91,7 +93,7 @@ type Transport struct { // If no ConnectionIDGenerator is set, this is set to a default. connIDGenerator ConnectionIDGenerator - server unknownPacketHandler + server *baseServer conn rawConn From c12f42580329a9fa6a724f7f0f56c7abb2a7dde6 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 17 Sep 2023 23:00:05 +0400 Subject: [PATCH 076/225] ackhandler: don't fail ECN validation if less than 10 testing packets are lost (#4088) * ackhandler: don't fail ECN validation less than 10 testing packets lost * ackhandler: simplify checks for mangling and loss of all testing packets --- internal/ackhandler/ecn.go | 22 +++++++++++++--------- internal/ackhandler/ecn_test.go | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/internal/ackhandler/ecn.go b/internal/ackhandler/ecn.go index 43cc3dd6e10..3e851c8ef3b 100644 --- a/internal/ackhandler/ecn.go +++ b/internal/ackhandler/ecn.go @@ -125,6 +125,10 @@ func (e *ecnTracker) LostPacket(pn protocol.PacketNumber) { 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 { @@ -223,16 +227,16 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 e.numAckedECT1 = ect1 e.numAckedECNCE = ecnce - if e.state == ecnStateTesting || e.state == ecnStateUnknown { - // Detect mangling (a path remarking all ECN-marked testing packets as CE). - if e.numSentECT0+e.numSentECT1 == e.numAckedECNCE && e.numAckedECNCE >= numECNTestingPackets { - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected) - } - e.state = ecnStateFailed - return false + // 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.numSentECT0+e.numSentECT1 == e.numAckedECNCE { + if e.tracer != nil && e.tracer.ECNStateUpdated != nil { + e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected) } - + e.state = ecnStateFailed + return false + } + if e.state == ecnStateTesting || e.state == ecnStateUnknown { var ackedTestingPacket bool for _, p := range packets { if e.isTestingPacket(p.PacketNumber) { diff --git a/internal/ackhandler/ecn_test.go b/internal/ackhandler/ecn_test.go index 26d54eed5f3..78eef8c9f4e 100644 --- a/internal/ackhandler/ecn_test.go +++ b/internal/ackhandler/ecn_test.go @@ -71,6 +71,22 @@ var _ = Describe("ECN tracker", func() { 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++ { From 4a046185b7d5275fd70504d2d630d10e731dbcc6 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 18 Sep 2023 09:08:33 +0400 Subject: [PATCH 077/225] ackhandler: fix ECN mangling detection when packets are lost (#4089) Some of the 10 testing packets are might be lost, while others might be CE-marked. We need to detect mangling if all testing packets are either lost are CE-marked. --- internal/ackhandler/ecn.go | 24 +++++++++++++++++----- internal/ackhandler/ecn_test.go | 35 ++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/internal/ackhandler/ecn.go b/internal/ackhandler/ecn.go index 3e851c8ef3b..68415ac6c08 100644 --- a/internal/ackhandler/ecn.go +++ b/internal/ackhandler/ecn.go @@ -135,7 +135,10 @@ func (e *ecnTracker) LostPacket(pn protocol.PacketNumber) { 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. @@ -229,12 +232,11 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // 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.numSentECT0+e.numSentECT1 == e.numAckedECNCE { - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected) + if e.state == ecnStateUnknown { + e.failIfMangled() + if e.state == ecnStateFailed { + return false } - e.state = ecnStateFailed - return false } if e.state == ecnStateTesting || e.state == ecnStateUnknown { var ackedTestingPacket bool @@ -259,6 +261,18 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 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 diff --git a/internal/ackhandler/ecn_test.go b/internal/ackhandler/ecn_test.go index 78eef8c9f4e..ab648d816f6 100644 --- a/internal/ackhandler/ecn_test.go +++ b/internal/ackhandler/ecn_test.go @@ -192,7 +192,7 @@ var _ = Describe("ECN tracker", func() { Expect(ecnTracker.HandleNewlyAcked(getAckedPackets(4, 5, 6, 15), 3, 0, 2)).To(BeFalse()) }) - It("detects ECN mangling", func() { + 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)) @@ -222,6 +222,39 @@ var _ = Describe("ECN tracker", func() { 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++ { From 4bdff39ff0ce859f3f9a8f7bddc8a389add6c0f0 Mon Sep 17 00:00:00 2001 From: Toby Date: Sun, 24 Sep 2023 04:01:03 -0700 Subject: [PATCH 078/225] README: add Hysteria (#4085) * chore: add my project * fix order --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a793f984764..976a07ccd43 100644 --- a/README.md +++ b/README.md @@ -200,12 +200,13 @@ http.Client{ ## Projects using quic-go | Project | Description | Stars | -|-----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------| +| --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | [AdGuardHome](https://github.com/AdguardTeam/AdGuardHome) | Free and open source, powerful network-wide ads & trackers blocking DNS server. | ![GitHub Repo stars](https://img.shields.io/github/stars/AdguardTeam/AdGuardHome?style=flat-square) | | [algernon](https://github.com/xyproto/algernon) | Small self-contained pure-Go web server with Lua, Markdown, HTTP/2, QUIC, Redis and PostgreSQL support | ![GitHub Repo stars](https://img.shields.io/github/stars/xyproto/algernon?style=flat-square) | | [caddy](https://github.com/caddyserver/caddy/) | Fast, multi-platform web server with automatic HTTPS | ![GitHub Repo stars](https://img.shields.io/github/stars/caddyserver/caddy?style=flat-square) | | [cloudflared](https://github.com/cloudflare/cloudflared) | A tunneling daemon that proxies traffic from the Cloudflare network to your origins | ![GitHub Repo stars](https://img.shields.io/github/stars/cloudflare/cloudflared?style=flat-square) | | [go-libp2p](https://github.com/libp2p/go-libp2p) | libp2p implementation in Go, powering [Kubo](https://github.com/ipfs/kubo) (IPFS) and [Lotus](https://github.com/filecoin-project/lotus) (Filecoin), among others | ![GitHub Repo stars](https://img.shields.io/github/stars/libp2p/go-libp2p?style=flat-square) | +| [Hysteria](https://github.com/apernet/hysteria) | A powerful, lightning fast and censorship resistant proxy | ![GitHub Repo stars](https://img.shields.io/github/stars/apernet/hysteria?style=flat-square) | | [Mercure](https://github.com/dunglas/mercure) | An open, easy, fast, reliable and battery-efficient solution for real-time communications | ![GitHub Repo stars](https://img.shields.io/github/stars/dunglas/mercure?style=flat-square) | | [OONI Probe](https://github.com/ooni/probe-cli) | Next generation OONI Probe. Library and CLI tool. | ![GitHub Repo stars](https://img.shields.io/github/stars/ooni/probe-cli?style=flat-square) | | [syncthing](https://github.com/syncthing/syncthing/) | Open Source Continuous File Synchronization | ![GitHub Repo stars](https://img.shields.io/github/stars/syncthing/syncthing?style=flat-square) | From 9a397abc177badb035e63b4d9321fc287430ee2d Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 24 Sep 2023 11:38:28 +0000 Subject: [PATCH 079/225] update gomock to v0.3.0 (#4087) --- go.mod | 4 +- go.sum | 8 +-- http3/mock_quic_early_listener_test.go | 8 ++- http3/mock_roundtripcloser_test.go | 8 ++- integrationtests/gomodvendor/go.sum | 9 ++- internal/ackhandler/mock_ecn_handler_test.go | 12 ++-- .../mock_sent_packet_tracker_test.go | 8 ++- .../ackhandler/received_packet_handler.go | 14 +++-- .../mocks/ackhandler/sent_packet_handler.go | 28 +++++---- internal/mocks/congestion.go | 22 ++++--- internal/mocks/connection_flow_controller.go | 12 ++-- internal/mocks/crypto_setup.go | 12 ++-- .../logging/internal/connection_tracer.go | 60 ++++++++++--------- internal/mocks/logging/internal/tracer.go | 12 ++-- internal/mocks/long_header_opener.go | 12 ++-- internal/mocks/quic/early_conn.go | 20 ++++--- internal/mocks/quic/stream.go | 20 ++++--- internal/mocks/short_header_opener.go | 12 ++-- internal/mocks/short_header_sealer.go | 10 +++- internal/mocks/stream_flow_controller.go | 14 +++-- internal/mocks/tls/client_session_cache.go | 10 +++- mock_ack_frame_source_test.go | 8 ++- mock_batch_conn_test.go | 8 ++- mock_conn_runner_test.go | 20 ++++--- mock_crypto_data_handler_test.go | 8 ++- mock_crypto_stream_test.go | 12 ++-- mock_frame_source_test.go | 10 +++- mock_mtu_discoverer_test.go | 10 +++- mock_packer_test.go | 22 ++++--- mock_packet_handler_manager_test.go | 28 +++++---- mock_packet_handler_test.go | 10 +++- mock_packetconn_test.go | 16 +++-- mock_quic_conn_test.go | 24 ++++---- mock_raw_conn_test.go | 10 +++- mock_receive_stream_internal_test.go | 18 +++--- mock_sealing_manager_test.go | 6 +- mock_send_conn_test.go | 8 ++- mock_send_stream_internal_test.go | 20 ++++--- mock_sender_test.go | 8 ++- mock_stream_getter_test.go | 10 +++- mock_stream_internal_test.go | 32 +++++----- mock_stream_manager_test.go | 26 ++++---- mock_stream_sender_test.go | 12 ++-- mock_token_store_test.go | 10 +++- mock_unpacker_test.go | 10 +++- server_test.go | 2 +- 46 files changed, 415 insertions(+), 248 deletions(-) diff --git a/go.mod b/go.mod index 936a3786336..0a56346309e 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/onsi/gomega v1.27.6 github.com/quic-go/qpack v0.4.0 github.com/quic-go/qtls-go1-20 v0.3.4 - go.uber.org/mock v0.2.0 + go.uber.org/mock v0.3.0 golang.org/x/crypto v0.4.0 golang.org/x/exp v0.0.0-20221205204356-47842c84f3db golang.org/x/net v0.10.0 @@ -21,7 +21,7 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect - golang.org/x/mod v0.10.0 // indirect + golang.org/x/mod v0.11.0 // indirect golang.org/x/text v0.9.0 // indirect golang.org/x/tools v0.9.1 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect diff --git a/go.sum b/go.sum index 8a3bc65580b..62b640db008 100644 --- a/go.sum +++ b/go.sum @@ -124,8 +124,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= @@ -139,8 +139,8 @@ golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZ 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/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= diff --git a/http3/mock_quic_early_listener_test.go b/http3/mock_quic_early_listener_test.go index b79e985865a..c6977bea972 100644 --- a/http3/mock_quic_early_listener_test.go +++ b/http3/mock_quic_early_listener_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/http3 (interfaces: QUICEarlyListener) - +// +// Generated by this command: +// +// mockgen -package http3 -destination mock_quic_early_listener_test.go github.com/quic-go/quic-go/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) } diff --git a/http3/mock_roundtripcloser_test.go b/http3/mock_roundtripcloser_test.go index ce7f0d19336..2aa3558d95f 100644 --- a/http3/mock_roundtripcloser_test.go +++ b/http3/mock_roundtripcloser_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/http3 (interfaces: RoundTripCloser) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package http3 -destination mock_roundtripcloser_test.go github.com/quic-go/quic-go/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) } diff --git a/integrationtests/gomodvendor/go.sum b/integrationtests/gomodvendor/go.sum index 5e207944f9c..29427a8ce82 100644 --- a/integrationtests/gomodvendor/go.sum +++ b/integrationtests/gomodvendor/go.sum @@ -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= diff --git a/internal/ackhandler/mock_ecn_handler_test.go b/internal/ackhandler/mock_ecn_handler_test.go index 28f350c1709..194ab891d83 100644 --- a/internal/ackhandler/mock_ecn_handler_test.go +++ b/internal/ackhandler/mock_ecn_handler_test.go @@ -1,6 +1,10 @@ // 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 @@ -43,7 +47,7 @@ func (m *MockECNHandler) HandleNewlyAcked(arg0 []*packet, arg1, arg2, arg3 int64 } // HandleNewlyAcked indicates an expected call of HandleNewlyAcked. -func (mr *MockECNHandlerMockRecorder) HandleNewlyAcked(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +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) } @@ -55,7 +59,7 @@ func (m *MockECNHandler) LostPacket(arg0 protocol.PacketNumber) { } // LostPacket indicates an expected call of LostPacket. -func (mr *MockECNHandlerMockRecorder) LostPacket(arg0 interface{}) *gomock.Call { +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) } @@ -81,7 +85,7 @@ func (m *MockECNHandler) SentPacket(arg0 protocol.PacketNumber, arg1 protocol.EC } // SentPacket indicates an expected call of SentPacket. -func (mr *MockECNHandlerMockRecorder) SentPacket(arg0, arg1 interface{}) *gomock.Call { +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) } diff --git a/internal/ackhandler/mock_sent_packet_tracker_test.go b/internal/ackhandler/mock_sent_packet_tracker_test.go index 63a9a163e4f..aa8c8674526 100644 --- a/internal/ackhandler/mock_sent_packet_tracker_test.go +++ b/internal/ackhandler/mock_sent_packet_tracker_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/ackhandler (interfaces: SentPacketTracker) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package ackhandler -destination mock_sent_packet_tracker_test.go github.com/quic-go/quic-go/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) } diff --git a/internal/mocks/ackhandler/received_packet_handler.go b/internal/mocks/ackhandler/received_packet_handler.go index b068586eaab..6455ec1c33b 100644 --- a/internal/mocks/ackhandler/received_packet_handler.go +++ b/internal/mocks/ackhandler/received_packet_handler.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/ackhandler (interfaces: ReceivedPacketHandler) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package mockackhandler -destination ackhandler/received_packet_handler.go github.com/quic-go/quic-go/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) } diff --git a/internal/mocks/ackhandler/sent_packet_handler.go b/internal/mocks/ackhandler/sent_packet_handler.go index 137ac2efad8..6cbde5dceb8 100644 --- a/internal/mocks/ackhandler/sent_packet_handler.go +++ b/internal/mocks/ackhandler/sent_packet_handler.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/ackhandler (interfaces: SentPacketHandler) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package mockackhandler -destination ackhandler/sent_packet_handler.go github.com/quic-go/quic-go/internal/ackhandler SentPacketHandler +// // Package mockackhandler is a generated GoMock package. package mockackhandler @@ -44,7 +48,7 @@ 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) } @@ -58,7 +62,7 @@ func (m *MockSentPacketHandler) ECNMode(arg0 bool) protocol.ECN { } // ECNMode indicates an expected call of ECNMode. -func (mr *MockSentPacketHandlerMockRecorder) ECNMode(arg0 interface{}) *gomock.Call { +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) } @@ -101,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) } @@ -115,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) } @@ -129,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) } @@ -144,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) } @@ -156,7 +160,7 @@ 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) } @@ -170,7 +174,7 @@ func (m *MockSentPacketHandler) ResetForRetry(arg0 time.Time) error { } // ResetForRetry indicates an expected call of ResetForRetry. -func (mr *MockSentPacketHandlerMockRecorder) ResetForRetry(arg0 interface{}) *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), arg0) } @@ -184,7 +188,7 @@ 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) } @@ -196,7 +200,7 @@ func (m *MockSentPacketHandler) SentPacket(arg0 time.Time, arg1, arg2 protocol.P } // SentPacket indicates an expected call of SentPacket. -func (mr *MockSentPacketHandlerMockRecorder) SentPacket(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 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, arg8) } @@ -220,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) } diff --git a/internal/mocks/congestion.go b/internal/mocks/congestion.go index 4d38d1db6d1..9a96239c0eb 100644 --- a/internal/mocks/congestion.go +++ b/internal/mocks/congestion.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/congestion (interfaces: SendAlgorithmWithDebugInfos) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package mocks -destination congestion.go github.com/quic-go/quic-go/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) } @@ -124,7 +128,7 @@ func (m *MockSendAlgorithmWithDebugInfos) OnCongestionEvent(arg0 protocol.Packet } // OnCongestionEvent indicates an expected call of OnCongestionEvent. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnCongestionEvent(arg0, arg1, arg2 interface{}) *gomock.Call { +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) } @@ -136,7 +140,7 @@ 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) } @@ -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) } diff --git a/internal/mocks/connection_flow_controller.go b/internal/mocks/connection_flow_controller.go index 1ec76f9e0b0..7407054ce86 100644 --- a/internal/mocks/connection_flow_controller.go +++ b/internal/mocks/connection_flow_controller.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/flowcontrol (interfaces: ConnectionFlowController) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package mocks -destination connection_flow_controller.go github.com/quic-go/quic-go/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) } diff --git a/internal/mocks/crypto_setup.go b/internal/mocks/crypto_setup.go index bf496c221df..1e4278ecad2 100644 --- a/internal/mocks/crypto_setup.go +++ b/internal/mocks/crypto_setup.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/handshake (interfaces: CryptoSetup) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package mocks -destination crypto_setup_tmp.go github.com/quic-go/quic-go/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) } diff --git a/internal/mocks/logging/internal/connection_tracer.go b/internal/mocks/logging/internal/connection_tracer.go index 1cc0bd2e25e..5131453a4a6 100644 --- a/internal/mocks/logging/internal/connection_tracer.go +++ b/internal/mocks/logging/internal/connection_tracer.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/mocks/logging (interfaces: ConnectionTracer) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package internal -destination internal/connection_tracer.go github.com/quic-go/quic-go/internal/mocks/logging ConnectionTracer +// // Package internal is a generated GoMock package. package internal @@ -46,7 +50,7 @@ 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) } @@ -58,7 +62,7 @@ func (m *MockConnectionTracer) BufferedPacket(arg0 logging.PacketType, arg1 prot } // 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) } @@ -82,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) } @@ -94,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) } @@ -106,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) } @@ -118,7 +122,7 @@ 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) } @@ -130,7 +134,7 @@ func (m *MockConnectionTracer) DroppedPacket(arg0 logging.PacketType, arg1 proto } // 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) } @@ -142,7 +146,7 @@ func (m *MockConnectionTracer) ECNStateUpdated(arg0 logging.ECNState, arg1 loggi } // ECNStateUpdated indicates an expected call of ECNStateUpdated. -func (mr *MockConnectionTracerMockRecorder) ECNStateUpdated(arg0, arg1 interface{}) *gomock.Call { +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) } @@ -166,7 +170,7 @@ func (m *MockConnectionTracer) LossTimerExpired(arg0 logging.TimerType, arg1 pro } // 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) } @@ -178,7 +182,7 @@ func (m *MockConnectionTracer) LostPacket(arg0 protocol.EncryptionLevel, arg1 pr } // 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) } @@ -190,7 +194,7 @@ 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) } @@ -202,7 +206,7 @@ func (m *MockConnectionTracer) ReceivedLongHeaderPacket(arg0 *wire.ExtendedHeade } // ReceivedLongHeaderPacket indicates an expected call of ReceivedLongHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) ReceivedLongHeaderPacket(arg0, arg1, arg2, arg3 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, arg3) } @@ -214,7 +218,7 @@ 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) } @@ -226,7 +230,7 @@ func (m *MockConnectionTracer) ReceivedShortHeaderPacket(arg0 *logging.ShortHead } // ReceivedShortHeaderPacket indicates an expected call of ReceivedShortHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) ReceivedShortHeaderPacket(arg0, arg1, arg2, arg3 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, arg3) } @@ -238,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) } @@ -250,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) } @@ -262,7 +266,7 @@ 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) } @@ -274,7 +278,7 @@ func (m *MockConnectionTracer) SentLongHeaderPacket(arg0 *wire.ExtendedHeader, a } // SentLongHeaderPacket indicates an expected call of SentLongHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) SentLongHeaderPacket(arg0, arg1, arg2, arg3, arg4 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, arg4) } @@ -286,7 +290,7 @@ func (m *MockConnectionTracer) SentShortHeaderPacket(arg0 *logging.ShortHeader, } // SentShortHeaderPacket indicates an expected call of SentShortHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) SentShortHeaderPacket(arg0, arg1, arg2, arg3, arg4 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, arg4) } @@ -298,7 +302,7 @@ 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) } @@ -310,7 +314,7 @@ func (m *MockConnectionTracer) SetLossTimer(arg0 logging.TimerType, arg1 protoco } // 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) } @@ -322,7 +326,7 @@ 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) } @@ -334,7 +338,7 @@ func (m *MockConnectionTracer) UpdatedCongestionState(arg0 logging.CongestionSta } // 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) } @@ -346,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) } @@ -358,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) } @@ -370,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) } @@ -382,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) } diff --git a/internal/mocks/logging/internal/tracer.go b/internal/mocks/logging/internal/tracer.go index 15dbcaed47e..14ce172c415 100644 --- a/internal/mocks/logging/internal/tracer.go +++ b/internal/mocks/logging/internal/tracer.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/mocks/logging (interfaces: Tracer) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package internal -destination internal/tracer.go github.com/quic-go/quic-go/internal/mocks/logging Tracer +// // Package internal is a generated GoMock package. package internal @@ -44,7 +48,7 @@ func (m *MockTracer) DroppedPacket(arg0 net.Addr, arg1 logging.PacketType, arg2 } // 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) } @@ -56,7 +60,7 @@ func (m *MockTracer) SentPacket(arg0 net.Addr, arg1 *wire.Header, arg2 protocol. } // 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) } @@ -68,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) } diff --git a/internal/mocks/long_header_opener.go b/internal/mocks/long_header_opener.go index fc284dd8b3e..ad5d6b69f81 100644 --- a/internal/mocks/long_header_opener.go +++ b/internal/mocks/long_header_opener.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/handshake (interfaces: LongHeaderOpener) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package mocks -destination long_header_opener.go github.com/quic-go/quic-go/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) } diff --git a/internal/mocks/quic/early_conn.go b/internal/mocks/quic/early_conn.go index c4db88d2ff1..205ed7f2281 100644 --- a/internal/mocks/quic/early_conn.go +++ b/internal/mocks/quic/early_conn.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: EarlyConnection) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package mockquic -destination quic/early_conn_tmp.go github.com/quic-go/quic-go 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) } diff --git a/internal/mocks/quic/stream.go b/internal/mocks/quic/stream.go index 7fc6560008d..2043fdfb646 100644 --- a/internal/mocks/quic/stream.go +++ b/internal/mocks/quic/stream.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: Stream) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package mockquic -destination quic/stream.go github.com/quic-go/quic-go 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) } diff --git a/internal/mocks/short_header_opener.go b/internal/mocks/short_header_opener.go index ffc8bd48903..4b9f77f880c 100644 --- a/internal/mocks/short_header_opener.go +++ b/internal/mocks/short_header_opener.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/handshake (interfaces: ShortHeaderOpener) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package mocks -destination short_header_opener.go github.com/quic-go/quic-go/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) } diff --git a/internal/mocks/short_header_sealer.go b/internal/mocks/short_header_sealer.go index d0109b5e6a8..aabe6867abb 100644 --- a/internal/mocks/short_header_sealer.go +++ b/internal/mocks/short_header_sealer.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/handshake (interfaces: ShortHeaderSealer) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package mocks -destination short_header_sealer.go github.com/quic-go/quic-go/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) } diff --git a/internal/mocks/stream_flow_controller.go b/internal/mocks/stream_flow_controller.go index 05eaf8b9b89..342661c9681 100644 --- a/internal/mocks/stream_flow_controller.go +++ b/internal/mocks/stream_flow_controller.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go/internal/flowcontrol (interfaces: StreamFlowController) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package mocks -destination stream_flow_controller.go github.com/quic-go/quic-go/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) } diff --git a/internal/mocks/tls/client_session_cache.go b/internal/mocks/tls/client_session_cache.go index 6877f9bb71e..8837755facf 100644 --- a/internal/mocks/tls/client_session_cache.go +++ b/internal/mocks/tls/client_session_cache.go @@ -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) } diff --git a/mock_ack_frame_source_test.go b/mock_ack_frame_source_test.go index 54105f9db18..4990e4722af 100644 --- a/mock_ack_frame_source_test.go +++ b/mock_ack_frame_source_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: AckFrameSource) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_ack_frame_source_test.go github.com/quic-go/quic-go 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) } diff --git a/mock_batch_conn_test.go b/mock_batch_conn_test.go index 9621e7b4ec4..1ecc4265f9b 100644 --- a/mock_batch_conn_test.go +++ b/mock_batch_conn_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: sys_conn_oob.go - +// +// Generated by this command: +// +// mockgen -package quic -self_package github.com/quic-go/quic-go -source sys_conn_oob.go -destination mock_batch_conn_test.go -mock_names batchConn=MockBatchConn +// // Package quic is a generated GoMock package. package quic @@ -44,7 +48,7 @@ func (m *MockBatchConn) ReadBatch(ms []ipv4.Message, flags int) (int, error) { } // ReadBatch indicates an expected call of ReadBatch. -func (mr *MockBatchConnMockRecorder) ReadBatch(ms, flags interface{}) *gomock.Call { +func (mr *MockBatchConnMockRecorder) ReadBatch(ms, flags any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadBatch", reflect.TypeOf((*MockBatchConn)(nil).ReadBatch), ms, flags) } diff --git a/mock_conn_runner_test.go b/mock_conn_runner_test.go index e404c28362b..37c0f6cd2f9 100644 --- a/mock_conn_runner_test.go +++ b/mock_conn_runner_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: ConnRunner) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_conn_runner_test.go github.com/quic-go/quic-go ConnRunner +// // Package quic is a generated GoMock package. package quic @@ -43,7 +47,7 @@ func (m *MockConnRunner) Add(arg0 protocol.ConnectionID, arg1 packetHandler) boo } // Add indicates an expected call of Add. -func (mr *MockConnRunnerMockRecorder) Add(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) Add(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockConnRunner)(nil).Add), arg0, arg1) } @@ -55,7 +59,7 @@ func (m *MockConnRunner) AddResetToken(arg0 protocol.StatelessResetToken, arg1 p } // AddResetToken indicates an expected call of AddResetToken. -func (mr *MockConnRunnerMockRecorder) AddResetToken(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) AddResetToken(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddResetToken", reflect.TypeOf((*MockConnRunner)(nil).AddResetToken), arg0, arg1) } @@ -69,7 +73,7 @@ func (m *MockConnRunner) GetStatelessResetToken(arg0 protocol.ConnectionID) prot } // GetStatelessResetToken indicates an expected call of GetStatelessResetToken. -func (mr *MockConnRunnerMockRecorder) GetStatelessResetToken(arg0 interface{}) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) GetStatelessResetToken(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessResetToken", reflect.TypeOf((*MockConnRunner)(nil).GetStatelessResetToken), arg0) } @@ -81,7 +85,7 @@ func (m *MockConnRunner) Remove(arg0 protocol.ConnectionID) { } // Remove indicates an expected call of Remove. -func (mr *MockConnRunnerMockRecorder) Remove(arg0 interface{}) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) Remove(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockConnRunner)(nil).Remove), arg0) } @@ -93,7 +97,7 @@ func (m *MockConnRunner) RemoveResetToken(arg0 protocol.StatelessResetToken) { } // RemoveResetToken indicates an expected call of RemoveResetToken. -func (mr *MockConnRunnerMockRecorder) RemoveResetToken(arg0 interface{}) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) RemoveResetToken(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveResetToken", reflect.TypeOf((*MockConnRunner)(nil).RemoveResetToken), arg0) } @@ -105,7 +109,7 @@ func (m *MockConnRunner) ReplaceWithClosed(arg0 []protocol.ConnectionID, arg1 pr } // ReplaceWithClosed indicates an expected call of ReplaceWithClosed. -func (mr *MockConnRunnerMockRecorder) ReplaceWithClosed(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) ReplaceWithClosed(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceWithClosed", reflect.TypeOf((*MockConnRunner)(nil).ReplaceWithClosed), arg0, arg1, arg2) } @@ -117,7 +121,7 @@ func (m *MockConnRunner) Retire(arg0 protocol.ConnectionID) { } // Retire indicates an expected call of Retire. -func (mr *MockConnRunnerMockRecorder) Retire(arg0 interface{}) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) Retire(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Retire", reflect.TypeOf((*MockConnRunner)(nil).Retire), arg0) } diff --git a/mock_crypto_data_handler_test.go b/mock_crypto_data_handler_test.go index 22e6eaa2937..3240b981e1a 100644 --- a/mock_crypto_data_handler_test.go +++ b/mock_crypto_data_handler_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: CryptoDataHandler) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_data_handler_test.go github.com/quic-go/quic-go CryptoDataHandler +// // Package quic is a generated GoMock package. package quic @@ -44,7 +48,7 @@ func (m *MockCryptoDataHandler) HandleMessage(arg0 []byte, arg1 protocol.Encrypt } // HandleMessage indicates an expected call of HandleMessage. -func (mr *MockCryptoDataHandlerMockRecorder) HandleMessage(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockCryptoDataHandlerMockRecorder) HandleMessage(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMessage", reflect.TypeOf((*MockCryptoDataHandler)(nil).HandleMessage), arg0, arg1) } diff --git a/mock_crypto_stream_test.go b/mock_crypto_stream_test.go index 253e95e8cbd..176b51f38e0 100644 --- a/mock_crypto_stream_test.go +++ b/mock_crypto_stream_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: CryptoStream) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_stream_test.go github.com/quic-go/quic-go CryptoStream +// // Package quic is a generated GoMock package. package quic @@ -72,7 +76,7 @@ func (m *MockCryptoStream) HandleCryptoFrame(arg0 *wire.CryptoFrame) error { } // HandleCryptoFrame indicates an expected call of HandleCryptoFrame. -func (mr *MockCryptoStreamMockRecorder) HandleCryptoFrame(arg0 interface{}) *gomock.Call { +func (mr *MockCryptoStreamMockRecorder) HandleCryptoFrame(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleCryptoFrame", reflect.TypeOf((*MockCryptoStream)(nil).HandleCryptoFrame), arg0) } @@ -100,7 +104,7 @@ func (m *MockCryptoStream) PopCryptoFrame(arg0 protocol.ByteCount) *wire.CryptoF } // PopCryptoFrame indicates an expected call of PopCryptoFrame. -func (mr *MockCryptoStreamMockRecorder) PopCryptoFrame(arg0 interface{}) *gomock.Call { +func (mr *MockCryptoStreamMockRecorder) PopCryptoFrame(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PopCryptoFrame", reflect.TypeOf((*MockCryptoStream)(nil).PopCryptoFrame), arg0) } @@ -115,7 +119,7 @@ func (m *MockCryptoStream) Write(arg0 []byte) (int, error) { } // Write indicates an expected call of Write. -func (mr *MockCryptoStreamMockRecorder) Write(arg0 interface{}) *gomock.Call { +func (mr *MockCryptoStreamMockRecorder) Write(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockCryptoStream)(nil).Write), arg0) } diff --git a/mock_frame_source_test.go b/mock_frame_source_test.go index 040c75815bf..b3b6638b550 100644 --- a/mock_frame_source_test.go +++ b/mock_frame_source_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: FrameSource) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_frame_source_test.go github.com/quic-go/quic-go FrameSource +// // Package quic is a generated GoMock package. package quic @@ -45,7 +49,7 @@ func (m *MockFrameSource) AppendControlFrames(arg0 []ackhandler.Frame, arg1 prot } // AppendControlFrames indicates an expected call of AppendControlFrames. -func (mr *MockFrameSourceMockRecorder) AppendControlFrames(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockFrameSourceMockRecorder) AppendControlFrames(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendControlFrames", reflect.TypeOf((*MockFrameSource)(nil).AppendControlFrames), arg0, arg1, arg2) } @@ -60,7 +64,7 @@ func (m *MockFrameSource) AppendStreamFrames(arg0 []ackhandler.StreamFrame, arg1 } // AppendStreamFrames indicates an expected call of AppendStreamFrames. -func (mr *MockFrameSourceMockRecorder) AppendStreamFrames(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockFrameSourceMockRecorder) AppendStreamFrames(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendStreamFrames", reflect.TypeOf((*MockFrameSource)(nil).AppendStreamFrames), arg0, arg1, arg2) } diff --git a/mock_mtu_discoverer_test.go b/mock_mtu_discoverer_test.go index 1f5432cd55a..a8a9be3e387 100644 --- a/mock_mtu_discoverer_test.go +++ b/mock_mtu_discoverer_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: MTUDiscoverer) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_mtu_discoverer_test.go github.com/quic-go/quic-go MTUDiscoverer +// // Package quic is a generated GoMock package. package quic @@ -74,7 +78,7 @@ func (m *MockMTUDiscoverer) ShouldSendProbe(arg0 time.Time) bool { } // ShouldSendProbe indicates an expected call of ShouldSendProbe. -func (mr *MockMTUDiscovererMockRecorder) ShouldSendProbe(arg0 interface{}) *gomock.Call { +func (mr *MockMTUDiscovererMockRecorder) ShouldSendProbe(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldSendProbe", reflect.TypeOf((*MockMTUDiscoverer)(nil).ShouldSendProbe), arg0) } @@ -86,7 +90,7 @@ func (m *MockMTUDiscoverer) Start(arg0 protocol.ByteCount) { } // Start indicates an expected call of Start. -func (mr *MockMTUDiscovererMockRecorder) Start(arg0 interface{}) *gomock.Call { +func (mr *MockMTUDiscovererMockRecorder) Start(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockMTUDiscoverer)(nil).Start), arg0) } diff --git a/mock_packer_test.go b/mock_packer_test.go index 4eedab98859..26fc63a00dc 100644 --- a/mock_packer_test.go +++ b/mock_packer_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: Packer) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_packer_test.go github.com/quic-go/quic-go Packer +// // Package quic is a generated GoMock package. package quic @@ -46,7 +50,7 @@ func (m *MockPacker) AppendPacket(arg0 *packetBuffer, arg1 protocol.ByteCount, a } // AppendPacket indicates an expected call of AppendPacket. -func (mr *MockPackerMockRecorder) AppendPacket(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockPackerMockRecorder) AppendPacket(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendPacket", reflect.TypeOf((*MockPacker)(nil).AppendPacket), arg0, arg1, arg2) } @@ -61,7 +65,7 @@ func (m *MockPacker) MaybePackProbePacket(arg0 protocol.EncryptionLevel, arg1 pr } // MaybePackProbePacket indicates an expected call of MaybePackProbePacket. -func (mr *MockPackerMockRecorder) MaybePackProbePacket(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockPackerMockRecorder) MaybePackProbePacket(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaybePackProbePacket", reflect.TypeOf((*MockPacker)(nil).MaybePackProbePacket), arg0, arg1, arg2) } @@ -77,7 +81,7 @@ func (m *MockPacker) PackAckOnlyPacket(arg0 protocol.ByteCount, arg1 protocol.Ve } // PackAckOnlyPacket indicates an expected call of PackAckOnlyPacket. -func (mr *MockPackerMockRecorder) PackAckOnlyPacket(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockPackerMockRecorder) PackAckOnlyPacket(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackAckOnlyPacket", reflect.TypeOf((*MockPacker)(nil).PackAckOnlyPacket), arg0, arg1) } @@ -92,7 +96,7 @@ func (m *MockPacker) PackApplicationClose(arg0 *qerr.ApplicationError, arg1 prot } // PackApplicationClose indicates an expected call of PackApplicationClose. -func (mr *MockPackerMockRecorder) PackApplicationClose(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockPackerMockRecorder) PackApplicationClose(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackApplicationClose", reflect.TypeOf((*MockPacker)(nil).PackApplicationClose), arg0, arg1, arg2) } @@ -107,7 +111,7 @@ func (m *MockPacker) PackCoalescedPacket(arg0 bool, arg1 protocol.ByteCount, arg } // PackCoalescedPacket indicates an expected call of PackCoalescedPacket. -func (mr *MockPackerMockRecorder) PackCoalescedPacket(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockPackerMockRecorder) PackCoalescedPacket(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackCoalescedPacket", reflect.TypeOf((*MockPacker)(nil).PackCoalescedPacket), arg0, arg1, arg2) } @@ -122,7 +126,7 @@ func (m *MockPacker) PackConnectionClose(arg0 *qerr.TransportError, arg1 protoco } // PackConnectionClose indicates an expected call of PackConnectionClose. -func (mr *MockPackerMockRecorder) PackConnectionClose(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockPackerMockRecorder) PackConnectionClose(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackConnectionClose", reflect.TypeOf((*MockPacker)(nil).PackConnectionClose), arg0, arg1, arg2) } @@ -138,7 +142,7 @@ func (m *MockPacker) PackMTUProbePacket(arg0 ackhandler.Frame, arg1 protocol.Byt } // PackMTUProbePacket indicates an expected call of PackMTUProbePacket. -func (mr *MockPackerMockRecorder) PackMTUProbePacket(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockPackerMockRecorder) PackMTUProbePacket(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackMTUProbePacket", reflect.TypeOf((*MockPacker)(nil).PackMTUProbePacket), arg0, arg1, arg2) } @@ -150,7 +154,7 @@ func (m *MockPacker) SetToken(arg0 []byte) { } // SetToken indicates an expected call of SetToken. -func (mr *MockPackerMockRecorder) SetToken(arg0 interface{}) *gomock.Call { +func (mr *MockPackerMockRecorder) SetToken(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetToken", reflect.TypeOf((*MockPacker)(nil).SetToken), arg0) } diff --git a/mock_packet_handler_manager_test.go b/mock_packet_handler_manager_test.go index c948d9d5199..e8c57416a7f 100644 --- a/mock_packet_handler_manager_test.go +++ b/mock_packet_handler_manager_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: PacketHandlerManager) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager +// // Package quic is a generated GoMock package. package quic @@ -43,7 +47,7 @@ func (m *MockPacketHandlerManager) Add(arg0 protocol.ConnectionID, arg1 packetHa } // Add indicates an expected call of Add. -func (mr *MockPacketHandlerManagerMockRecorder) Add(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) Add(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockPacketHandlerManager)(nil).Add), arg0, arg1) } @@ -55,7 +59,7 @@ func (m *MockPacketHandlerManager) AddResetToken(arg0 protocol.StatelessResetTok } // AddResetToken indicates an expected call of AddResetToken. -func (mr *MockPacketHandlerManagerMockRecorder) AddResetToken(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) AddResetToken(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).AddResetToken), arg0, arg1) } @@ -69,7 +73,7 @@ func (m *MockPacketHandlerManager) AddWithConnID(arg0, arg1 protocol.ConnectionI } // AddWithConnID indicates an expected call of AddWithConnID. -func (mr *MockPacketHandlerManagerMockRecorder) AddWithConnID(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) AddWithConnID(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWithConnID", reflect.TypeOf((*MockPacketHandlerManager)(nil).AddWithConnID), arg0, arg1, arg2) } @@ -81,7 +85,7 @@ func (m *MockPacketHandlerManager) Close(arg0 error) { } // Close indicates an expected call of Close. -func (mr *MockPacketHandlerManagerMockRecorder) Close(arg0 interface{}) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) Close(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPacketHandlerManager)(nil).Close), arg0) } @@ -108,7 +112,7 @@ func (m *MockPacketHandlerManager) Get(arg0 protocol.ConnectionID) (packetHandle } // Get indicates an expected call of Get. -func (mr *MockPacketHandlerManagerMockRecorder) Get(arg0 interface{}) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) Get(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockPacketHandlerManager)(nil).Get), arg0) } @@ -123,7 +127,7 @@ func (m *MockPacketHandlerManager) GetByResetToken(arg0 protocol.StatelessResetT } // GetByResetToken indicates an expected call of GetByResetToken. -func (mr *MockPacketHandlerManagerMockRecorder) GetByResetToken(arg0 interface{}) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) GetByResetToken(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).GetByResetToken), arg0) } @@ -137,7 +141,7 @@ func (m *MockPacketHandlerManager) GetStatelessResetToken(arg0 protocol.Connecti } // GetStatelessResetToken indicates an expected call of GetStatelessResetToken. -func (mr *MockPacketHandlerManagerMockRecorder) GetStatelessResetToken(arg0 interface{}) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) GetStatelessResetToken(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).GetStatelessResetToken), arg0) } @@ -149,7 +153,7 @@ func (m *MockPacketHandlerManager) Remove(arg0 protocol.ConnectionID) { } // Remove indicates an expected call of Remove. -func (mr *MockPacketHandlerManagerMockRecorder) Remove(arg0 interface{}) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) Remove(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockPacketHandlerManager)(nil).Remove), arg0) } @@ -161,7 +165,7 @@ func (m *MockPacketHandlerManager) RemoveResetToken(arg0 protocol.StatelessReset } // RemoveResetToken indicates an expected call of RemoveResetToken. -func (mr *MockPacketHandlerManagerMockRecorder) RemoveResetToken(arg0 interface{}) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) RemoveResetToken(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).RemoveResetToken), arg0) } @@ -173,7 +177,7 @@ func (m *MockPacketHandlerManager) ReplaceWithClosed(arg0 []protocol.ConnectionI } // ReplaceWithClosed indicates an expected call of ReplaceWithClosed. -func (mr *MockPacketHandlerManagerMockRecorder) ReplaceWithClosed(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) ReplaceWithClosed(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceWithClosed", reflect.TypeOf((*MockPacketHandlerManager)(nil).ReplaceWithClosed), arg0, arg1, arg2) } @@ -185,7 +189,7 @@ func (m *MockPacketHandlerManager) Retire(arg0 protocol.ConnectionID) { } // Retire indicates an expected call of Retire. -func (mr *MockPacketHandlerManagerMockRecorder) Retire(arg0 interface{}) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) Retire(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Retire", reflect.TypeOf((*MockPacketHandlerManager)(nil).Retire), arg0) } diff --git a/mock_packet_handler_test.go b/mock_packet_handler_test.go index e84905899ab..f30e8f0716d 100644 --- a/mock_packet_handler_test.go +++ b/mock_packet_handler_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: PacketHandler) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_test.go github.com/quic-go/quic-go PacketHandler +// // Package quic is a generated GoMock package. package quic @@ -41,7 +45,7 @@ func (m *MockPacketHandler) destroy(arg0 error) { } // destroy indicates an expected call of destroy. -func (mr *MockPacketHandlerMockRecorder) destroy(arg0 interface{}) *gomock.Call { +func (mr *MockPacketHandlerMockRecorder) destroy(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "destroy", reflect.TypeOf((*MockPacketHandler)(nil).destroy), arg0) } @@ -67,7 +71,7 @@ func (m *MockPacketHandler) handlePacket(arg0 receivedPacket) { } // handlePacket indicates an expected call of handlePacket. -func (mr *MockPacketHandlerMockRecorder) handlePacket(arg0 interface{}) *gomock.Call { +func (mr *MockPacketHandlerMockRecorder) handlePacket(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handlePacket", reflect.TypeOf((*MockPacketHandler)(nil).handlePacket), arg0) } diff --git a/mock_packetconn_test.go b/mock_packetconn_test.go index c8e20bf2880..f148bb32cba 100644 --- a/mock_packetconn_test.go +++ b/mock_packetconn_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: net (interfaces: PacketConn) - +// +// Generated by this command: +// +// mockgen -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_packetconn_test.go net PacketConn +// // Package quic is a generated GoMock package. package quic @@ -74,7 +78,7 @@ func (m *MockPacketConn) ReadFrom(arg0 []byte) (int, net.Addr, error) { } // ReadFrom indicates an expected call of ReadFrom. -func (mr *MockPacketConnMockRecorder) ReadFrom(arg0 interface{}) *gomock.Call { +func (mr *MockPacketConnMockRecorder) ReadFrom(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadFrom", reflect.TypeOf((*MockPacketConn)(nil).ReadFrom), arg0) } @@ -88,7 +92,7 @@ func (m *MockPacketConn) SetDeadline(arg0 time.Time) error { } // SetDeadline indicates an expected call of SetDeadline. -func (mr *MockPacketConnMockRecorder) SetDeadline(arg0 interface{}) *gomock.Call { +func (mr *MockPacketConnMockRecorder) SetDeadline(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetDeadline), arg0) } @@ -102,7 +106,7 @@ func (m *MockPacketConn) SetReadDeadline(arg0 time.Time) error { } // SetReadDeadline indicates an expected call of SetReadDeadline. -func (mr *MockPacketConnMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call { +func (mr *MockPacketConnMockRecorder) SetReadDeadline(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetReadDeadline), arg0) } @@ -116,7 +120,7 @@ func (m *MockPacketConn) SetWriteDeadline(arg0 time.Time) error { } // SetWriteDeadline indicates an expected call of SetWriteDeadline. -func (mr *MockPacketConnMockRecorder) SetWriteDeadline(arg0 interface{}) *gomock.Call { +func (mr *MockPacketConnMockRecorder) SetWriteDeadline(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetWriteDeadline), arg0) } @@ -131,7 +135,7 @@ func (m *MockPacketConn) WriteTo(arg0 []byte, arg1 net.Addr) (int, error) { } // WriteTo indicates an expected call of WriteTo. -func (mr *MockPacketConnMockRecorder) WriteTo(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockPacketConnMockRecorder) WriteTo(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteTo", reflect.TypeOf((*MockPacketConn)(nil).WriteTo), arg0, arg1) } diff --git a/mock_quic_conn_test.go b/mock_quic_conn_test.go index 20015c661db..d30a939dabc 100644 --- a/mock_quic_conn_test.go +++ b/mock_quic_conn_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: QUICConn) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_quic_conn_test.go github.com/quic-go/quic-go QUICConn +// // Package quic is a generated GoMock package. package quic @@ -47,7 +51,7 @@ func (m *MockQUICConn) AcceptStream(arg0 context.Context) (Stream, error) { } // AcceptStream indicates an expected call of AcceptStream. -func (mr *MockQUICConnMockRecorder) AcceptStream(arg0 interface{}) *gomock.Call { +func (mr *MockQUICConnMockRecorder) AcceptStream(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptStream", reflect.TypeOf((*MockQUICConn)(nil).AcceptStream), arg0) } @@ -62,7 +66,7 @@ func (m *MockQUICConn) AcceptUniStream(arg0 context.Context) (ReceiveStream, err } // AcceptUniStream indicates an expected call of AcceptUniStream. -func (mr *MockQUICConnMockRecorder) AcceptUniStream(arg0 interface{}) *gomock.Call { +func (mr *MockQUICConnMockRecorder) AcceptUniStream(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptUniStream", reflect.TypeOf((*MockQUICConn)(nil).AcceptUniStream), arg0) } @@ -76,7 +80,7 @@ func (m *MockQUICConn) CloseWithError(arg0 qerr.ApplicationErrorCode, arg1 strin } // CloseWithError indicates an expected call of CloseWithError. -func (mr *MockQUICConnMockRecorder) CloseWithError(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockQUICConnMockRecorder) CloseWithError(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseWithError", reflect.TypeOf((*MockQUICConn)(nil).CloseWithError), arg0, arg1) } @@ -190,7 +194,7 @@ func (m *MockQUICConn) OpenStreamSync(arg0 context.Context) (Stream, error) { } // OpenStreamSync indicates an expected call of OpenStreamSync. -func (mr *MockQUICConnMockRecorder) OpenStreamSync(arg0 interface{}) *gomock.Call { +func (mr *MockQUICConnMockRecorder) OpenStreamSync(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStreamSync", reflect.TypeOf((*MockQUICConn)(nil).OpenStreamSync), arg0) } @@ -220,7 +224,7 @@ func (m *MockQUICConn) OpenUniStreamSync(arg0 context.Context) (SendStream, erro } // OpenUniStreamSync indicates an expected call of OpenUniStreamSync. -func (mr *MockQUICConnMockRecorder) OpenUniStreamSync(arg0 interface{}) *gomock.Call { +func (mr *MockQUICConnMockRecorder) OpenUniStreamSync(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStreamSync", reflect.TypeOf((*MockQUICConn)(nil).OpenUniStreamSync), arg0) } @@ -235,7 +239,7 @@ func (m *MockQUICConn) ReceiveMessage(arg0 context.Context) ([]byte, error) { } // ReceiveMessage indicates an expected call of ReceiveMessage. -func (mr *MockQUICConnMockRecorder) ReceiveMessage(arg0 interface{}) *gomock.Call { +func (mr *MockQUICConnMockRecorder) ReceiveMessage(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveMessage", reflect.TypeOf((*MockQUICConn)(nil).ReceiveMessage), arg0) } @@ -263,7 +267,7 @@ func (m *MockQUICConn) SendMessage(arg0 []byte) error { } // SendMessage indicates an expected call of SendMessage. -func (mr *MockQUICConnMockRecorder) SendMessage(arg0 interface{}) *gomock.Call { +func (mr *MockQUICConnMockRecorder) SendMessage(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockQUICConn)(nil).SendMessage), arg0) } @@ -275,7 +279,7 @@ func (m *MockQUICConn) destroy(arg0 error) { } // destroy indicates an expected call of destroy. -func (mr *MockQUICConnMockRecorder) destroy(arg0 interface{}) *gomock.Call { +func (mr *MockQUICConnMockRecorder) destroy(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "destroy", reflect.TypeOf((*MockQUICConn)(nil).destroy), arg0) } @@ -315,7 +319,7 @@ func (m *MockQUICConn) handlePacket(arg0 receivedPacket) { } // handlePacket indicates an expected call of handlePacket. -func (mr *MockQUICConnMockRecorder) handlePacket(arg0 interface{}) *gomock.Call { +func (mr *MockQUICConnMockRecorder) handlePacket(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handlePacket", reflect.TypeOf((*MockQUICConn)(nil).handlePacket), arg0) } diff --git a/mock_raw_conn_test.go b/mock_raw_conn_test.go index d462fc87dc0..bf4751d9dac 100644 --- a/mock_raw_conn_test.go +++ b/mock_raw_conn_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: RawConn) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn +// // Package quic is a generated GoMock package. package quic @@ -88,7 +92,7 @@ func (m *MockRawConn) SetReadDeadline(arg0 time.Time) error { } // SetReadDeadline indicates an expected call of SetReadDeadline. -func (mr *MockRawConnMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call { +func (mr *MockRawConnMockRecorder) SetReadDeadline(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockRawConn)(nil).SetReadDeadline), arg0) } @@ -103,7 +107,7 @@ func (m *MockRawConn) WritePacket(arg0 []byte, arg1 net.Addr, arg2 []byte, arg3 } // WritePacket indicates an expected call of WritePacket. -func (mr *MockRawConnMockRecorder) WritePacket(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockRawConnMockRecorder) WritePacket(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePacket", reflect.TypeOf((*MockRawConn)(nil).WritePacket), arg0, arg1, arg2, arg3, arg4) } diff --git a/mock_receive_stream_internal_test.go b/mock_receive_stream_internal_test.go index 518e275b8d3..74ef3fed8dc 100644 --- a/mock_receive_stream_internal_test.go +++ b/mock_receive_stream_internal_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: ReceiveStreamI) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_receive_stream_internal_test.go github.com/quic-go/quic-go ReceiveStreamI +// // Package quic is a generated GoMock package. package quic @@ -44,7 +48,7 @@ func (m *MockReceiveStreamI) CancelRead(arg0 qerr.StreamErrorCode) { } // CancelRead indicates an expected call of CancelRead. -func (mr *MockReceiveStreamIMockRecorder) CancelRead(arg0 interface{}) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) CancelRead(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRead", reflect.TypeOf((*MockReceiveStreamI)(nil).CancelRead), arg0) } @@ -59,7 +63,7 @@ func (m *MockReceiveStreamI) Read(arg0 []byte) (int, error) { } // Read indicates an expected call of Read. -func (mr *MockReceiveStreamIMockRecorder) Read(arg0 interface{}) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) Read(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockReceiveStreamI)(nil).Read), arg0) } @@ -73,7 +77,7 @@ func (m *MockReceiveStreamI) SetReadDeadline(arg0 time.Time) error { } // SetReadDeadline indicates an expected call of SetReadDeadline. -func (mr *MockReceiveStreamIMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) SetReadDeadline(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockReceiveStreamI)(nil).SetReadDeadline), arg0) } @@ -99,7 +103,7 @@ func (m *MockReceiveStreamI) closeForShutdown(arg0 error) { } // closeForShutdown indicates an expected call of closeForShutdown. -func (mr *MockReceiveStreamIMockRecorder) closeForShutdown(arg0 interface{}) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) closeForShutdown(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "closeForShutdown", reflect.TypeOf((*MockReceiveStreamI)(nil).closeForShutdown), arg0) } @@ -127,7 +131,7 @@ func (m *MockReceiveStreamI) handleResetStreamFrame(arg0 *wire.ResetStreamFrame) } // handleResetStreamFrame indicates an expected call of handleResetStreamFrame. -func (mr *MockReceiveStreamIMockRecorder) handleResetStreamFrame(arg0 interface{}) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) handleResetStreamFrame(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleResetStreamFrame", reflect.TypeOf((*MockReceiveStreamI)(nil).handleResetStreamFrame), arg0) } @@ -141,7 +145,7 @@ func (m *MockReceiveStreamI) handleStreamFrame(arg0 *wire.StreamFrame) error { } // handleStreamFrame indicates an expected call of handleStreamFrame. -func (mr *MockReceiveStreamIMockRecorder) handleStreamFrame(arg0 interface{}) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) handleStreamFrame(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStreamFrame", reflect.TypeOf((*MockReceiveStreamI)(nil).handleStreamFrame), arg0) } diff --git a/mock_sealing_manager_test.go b/mock_sealing_manager_test.go index b77c747a38b..c8ecaad238e 100644 --- a/mock_sealing_manager_test.go +++ b/mock_sealing_manager_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: SealingManager) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_sealing_manager_test.go github.com/quic-go/quic-go SealingManager +// // Package quic is a generated GoMock package. package quic diff --git a/mock_send_conn_test.go b/mock_send_conn_test.go index 6568f9e5ffb..407c798b89c 100644 --- a/mock_send_conn_test.go +++ b/mock_send_conn_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: SendConn) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn +// // Package quic is a generated GoMock package. package quic @@ -86,7 +90,7 @@ func (m *MockSendConn) Write(arg0 []byte, arg1 uint16, arg2 protocol.ECN) error } // Write indicates an expected call of Write. -func (mr *MockSendConnMockRecorder) Write(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockSendConnMockRecorder) Write(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendConn)(nil).Write), arg0, arg1, arg2) } diff --git a/mock_send_stream_internal_test.go b/mock_send_stream_internal_test.go index 4fb89a35371..ded44a85a1e 100644 --- a/mock_send_stream_internal_test.go +++ b/mock_send_stream_internal_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: SendStreamI) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_send_stream_internal_test.go github.com/quic-go/quic-go SendStreamI +// // Package quic is a generated GoMock package. package quic @@ -46,7 +50,7 @@ func (m *MockSendStreamI) CancelWrite(arg0 qerr.StreamErrorCode) { } // CancelWrite indicates an expected call of CancelWrite. -func (mr *MockSendStreamIMockRecorder) CancelWrite(arg0 interface{}) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) CancelWrite(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelWrite", reflect.TypeOf((*MockSendStreamI)(nil).CancelWrite), arg0) } @@ -88,7 +92,7 @@ func (m *MockSendStreamI) SetWriteDeadline(arg0 time.Time) error { } // SetWriteDeadline indicates an expected call of SetWriteDeadline. -func (mr *MockSendStreamIMockRecorder) SetWriteDeadline(arg0 interface{}) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) SetWriteDeadline(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockSendStreamI)(nil).SetWriteDeadline), arg0) } @@ -117,7 +121,7 @@ func (m *MockSendStreamI) Write(arg0 []byte) (int, error) { } // Write indicates an expected call of Write. -func (mr *MockSendStreamIMockRecorder) Write(arg0 interface{}) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) Write(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendStreamI)(nil).Write), arg0) } @@ -129,7 +133,7 @@ func (m *MockSendStreamI) closeForShutdown(arg0 error) { } // closeForShutdown indicates an expected call of closeForShutdown. -func (mr *MockSendStreamIMockRecorder) closeForShutdown(arg0 interface{}) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) closeForShutdown(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "closeForShutdown", reflect.TypeOf((*MockSendStreamI)(nil).closeForShutdown), arg0) } @@ -141,7 +145,7 @@ func (m *MockSendStreamI) handleStopSendingFrame(arg0 *wire.StopSendingFrame) { } // handleStopSendingFrame indicates an expected call of handleStopSendingFrame. -func (mr *MockSendStreamIMockRecorder) handleStopSendingFrame(arg0 interface{}) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) handleStopSendingFrame(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStopSendingFrame", reflect.TypeOf((*MockSendStreamI)(nil).handleStopSendingFrame), arg0) } @@ -171,7 +175,7 @@ func (m *MockSendStreamI) popStreamFrame(arg0 protocol.ByteCount, arg1 protocol. } // popStreamFrame indicates an expected call of popStreamFrame. -func (mr *MockSendStreamIMockRecorder) popStreamFrame(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) popStreamFrame(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "popStreamFrame", reflect.TypeOf((*MockSendStreamI)(nil).popStreamFrame), arg0, arg1) } @@ -183,7 +187,7 @@ func (m *MockSendStreamI) updateSendWindow(arg0 protocol.ByteCount) { } // updateSendWindow indicates an expected call of updateSendWindow. -func (mr *MockSendStreamIMockRecorder) updateSendWindow(arg0 interface{}) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) updateSendWindow(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "updateSendWindow", reflect.TypeOf((*MockSendStreamI)(nil).updateSendWindow), arg0) } diff --git a/mock_sender_test.go b/mock_sender_test.go index 67bb9d09e42..2565a8fa7d6 100644 --- a/mock_sender_test.go +++ b/mock_sender_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: Sender) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender +// // Package quic is a generated GoMock package. package quic @@ -81,7 +85,7 @@ func (m *MockSender) Send(arg0 *packetBuffer, arg1 uint16, arg2 protocol.ECN) { } // Send indicates an expected call of Send. -func (mr *MockSenderMockRecorder) Send(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) Send(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockSender)(nil).Send), arg0, arg1, arg2) } diff --git a/mock_stream_getter_test.go b/mock_stream_getter_test.go index 0ff7f13fbbe..d0acde1d6f6 100644 --- a/mock_stream_getter_test.go +++ b/mock_stream_getter_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: StreamGetter) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_getter_test.go github.com/quic-go/quic-go StreamGetter +// // Package quic is a generated GoMock package. package quic @@ -44,7 +48,7 @@ func (m *MockStreamGetter) GetOrOpenReceiveStream(arg0 protocol.StreamID) (recei } // GetOrOpenReceiveStream indicates an expected call of GetOrOpenReceiveStream. -func (mr *MockStreamGetterMockRecorder) GetOrOpenReceiveStream(arg0 interface{}) *gomock.Call { +func (mr *MockStreamGetterMockRecorder) GetOrOpenReceiveStream(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenReceiveStream", reflect.TypeOf((*MockStreamGetter)(nil).GetOrOpenReceiveStream), arg0) } @@ -59,7 +63,7 @@ func (m *MockStreamGetter) GetOrOpenSendStream(arg0 protocol.StreamID) (sendStre } // GetOrOpenSendStream indicates an expected call of GetOrOpenSendStream. -func (mr *MockStreamGetterMockRecorder) GetOrOpenSendStream(arg0 interface{}) *gomock.Call { +func (mr *MockStreamGetterMockRecorder) GetOrOpenSendStream(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenSendStream", reflect.TypeOf((*MockStreamGetter)(nil).GetOrOpenSendStream), arg0) } diff --git a/mock_stream_internal_test.go b/mock_stream_internal_test.go index 447438c1575..9121a46178c 100644 --- a/mock_stream_internal_test.go +++ b/mock_stream_internal_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: StreamI) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_internal_test.go github.com/quic-go/quic-go StreamI +// // Package quic is a generated GoMock package. package quic @@ -46,7 +50,7 @@ func (m *MockStreamI) CancelRead(arg0 qerr.StreamErrorCode) { } // CancelRead indicates an expected call of CancelRead. -func (mr *MockStreamIMockRecorder) CancelRead(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) CancelRead(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRead", reflect.TypeOf((*MockStreamI)(nil).CancelRead), arg0) } @@ -58,7 +62,7 @@ func (m *MockStreamI) CancelWrite(arg0 qerr.StreamErrorCode) { } // CancelWrite indicates an expected call of CancelWrite. -func (mr *MockStreamIMockRecorder) CancelWrite(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) CancelWrite(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelWrite", reflect.TypeOf((*MockStreamI)(nil).CancelWrite), arg0) } @@ -101,7 +105,7 @@ func (m *MockStreamI) Read(arg0 []byte) (int, error) { } // Read indicates an expected call of Read. -func (mr *MockStreamIMockRecorder) Read(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) Read(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStreamI)(nil).Read), arg0) } @@ -115,7 +119,7 @@ func (m *MockStreamI) SetDeadline(arg0 time.Time) error { } // SetDeadline indicates an expected call of SetDeadline. -func (mr *MockStreamIMockRecorder) SetDeadline(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) SetDeadline(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStreamI)(nil).SetDeadline), arg0) } @@ -129,7 +133,7 @@ func (m *MockStreamI) SetReadDeadline(arg0 time.Time) error { } // SetReadDeadline indicates an expected call of SetReadDeadline. -func (mr *MockStreamIMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) SetReadDeadline(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStreamI)(nil).SetReadDeadline), arg0) } @@ -143,7 +147,7 @@ func (m *MockStreamI) SetWriteDeadline(arg0 time.Time) error { } // SetWriteDeadline indicates an expected call of SetWriteDeadline. -func (mr *MockStreamIMockRecorder) SetWriteDeadline(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) SetWriteDeadline(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStreamI)(nil).SetWriteDeadline), arg0) } @@ -172,7 +176,7 @@ func (m *MockStreamI) Write(arg0 []byte) (int, error) { } // Write indicates an expected call of Write. -func (mr *MockStreamIMockRecorder) Write(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) Write(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStreamI)(nil).Write), arg0) } @@ -184,7 +188,7 @@ func (m *MockStreamI) closeForShutdown(arg0 error) { } // closeForShutdown indicates an expected call of closeForShutdown. -func (mr *MockStreamIMockRecorder) closeForShutdown(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) closeForShutdown(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "closeForShutdown", reflect.TypeOf((*MockStreamI)(nil).closeForShutdown), arg0) } @@ -212,7 +216,7 @@ func (m *MockStreamI) handleResetStreamFrame(arg0 *wire.ResetStreamFrame) error } // handleResetStreamFrame indicates an expected call of handleResetStreamFrame. -func (mr *MockStreamIMockRecorder) handleResetStreamFrame(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) handleResetStreamFrame(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleResetStreamFrame", reflect.TypeOf((*MockStreamI)(nil).handleResetStreamFrame), arg0) } @@ -224,7 +228,7 @@ func (m *MockStreamI) handleStopSendingFrame(arg0 *wire.StopSendingFrame) { } // handleStopSendingFrame indicates an expected call of handleStopSendingFrame. -func (mr *MockStreamIMockRecorder) handleStopSendingFrame(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) handleStopSendingFrame(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStopSendingFrame", reflect.TypeOf((*MockStreamI)(nil).handleStopSendingFrame), arg0) } @@ -238,7 +242,7 @@ func (m *MockStreamI) handleStreamFrame(arg0 *wire.StreamFrame) error { } // handleStreamFrame indicates an expected call of handleStreamFrame. -func (mr *MockStreamIMockRecorder) handleStreamFrame(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) handleStreamFrame(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStreamFrame", reflect.TypeOf((*MockStreamI)(nil).handleStreamFrame), arg0) } @@ -268,7 +272,7 @@ func (m *MockStreamI) popStreamFrame(arg0 protocol.ByteCount, arg1 protocol.Vers } // popStreamFrame indicates an expected call of popStreamFrame. -func (mr *MockStreamIMockRecorder) popStreamFrame(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) popStreamFrame(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "popStreamFrame", reflect.TypeOf((*MockStreamI)(nil).popStreamFrame), arg0, arg1) } @@ -280,7 +284,7 @@ func (m *MockStreamI) updateSendWindow(arg0 protocol.ByteCount) { } // updateSendWindow indicates an expected call of updateSendWindow. -func (mr *MockStreamIMockRecorder) updateSendWindow(arg0 interface{}) *gomock.Call { +func (mr *MockStreamIMockRecorder) updateSendWindow(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "updateSendWindow", reflect.TypeOf((*MockStreamI)(nil).updateSendWindow), arg0) } diff --git a/mock_stream_manager_test.go b/mock_stream_manager_test.go index dc4a39eb37a..3dacd419b94 100644 --- a/mock_stream_manager_test.go +++ b/mock_stream_manager_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: StreamManager) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_manager_test.go github.com/quic-go/quic-go StreamManager +// // Package quic is a generated GoMock package. package quic @@ -46,7 +50,7 @@ func (m *MockStreamManager) AcceptStream(arg0 context.Context) (Stream, error) { } // AcceptStream indicates an expected call of AcceptStream. -func (mr *MockStreamManagerMockRecorder) AcceptStream(arg0 interface{}) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) AcceptStream(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptStream", reflect.TypeOf((*MockStreamManager)(nil).AcceptStream), arg0) } @@ -61,7 +65,7 @@ func (m *MockStreamManager) AcceptUniStream(arg0 context.Context) (ReceiveStream } // AcceptUniStream indicates an expected call of AcceptUniStream. -func (mr *MockStreamManagerMockRecorder) AcceptUniStream(arg0 interface{}) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) AcceptUniStream(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptUniStream", reflect.TypeOf((*MockStreamManager)(nil).AcceptUniStream), arg0) } @@ -73,7 +77,7 @@ func (m *MockStreamManager) CloseWithError(arg0 error) { } // CloseWithError indicates an expected call of CloseWithError. -func (mr *MockStreamManagerMockRecorder) CloseWithError(arg0 interface{}) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) CloseWithError(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseWithError", reflect.TypeOf((*MockStreamManager)(nil).CloseWithError), arg0) } @@ -87,7 +91,7 @@ func (m *MockStreamManager) DeleteStream(arg0 protocol.StreamID) error { } // DeleteStream indicates an expected call of DeleteStream. -func (mr *MockStreamManagerMockRecorder) DeleteStream(arg0 interface{}) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) DeleteStream(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStream", reflect.TypeOf((*MockStreamManager)(nil).DeleteStream), arg0) } @@ -102,7 +106,7 @@ func (m *MockStreamManager) GetOrOpenReceiveStream(arg0 protocol.StreamID) (rece } // GetOrOpenReceiveStream indicates an expected call of GetOrOpenReceiveStream. -func (mr *MockStreamManagerMockRecorder) GetOrOpenReceiveStream(arg0 interface{}) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) GetOrOpenReceiveStream(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenReceiveStream", reflect.TypeOf((*MockStreamManager)(nil).GetOrOpenReceiveStream), arg0) } @@ -117,7 +121,7 @@ func (m *MockStreamManager) GetOrOpenSendStream(arg0 protocol.StreamID) (sendStr } // GetOrOpenSendStream indicates an expected call of GetOrOpenSendStream. -func (mr *MockStreamManagerMockRecorder) GetOrOpenSendStream(arg0 interface{}) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) GetOrOpenSendStream(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenSendStream", reflect.TypeOf((*MockStreamManager)(nil).GetOrOpenSendStream), arg0) } @@ -129,7 +133,7 @@ func (m *MockStreamManager) HandleMaxStreamsFrame(arg0 *wire.MaxStreamsFrame) { } // HandleMaxStreamsFrame indicates an expected call of HandleMaxStreamsFrame. -func (mr *MockStreamManagerMockRecorder) HandleMaxStreamsFrame(arg0 interface{}) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) HandleMaxStreamsFrame(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMaxStreamsFrame", reflect.TypeOf((*MockStreamManager)(nil).HandleMaxStreamsFrame), arg0) } @@ -159,7 +163,7 @@ func (m *MockStreamManager) OpenStreamSync(arg0 context.Context) (Stream, error) } // OpenStreamSync indicates an expected call of OpenStreamSync. -func (mr *MockStreamManagerMockRecorder) OpenStreamSync(arg0 interface{}) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) OpenStreamSync(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStreamSync", reflect.TypeOf((*MockStreamManager)(nil).OpenStreamSync), arg0) } @@ -189,7 +193,7 @@ func (m *MockStreamManager) OpenUniStreamSync(arg0 context.Context) (SendStream, } // OpenUniStreamSync indicates an expected call of OpenUniStreamSync. -func (mr *MockStreamManagerMockRecorder) OpenUniStreamSync(arg0 interface{}) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) OpenUniStreamSync(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStreamSync", reflect.TypeOf((*MockStreamManager)(nil).OpenUniStreamSync), arg0) } @@ -213,7 +217,7 @@ func (m *MockStreamManager) UpdateLimits(arg0 *wire.TransportParameters) { } // UpdateLimits indicates an expected call of UpdateLimits. -func (mr *MockStreamManagerMockRecorder) UpdateLimits(arg0 interface{}) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) UpdateLimits(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLimits", reflect.TypeOf((*MockStreamManager)(nil).UpdateLimits), arg0) } diff --git a/mock_stream_sender_test.go b/mock_stream_sender_test.go index 94606942d64..87a05a485e8 100644 --- a/mock_stream_sender_test.go +++ b/mock_stream_sender_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: StreamSender) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_sender_test.go github.com/quic-go/quic-go StreamSender +// // Package quic is a generated GoMock package. package quic @@ -42,7 +46,7 @@ func (m *MockStreamSender) onHasStreamData(arg0 protocol.StreamID) { } // onHasStreamData indicates an expected call of onHasStreamData. -func (mr *MockStreamSenderMockRecorder) onHasStreamData(arg0 interface{}) *gomock.Call { +func (mr *MockStreamSenderMockRecorder) onHasStreamData(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "onHasStreamData", reflect.TypeOf((*MockStreamSender)(nil).onHasStreamData), arg0) } @@ -54,7 +58,7 @@ func (m *MockStreamSender) onStreamCompleted(arg0 protocol.StreamID) { } // onStreamCompleted indicates an expected call of onStreamCompleted. -func (mr *MockStreamSenderMockRecorder) onStreamCompleted(arg0 interface{}) *gomock.Call { +func (mr *MockStreamSenderMockRecorder) onStreamCompleted(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "onStreamCompleted", reflect.TypeOf((*MockStreamSender)(nil).onStreamCompleted), arg0) } @@ -66,7 +70,7 @@ func (m *MockStreamSender) queueControlFrame(arg0 wire.Frame) { } // queueControlFrame indicates an expected call of queueControlFrame. -func (mr *MockStreamSenderMockRecorder) queueControlFrame(arg0 interface{}) *gomock.Call { +func (mr *MockStreamSenderMockRecorder) queueControlFrame(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "queueControlFrame", reflect.TypeOf((*MockStreamSender)(nil).queueControlFrame), arg0) } diff --git a/mock_token_store_test.go b/mock_token_store_test.go index 8576a3e205c..3d251052a3f 100644 --- a/mock_token_store_test.go +++ b/mock_token_store_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: TokenStore) - +// +// Generated by this command: +// +// mockgen -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_token_store_test.go github.com/quic-go/quic-go TokenStore +// // Package quic is a generated GoMock package. package quic @@ -42,7 +46,7 @@ func (m *MockTokenStore) Pop(arg0 string) *ClientToken { } // Pop indicates an expected call of Pop. -func (mr *MockTokenStoreMockRecorder) Pop(arg0 interface{}) *gomock.Call { +func (mr *MockTokenStoreMockRecorder) Pop(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pop", reflect.TypeOf((*MockTokenStore)(nil).Pop), arg0) } @@ -54,7 +58,7 @@ func (m *MockTokenStore) Put(arg0 string, arg1 *ClientToken) { } // Put indicates an expected call of Put. -func (mr *MockTokenStoreMockRecorder) Put(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockTokenStoreMockRecorder) Put(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockTokenStore)(nil).Put), arg0, arg1) } diff --git a/mock_unpacker_test.go b/mock_unpacker_test.go index 272585c0453..372e4ac3947 100644 --- a/mock_unpacker_test.go +++ b/mock_unpacker_test.go @@ -1,6 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/quic-go/quic-go (interfaces: Unpacker) - +// +// Generated by this command: +// +// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_unpacker_test.go github.com/quic-go/quic-go Unpacker +// // Package quic is a generated GoMock package. package quic @@ -46,7 +50,7 @@ func (m *MockUnpacker) UnpackLongHeader(arg0 *wire.Header, arg1 time.Time, arg2 } // UnpackLongHeader indicates an expected call of UnpackLongHeader. -func (mr *MockUnpackerMockRecorder) UnpackLongHeader(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockUnpackerMockRecorder) UnpackLongHeader(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnpackLongHeader", reflect.TypeOf((*MockUnpacker)(nil).UnpackLongHeader), arg0, arg1, arg2, arg3) } @@ -64,7 +68,7 @@ func (m *MockUnpacker) UnpackShortHeader(arg0 time.Time, arg1 []byte) (protocol. } // UnpackShortHeader indicates an expected call of UnpackShortHeader. -func (mr *MockUnpackerMockRecorder) UnpackShortHeader(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockUnpackerMockRecorder) UnpackShortHeader(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnpackShortHeader", reflect.TypeOf((*MockUnpacker)(nil).UnpackShortHeader), arg0, arg1) } diff --git a/server_test.go b/server_test.go index 6e50de82926..6944a81e519 100644 --- a/server_test.go +++ b/server_test.go @@ -1412,7 +1412,7 @@ var _ = Describe("Server", func() { _ protocol.VersionNumber, ) quicConn { conn := NewMockQUICConn(mockCtrl) - var calls []*gomock.Call + var calls []any calls = append(calls, conn.EXPECT().handlePacket(initial)) for _, p := range zeroRTTPackets { calls = append(calls, conn.EXPECT().handlePacket(p)) From 348042ee4c075e82eaecd95f1f6606bc9cfc69ad Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 25 Sep 2023 09:14:07 +0000 Subject: [PATCH 080/225] simplify sending of INVALID_TOKEN errors (#4090) --- server.go | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/server.go b/server.go index 119289b3970..01f7c92b167 100644 --- a/server.go +++ b/server.go @@ -54,6 +54,11 @@ type zeroRTTQueue struct { expiration time.Time } +type rejectedPacket struct { + receivedPacket + hdr *wire.Header +} + // A Listener of QUIC type baseServer struct { mutex sync.Mutex @@ -104,7 +109,7 @@ type baseServer struct { closed bool running chan struct{} // closed as soon as run() returns versionNegotiationQueue chan receivedPacket - invalidTokenQueue chan receivedPacket + invalidTokenQueue chan rejectedPacket connQueue chan quicConn connQueueLen int32 // to be used as an atomic @@ -245,7 +250,7 @@ func newServer( running: make(chan struct{}), receivedPackets: make(chan receivedPacket, protocol.MaxServerUnprocessedPackets), versionNegotiationQueue: make(chan receivedPacket, 4), - invalidTokenQueue: make(chan receivedPacket, 4), + invalidTokenQueue: make(chan rejectedPacket, 4), newConn: newConnection, tracer: tracer, logger: utils.DefaultLogger.WithPrefix("server"), @@ -580,7 +585,12 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error // For Retry tokens, we send an INVALID_ERROR if // * the token is too old, or // * the token is invalid, in case of a retry token. - s.enqueueInvalidToken(p) + select { + case s.invalidTokenQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}: + default: + // it's fine to drop INVALID_TOKEN packets when we are busy + p.buffer.Release() + } return nil } } @@ -748,29 +758,12 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info packe return err } -func (s *baseServer) enqueueInvalidToken(p receivedPacket) { - select { - case s.invalidTokenQueue <- p: - default: - // it's fine to drop INVALID_TOKEN packets when we are busy - p.buffer.Release() - } -} - -func (s *baseServer) maybeSendInvalidToken(p receivedPacket) { +func (s *baseServer) maybeSendInvalidToken(p rejectedPacket) { defer p.buffer.Release() - hdr, _, _, err := wire.ParsePacket(p.data) - if err != nil { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError) - } - s.logger.Debugf("Error parsing packet: %s", err) - return - } - // Only send INVALID_TOKEN if we can unprotect the packet. // This makes sure that we won't send it for packets that were corrupted. + hdr := p.hdr sealer, opener := handshake.NewInitialAEAD(hdr.DestConnectionID, protocol.PerspectiveServer, hdr.Version) data := p.data[:hdr.ParsedLen()+hdr.Length] extHdr, err := unpackLongHeader(opener, hdr, data, hdr.Version) From ae2ef95fa399c217477d6ac22449254bcdf68837 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 25 Sep 2023 09:31:27 +0000 Subject: [PATCH 081/225] don't spawn a new Go routine to send a CONNECTION_REFUSED packet (#4091) --- server.go | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/server.go b/server.go index 01f7c92b167..e90e1725d85 100644 --- a/server.go +++ b/server.go @@ -110,6 +110,7 @@ type baseServer struct { running chan struct{} // closed as soon as run() returns versionNegotiationQueue chan receivedPacket invalidTokenQueue chan rejectedPacket + connectionRefusedQueue chan rejectedPacket connQueue chan quicConn connQueueLen int32 // to be used as an atomic @@ -251,6 +252,7 @@ func newServer( receivedPackets: make(chan receivedPacket, protocol.MaxServerUnprocessedPackets), versionNegotiationQueue: make(chan receivedPacket, 4), invalidTokenQueue: make(chan rejectedPacket, 4), + connectionRefusedQueue: make(chan rejectedPacket, 4), newConn: newConnection, tracer: tracer, logger: utils.DefaultLogger.WithPrefix("server"), @@ -295,6 +297,8 @@ func (s *baseServer) runSendQueue() { s.maybeSendVersionNegotiationPacket(p) case p := <-s.invalidTokenQueue: s.maybeSendInvalidToken(p) + case p := <-s.connectionRefusedQueue: + s.sendConnectionRefused(p) } } } @@ -588,7 +592,7 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error select { case s.invalidTokenQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}: default: - // it's fine to drop INVALID_TOKEN packets when we are busy + // drop packet if we can't send out the INVALID_TOKEN packets fast enough p.buffer.Release() } return nil @@ -608,12 +612,12 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error if queueLen := atomic.LoadInt32(&s.connQueueLen); queueLen >= protocol.MaxAcceptQueueSize { s.logger.Debugf("Rejecting new connection. Server currently busy. Accept queue length: %d (max %d)", queueLen, protocol.MaxAcceptQueueSize) - go func() { - defer p.buffer.Release() - if err := s.sendConnectionRefused(p.remoteAddr, hdr, p.info); err != nil { - s.logger.Debugf("Error rejecting connection: %s", err) - } - }() + select { + case s.connectionRefusedQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}: + default: + // drop packet if we can't send out the CONNECTION_REFUSED fast enough + p.buffer.Release() + } return nil } @@ -673,12 +677,12 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error return conn, true }); !added { - go func() { - defer p.buffer.Release() - if err := s.sendConnectionRefused(p.remoteAddr, hdr, p.info); err != nil { - s.logger.Debugf("Error rejecting connection: %s", err) - } - }() + select { + case s.connectionRefusedQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}: + default: + // drop packet if we can't send out the CONNECTION_REFUSED fast enough + p.buffer.Release() + } return nil } go conn.run() @@ -790,9 +794,12 @@ func (s *baseServer) maybeSendInvalidToken(p rejectedPacket) { } } -func (s *baseServer) sendConnectionRefused(remoteAddr net.Addr, hdr *wire.Header, info packetInfo) error { - sealer, _ := handshake.NewInitialAEAD(hdr.DestConnectionID, protocol.PerspectiveServer, hdr.Version) - return s.sendError(remoteAddr, hdr, sealer, qerr.ConnectionRefused, info) +func (s *baseServer) sendConnectionRefused(p rejectedPacket) { + defer p.buffer.Release() + sealer, _ := handshake.NewInitialAEAD(p.hdr.DestConnectionID, protocol.PerspectiveServer, p.hdr.Version) + if err := s.sendError(p.remoteAddr, p.hdr, sealer, qerr.ConnectionRefused, p.info); err != nil { + s.logger.Debugf("Error sending CONNECTION_REFUSED error: %s", err) + } } // sendError sends the error as a response to the packet received with header hdr From 49e588a6a9905446e49d382d78115e6e960b1144 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 25 Sep 2023 11:21:51 +0000 Subject: [PATCH 082/225] don't spawn a new Go routine to send a Retry packet (#4092) --- server.go | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/server.go b/server.go index e90e1725d85..8353cdeba59 100644 --- a/server.go +++ b/server.go @@ -111,6 +111,7 @@ type baseServer struct { versionNegotiationQueue chan receivedPacket invalidTokenQueue chan rejectedPacket connectionRefusedQueue chan rejectedPacket + retryQueue chan rejectedPacket connQueue chan quicConn connQueueLen int32 // to be used as an atomic @@ -253,6 +254,7 @@ func newServer( versionNegotiationQueue: make(chan receivedPacket, 4), invalidTokenQueue: make(chan rejectedPacket, 4), connectionRefusedQueue: make(chan rejectedPacket, 4), + retryQueue: make(chan rejectedPacket, 8), newConn: newConnection, tracer: tracer, logger: utils.DefaultLogger.WithPrefix("server"), @@ -299,6 +301,8 @@ func (s *baseServer) runSendQueue() { s.maybeSendInvalidToken(p) case p := <-s.connectionRefusedQueue: s.sendConnectionRefused(p) + case p := <-s.retryQueue: + s.sendRetry(p) } } } @@ -601,12 +605,12 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error if token == nil && s.config.RequireAddressValidation(p.remoteAddr) { // Retry invalidates all 0-RTT packets sent. delete(s.zeroRTTQueues, hdr.DestConnectionID) - go func() { - defer p.buffer.Release() - if err := s.sendRetry(p.remoteAddr, hdr, p.info); err != nil { - s.logger.Debugf("Error sending Retry: %s", err) - } - }() + select { + case s.retryQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}: + default: + // drop packet if we can't send out Retry packets fast enough + p.buffer.Release() + } return nil } @@ -722,7 +726,14 @@ func (s *baseServer) handleNewConn(conn quicConn) { } } -func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info packetInfo) error { +func (s *baseServer) sendRetry(p rejectedPacket) { + if err := s.sendRetryPacket(p); err != nil { + s.logger.Debugf("Error sending Retry packet: %s", err) + } +} + +func (s *baseServer) sendRetryPacket(p rejectedPacket) error { + hdr := p.hdr // Log the Initial packet now. // If no Retry is sent, the packet will be logged by the connection. (&wire.ExtendedHeader{Header: *hdr}).Log(s.logger) @@ -730,7 +741,7 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info packe if err != nil { return err } - token, err := s.tokenGenerator.NewRetryToken(remoteAddr, hdr.DestConnectionID, srcConnID) + token, err := s.tokenGenerator.NewRetryToken(p.remoteAddr, hdr.DestConnectionID, srcConnID) if err != nil { return err } @@ -756,9 +767,9 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info packe tag := handshake.GetRetryIntegrityTag(buf.Data, hdr.DestConnectionID, hdr.Version) buf.Data = append(buf.Data, tag[:]...) if s.tracer != nil && s.tracer.SentPacket != nil { - s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(buf.Data)), nil) + s.tracer.SentPacket(p.remoteAddr, &replyHdr.Header, protocol.ByteCount(len(buf.Data)), nil) } - _, err = s.conn.WritePacket(buf.Data, remoteAddr, info.OOB(), 0, protocol.ECNUnsupported) + _, err = s.conn.WritePacket(buf.Data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported) return err } From f49944b737ff33d0e0e985482b86871469918ff8 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 13 Oct 2023 14:05:47 +0700 Subject: [PATCH 083/225] README: add qlog to list of supported RFCs, add an example (#4102) --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 976a07ccd43..e6beb8aa5b0 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ In addition to these base RFCs, it also implements the following RFCs: * Unreliable Datagram Extension ([RFC 9221](https://datatracker.ietf.org/doc/html/rfc9221)) * Datagram Packetization Layer Path MTU Discovery (DPLPMTUD, [RFC 8899](https://datatracker.ietf.org/doc/html/rfc8899)) * QUIC Version 2 ([RFC 9369](https://datatracker.ietf.org/doc/html/rfc9369)) +* QUIC Event Logging using qlog ([draft-ietf-quic-qlog-main-schema](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-main-schema/) and [draft-ietf-quic-qlog-quic-events](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-quic-events/)) ## Using QUIC @@ -174,6 +175,30 @@ msg, err := conn.ReceiveMessage() Note that this code path is currently not optimized. It works for datagrams that are sent occasionally, but it doesn't achieve the same throughput as writing data on a stream. Please get in touch on issue #3766 if your use case relies on high datagram throughput, or if you'd like to help fix this issue. There are also some restrictions regarding the maximum message size (see #3599). +### QUIC Event Logging using qlog + +quic-go logs a wide range of events defined in [draft-ietf-quic-qlog-quic-events](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-quic-events/), providing comprehensive insights in the internals of a QUIC connection. + +qlog files can be processed by a number of 3rd-party tools. [qviz](https://qvis.quictools.info/) has proven very useful for debugging all kinds of QUIC connection failures. + +qlog is activated by setting a `Tracer` callback on the `Config`. It is called as soon as quic-go decides to starts the QUIC handshake on a new connection. +A useful implementation of this callback could look like this: +```go +quic.Config{ + Tracer: func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer { + role := "server" + if p == logging.PerspectiveClient { + role = "client" + } + filename := fmt.Sprintf("./log_%x_%s.qlog", connID, role) + f, err := os.Create(filename) + // handle the error + return qlog.NewConnectionTracer(f, p, connID) + } +} +``` + +This implementation of the callback creates a new qlog file in the current directory named `log__.qlog`. ## Using HTTP/3 From 262cf0a5925389216d2a919cfbd0a30d09ed3498 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 17 Oct 2023 12:50:40 +0700 Subject: [PATCH 084/225] fix IPv4 ECN control message length on FreeBSD (#4110) --- sys_conn_helper_freebsd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys_conn_helper_freebsd.go b/sys_conn_helper_freebsd.go index 5e635b18df8..a53ca2eae0d 100644 --- a/sys_conn_helper_freebsd.go +++ b/sys_conn_helper_freebsd.go @@ -14,7 +14,7 @@ const ( ipv4PKTINFO = 0x7 ) -const ecnIPv4DataLen = 4 +const ecnIPv4DataLen = 1 const batchSize = 8 From b344940f06b9db32db79dec4c9375825e6a7963a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 17 Oct 2023 15:23:33 +0700 Subject: [PATCH 085/225] catch EPERM sendmsg errors for the very first packet on Linux (#4111) --- send_conn.go | 16 ++++++++++++++-- send_conn_test.go | 23 +++++++++++++++++++++++ sys_conn_helper_linux.go | 11 +++++++++++ sys_conn_helper_linux_test.go | 5 ++++- sys_conn_helper_nonlinux.go | 1 + sys_conn_helper_nonlinux_test.go | 5 ++++- 6 files changed, 57 insertions(+), 4 deletions(-) diff --git a/send_conn.go b/send_conn.go index 4fda1469122..498ed112b46 100644 --- a/send_conn.go +++ b/send_conn.go @@ -28,6 +28,9 @@ type sconn struct { packetInfoOOB []byte // If GSO enabled, and we receive a GSO error for this remote address, GSO is disabled. gotGSOError bool + // Used to catch the error sometimes returned by the first sendmsg call on Linux, + // see https://github.com/golang/go/issues/63322. + wroteFirstPacket bool } var _ sendConn = &sconn{} @@ -56,7 +59,7 @@ func newSendConn(c rawConn, remote net.Addr, info packetInfo, logger utils.Logge } func (c *sconn) Write(p []byte, gsoSize uint16, ecn protocol.ECN) error { - _, err := c.WritePacket(p, c.remoteAddr, c.packetInfoOOB, gsoSize, ecn) + err := c.writePacket(p, c.remoteAddr, c.packetInfoOOB, gsoSize, ecn) if err != nil && isGSOError(err) { // disable GSO for future calls c.gotGSOError = true @@ -69,7 +72,7 @@ func (c *sconn) Write(p []byte, gsoSize uint16, ecn protocol.ECN) error { if l > int(gsoSize) { l = int(gsoSize) } - if _, err := c.WritePacket(p[:l], c.remoteAddr, c.packetInfoOOB, 0, ecn); err != nil { + if err := c.writePacket(p[:l], c.remoteAddr, c.packetInfoOOB, 0, ecn); err != nil { return err } p = p[l:] @@ -79,6 +82,15 @@ func (c *sconn) Write(p []byte, gsoSize uint16, ecn protocol.ECN) error { return err } +func (c *sconn) writePacket(p []byte, addr net.Addr, oob []byte, gsoSize uint16, ecn protocol.ECN) error { + _, err := c.WritePacket(p, addr, oob, gsoSize, ecn) + if err != nil && !c.wroteFirstPacket && isPermissionError(err) { + _, err = c.WritePacket(p, addr, oob, gsoSize, ecn) + } + c.wroteFirstPacket = true + return err +} + func (c *sconn) capabilities() connCapabilities { capabilities := c.rawConn.capabilities() if capabilities.GSO { diff --git a/send_conn_test.go b/send_conn_test.go index bbac8fe7c3d..f69c77e7619 100644 --- a/send_conn_test.go +++ b/send_conn_test.go @@ -76,4 +76,27 @@ var _ = Describe("Connection (for sending packets)", func() { Expect(c.capabilities().GSO).To(BeFalse()) }) } + + if runtime.GOOS == "linux" { + It("doesn't fail if the very first sendmsg call fails", func() { + rawConn := NewMockRawConn(mockCtrl) + rawConn.EXPECT().LocalAddr() + rawConn.EXPECT().capabilities().AnyTimes() + c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) + gomock.InOrder( + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any(), gomock.Any(), protocol.ECNCE).Return(0, errNotPermitted), + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any(), uint16(0), protocol.ECNCE).Return(6, nil), + ) + Expect(c.Write([]byte("foobar"), 0, protocol.ECNCE)).To(Succeed()) + }) + + It("fails if the sendmsg calls fail multiple times", func() { + rawConn := NewMockRawConn(mockCtrl) + rawConn.EXPECT().LocalAddr() + rawConn.EXPECT().capabilities().AnyTimes() + c := newSendConn(rawConn, remoteAddr, packetInfo{}, utils.DefaultLogger) + rawConn.EXPECT().WritePacket([]byte("foobar"), remoteAddr, gomock.Any(), gomock.Any(), protocol.ECNCE).Return(0, errNotPermitted).Times(2) + Expect(c.Write([]byte("foobar"), 0, protocol.ECNCE)).To(MatchError(errNotPermitted)) + }) + } }) diff --git a/sys_conn_helper_linux.go b/sys_conn_helper_linux.go index 622f4e6f344..8e326af9817 100644 --- a/sys_conn_helper_linux.go +++ b/sys_conn_helper_linux.go @@ -97,3 +97,14 @@ func isGSOError(err error) bool { } return false } + +// The first sendmsg call on a new UDP socket sometimes errors on Linux. +// It's not clear why this happens. +// See https://github.com/golang/go/issues/63322. +func isPermissionError(err error) bool { + var serr *os.SyscallError + if errors.As(err, &serr) { + return serr.Syscall == "sendmsg" && serr.Err == unix.EPERM + } + return false +} diff --git a/sys_conn_helper_linux_test.go b/sys_conn_helper_linux_test.go index 4cf59abe22c..3385fc81d8a 100644 --- a/sys_conn_helper_linux_test.go +++ b/sys_conn_helper_linux_test.go @@ -13,7 +13,10 @@ import ( . "github.com/onsi/gomega" ) -var errGSO = &os.SyscallError{Err: unix.EIO} +var ( + errGSO = &os.SyscallError{Err: unix.EIO} + errNotPermitted = &os.SyscallError{Syscall: "sendmsg", Err: unix.EPERM} +) var _ = Describe("forcing a change of send and receive buffer sizes", func() { It("forces a change of the receive buffer size", func() { diff --git a/sys_conn_helper_nonlinux.go b/sys_conn_helper_nonlinux.go index cace82d5dcc..f8d69803b5a 100644 --- a/sys_conn_helper_nonlinux.go +++ b/sys_conn_helper_nonlinux.go @@ -7,3 +7,4 @@ func forceSetSendBuffer(c any, bytes int) error { return nil } func appendUDPSegmentSizeMsg([]byte, uint16) []byte { return nil } func isGSOError(error) bool { return false } +func isPermissionError(err error) bool { return false } diff --git a/sys_conn_helper_nonlinux_test.go b/sys_conn_helper_nonlinux_test.go index 29d42ad33ab..09671241863 100644 --- a/sys_conn_helper_nonlinux_test.go +++ b/sys_conn_helper_nonlinux_test.go @@ -4,4 +4,7 @@ package quic import "errors" -var errGSO = errors.New("fake GSO error") +var ( + errGSO = errors.New("fake GSO error") + errNotPermitted = errors.New("fake not permitted error") +) From a263164d9f0777de99f5c6cf24a2c4a986200296 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 21 Oct 2023 12:55:33 +0700 Subject: [PATCH 086/225] use new gomock feature to generate type-safe methods in mocks (#4057) --- client_test.go | 4 +- connection_test.go | 17 +- http3/client_test.go | 47 +- http3/mock_quic_early_listener_test.go | 86 +- http3/mock_roundtripcloser_test.go | 86 +- http3/mockgen.go | 4 +- http3/server_test.go | 55 +- .../mock_sent_packet_tracker_test.go | 58 +- internal/ackhandler/mockgen.go | 2 +- .../ackhandler/received_packet_handler.go | 142 ++- .../mocks/ackhandler/sent_packet_handler.go | 422 ++++++++- internal/mocks/congestion.go | 338 +++++++- internal/mocks/connection_flow_controller.go | 198 ++++- internal/mocks/crypto_setup.go | 506 ++++++++++- .../logging/internal/connection_tracer.go | 814 ++++++++++++++++-- internal/mocks/logging/internal/tracer.go | 86 +- internal/mocks/logging/mockgen.go | 4 +- internal/mocks/long_header_opener.go | 86 +- internal/mocks/mockgen.go | 24 +- internal/mocks/quic/early_conn.go | 422 ++++++++- internal/mocks/quic/stream.go | 282 +++++- internal/mocks/short_header_opener.go | 86 +- internal/mocks/short_header_sealer.go | 114 ++- internal/mocks/stream_flow_controller.go | 226 ++++- internal/mocks/tls/client_session_cache.go | 58 +- mock_ack_frame_source_test.go | 30 +- mock_batch_conn_test.go | 30 +- mock_conn_runner_test.go | 198 ++++- mock_crypto_data_handler_test.go | 58 +- mock_crypto_stream_test.go | 170 +++- mock_frame_source_test.go | 86 +- mock_mtu_discoverer_test.go | 114 ++- mock_packer_test.go | 226 ++++- mock_packet_handler_manager_test.go | 338 +++++++- mock_packet_handler_test.go | 114 ++- mock_packetconn_test.go | 198 ++++- mock_quic_conn_test.go | 618 ++++++++++++- mock_raw_conn_test.go | 170 +++- mock_receive_stream_internal_test.go | 226 ++++- mock_sealing_manager_test.go | 114 ++- mock_send_conn_test.go | 142 ++- mock_send_stream_internal_test.go | 310 ++++++- mock_sender_test.go | 142 ++- mock_stream_getter_test.go | 58 +- mock_stream_internal_test.go | 506 ++++++++++- mock_stream_manager_test.go | 394 ++++++++- mock_stream_sender_test.go | 86 +- mock_token_store_test.go | 58 +- mock_unpacker_test.go | 58 +- mockgen.go | 48 +- send_queue_test.go | 4 +- server_test.go | 21 +- transport_test.go | 3 +- 53 files changed, 7933 insertions(+), 754 deletions(-) diff --git a/client_test.go b/client_test.go index 3fa5fb5a22b..62bcef527fa 100644 --- a/client_test.go +++ b/client_test.go @@ -129,7 +129,7 @@ var _ = Describe("Client", func() { ) quicConn { Expect(enable0RTT).To(BeFalse()) conn := NewMockQUICConn(mockCtrl) - conn.EXPECT().run().Do(func() { close(run) }) + conn.EXPECT().run().Do(func() error { close(run); return nil }) c := make(chan struct{}) close(c) conn.EXPECT().HandshakeComplete().Return(c) @@ -166,7 +166,7 @@ var _ = Describe("Client", func() { ) quicConn { Expect(enable0RTT).To(BeTrue()) conn := NewMockQUICConn(mockCtrl) - conn.EXPECT().run().Do(func() { close(done) }) + conn.EXPECT().run().Do(func() error { close(done); return nil }) conn.EXPECT().HandshakeComplete().Return(make(chan struct{})) conn.EXPECT().earlyConnReady().Return(readyChan) return conn diff --git a/connection_test.go b/connection_test.go index e2cca32e08c..7bc5b96d66f 100644 --- a/connection_test.go +++ b/connection_test.go @@ -83,7 +83,7 @@ var _ = Describe("Connection", func() { }) } - expectAppendPacket := func(packer *MockPacker, p shortHeaderPacket, b []byte) *gomock.Call { + expectAppendPacket := func(packer *MockPacker, p shortHeaderPacket, b []byte) *PackerAppendPacketCall { return packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), Version1).DoAndReturn(func(buf *packetBuffer, _ protocol.ByteCount, _ protocol.VersionNumber) (shortHeaderPacket, error) { buf.Data = append(buf.Data, b...) return p, nil @@ -1280,7 +1280,10 @@ var _ = Describe("Connection", func() { 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) }) + packer.EXPECT().PackCoalescedPacket(true, gomock.Any(), conn.version).Do(func(bool, protocol.ByteCount, protocol.VersionNumber) (*coalescedPacket, error) { + close(done) + return nil, nil + }) runConn() conn.scheduleSending() Eventually(done).Should(BeClosed()) @@ -1914,7 +1917,7 @@ var _ = Describe("Connection", func() { ) sent := make(chan struct{}) - mconn.EXPECT().Write([]byte("foobar"), uint16(0), protocol.ECT1).Do(func([]byte, uint16, protocol.ECN) { close(sent) }) + mconn.EXPECT().Write([]byte("foobar"), uint16(0), protocol.ECT1).Do(func([]byte, uint16, protocol.ECN) error { close(sent); return nil }) go func() { defer GinkgoRecover() @@ -2581,7 +2584,10 @@ var _ = Describe("Client Connection", func() { }) conn.unpacker = unpacker done := make(chan struct{}) - packer.EXPECT().PackCoalescedPacket(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(onlyAck bool, maxPacketSize protocol.ByteCount, v protocol.VersionNumber) { close(done) }) + packer.EXPECT().PackCoalescedPacket(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(onlyAck bool, maxPacketSize protocol.ByteCount, v protocol.VersionNumber) (*coalescedPacket, error) { + close(done) + return nil, nil + }) newConnID := protocol.ParseConnectionID([]byte{1, 3, 3, 7, 1, 3, 3, 7}) p := getPacket(&wire.ExtendedHeader{ Header: wire.Header{ @@ -2671,9 +2677,10 @@ var _ = Describe("Client Connection", func() { tracer.EXPECT().ClosedConnection(gomock.Any()) tracer.EXPECT().Close() running := make(chan struct{}) - cryptoSetup.EXPECT().StartHandshake().Do(func() { + cryptoSetup.EXPECT().StartHandshake().Do(func() error { close(running) conn.closeLocal(errors.New("early error")) + return nil }) cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}) cryptoSetup.EXPECT().Close() diff --git a/http3/client_test.go b/http3/client_test.go index 66e290e2fa5..014c29a5b4f 100644 --- a/http3/client_test.go +++ b/http3/client_test.go @@ -213,9 +213,10 @@ var _ = Describe("Client", func() { testDone = make(chan struct{}) settingsFrameWritten = make(chan struct{}) controlStr := mockquic.NewMockStream(mockCtrl) - controlStr.EXPECT().Write(gomock.Any()).Do(func(b []byte) { + controlStr.EXPECT().Write(gomock.Any()).Do(func(b []byte) (int, error) { defer GinkgoRecover() close(settingsFrameWritten) + return len(b), nil }) conn = mockquic.NewMockEarlyConnection(mockCtrl) conn.EXPECT().OpenUniStream().Return(controlStr, nil) @@ -339,9 +340,10 @@ var _ = Describe("Client", func() { testDone = make(chan struct{}) settingsFrameWritten = make(chan struct{}) controlStr := mockquic.NewMockStream(mockCtrl) - controlStr.EXPECT().Write(gomock.Any()).Do(func(b []byte) { + controlStr.EXPECT().Write(gomock.Any()).Do(func(b []byte) (int, error) { defer GinkgoRecover() close(settingsFrameWritten) + return len(b), nil }) conn = mockquic.NewMockEarlyConnection(mockCtrl) conn.EXPECT().OpenUniStream().Return(controlStr, nil) @@ -445,9 +447,10 @@ var _ = Describe("Client", func() { BeforeEach(func() { settingsFrameWritten = make(chan struct{}) controlStr := mockquic.NewMockStream(mockCtrl) - controlStr.EXPECT().Write(gomock.Any()).Do(func(b []byte) { + controlStr.EXPECT().Write(gomock.Any()).Do(func(b []byte) (int, error) { defer GinkgoRecover() close(settingsFrameWritten) + return len(b), nil }) conn = mockquic.NewMockEarlyConnection(mockCtrl) conn.EXPECT().OpenUniStream().Return(controlStr, nil) @@ -514,9 +517,7 @@ var _ = Describe("Client", func() { str := mockquic.NewMockStream(mockCtrl) str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes() done := make(chan struct{}) - str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError)).Do(func(code quic.StreamErrorCode) { - close(done) - }) + str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError)).Do(func(quic.StreamErrorCode) { close(done) }) conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) { return str, nil @@ -544,10 +545,9 @@ var _ = Describe("Client", func() { return nil, errors.New("test done") }) done := make(chan struct{}) - conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { - defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(ErrCodeMissingSettings)) + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeMissingSettings), gomock.Any()).Do(func(quic.ApplicationErrorCode, string) error { close(done) + return nil }) _, err := cl.RoundTripOpt(req, RoundTripOpt{}) Expect(err).To(MatchError("done")) @@ -568,10 +568,9 @@ var _ = Describe("Client", func() { return nil, errors.New("test done") }) done := make(chan struct{}) - conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { - defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(ErrCodeFrameError)) + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameError), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) error { close(done) + return nil }) _, err := cl.RoundTripOpt(req, RoundTripOpt{}) Expect(err).To(MatchError("done")) @@ -590,10 +589,9 @@ var _ = Describe("Client", func() { return nil, errors.New("test done") }) done := make(chan struct{}) - conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { - defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(ErrCodeIDError)) + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeIDError), gomock.Any()).Do(func(quic.ApplicationErrorCode, string) error { close(done) + return nil }) _, err := cl.RoundTripOpt(req, RoundTripOpt{}) Expect(err).To(MatchError("done")) @@ -616,11 +614,9 @@ var _ = Describe("Client", func() { }) conn.EXPECT().ConnectionState().Return(quic.ConnectionState{SupportsDatagrams: false}) done := make(chan struct{}) - conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, reason string) { - defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(ErrCodeSettingsError)) - Expect(reason).To(Equal("missing QUIC Datagram support")) + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeSettingsError), "missing QUIC Datagram support").Do(func(quic.ApplicationErrorCode, string) error { close(done) + return nil }) _, err := cl.RoundTripOpt(req, RoundTripOpt{}) Expect(err).To(MatchError("done")) @@ -669,13 +665,14 @@ var _ = Describe("Client", func() { BeforeEach(func() { settingsFrameWritten = make(chan struct{}) controlStr := mockquic.NewMockStream(mockCtrl) - controlStr.EXPECT().Write(gomock.Any()).Do(func(b []byte) { + controlStr.EXPECT().Write(gomock.Any()).Do(func(b []byte) (int, error) { defer GinkgoRecover() r := bytes.NewReader(b) streamType, err := quicvarint.Read(r) Expect(err).ToNot(HaveOccurred()) Expect(streamType).To(BeEquivalentTo(streamTypeControlStream)) close(settingsFrameWritten) + return len(b), nil }) // SETTINGS frame str = mockquic.NewMockStream(mockCtrl) conn = mockquic.NewMockEarlyConnection(mockCtrl) @@ -777,7 +774,7 @@ var _ = Describe("Client", func() { It("sends a request", func() { done := make(chan struct{}) gomock.InOrder( - str.EXPECT().Close().Do(func() { close(done) }), + str.EXPECT().Close().Do(func() error { close(done); return nil }), str.EXPECT().CancelWrite(gomock.Any()).MaxTimes(1), // when reading the response errors ) // the response body is sent asynchronously, while already reading the response @@ -831,7 +828,7 @@ var _ = Describe("Client", func() { return 0, errors.New("test done") }) closed := make(chan struct{}) - str.EXPECT().Close().Do(func() { close(closed) }) + str.EXPECT().Close().Do(func() error { close(closed); return nil }) _, err := cl.RoundTripOpt(req, RoundTripOpt{}) Expect(err).To(MatchError("test done")) Eventually(closed).Should(BeClosed()) @@ -842,7 +839,7 @@ var _ = Describe("Client", func() { conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), gomock.Any()) closed := make(chan struct{}) r := bytes.NewReader(b) - str.EXPECT().Close().Do(func() { close(closed) }) + str.EXPECT().Close().Do(func() error { close(closed); return nil }) str.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes() _, err := cl.RoundTripOpt(req, RoundTripOpt{}) Expect(err).To(MatchError("expected first frame to be a HEADERS frame")) @@ -860,7 +857,7 @@ var _ = Describe("Client", func() { r := bytes.NewReader(b) str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeMessageError)) closed := make(chan struct{}) - str.EXPECT().Close().Do(func() { close(closed) }) + str.EXPECT().Close().Do(func() error { close(closed); return nil }) str.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes() _, err := cl.RoundTripOpt(req, RoundTripOpt{}) Expect(err).To(HaveOccurred()) @@ -872,7 +869,7 @@ var _ = Describe("Client", func() { r := bytes.NewReader(b) str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeFrameError)) closed := make(chan struct{}) - str.EXPECT().Close().Do(func() { close(closed) }) + str.EXPECT().Close().Do(func() error { close(closed); return nil }) str.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes() _, err := cl.RoundTripOpt(req, RoundTripOpt{}) Expect(err).To(MatchError("HEADERS frame too large: 1338 bytes (max: 1337)")) diff --git a/http3/mock_quic_early_listener_test.go b/http3/mock_quic_early_listener_test.go index c6977bea972..a63086ed924 100644 --- a/http3/mock_quic_early_listener_test.go +++ b/http3/mock_quic_early_listener_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -package http3 -destination mock_quic_early_listener_test.go github.com/quic-go/quic-go/http3 QUICEarlyListener +// mockgen -typed -package http3 -destination mock_quic_early_listener_test.go github.com/quic-go/quic-go/http3 QUICEarlyListener // // Package http3 is a generated GoMock package. package http3 @@ -50,9 +50,33 @@ func (m *MockQUICEarlyListener) Accept(arg0 context.Context) (quic.EarlyConnecti } // Accept indicates an expected call of Accept. -func (mr *MockQUICEarlyListenerMockRecorder) Accept(arg0 any) *gomock.Call { +func (mr *MockQUICEarlyListenerMockRecorder) Accept(arg0 any) *QUICEarlyListenerAcceptCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accept", reflect.TypeOf((*MockQUICEarlyListener)(nil).Accept), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accept", reflect.TypeOf((*MockQUICEarlyListener)(nil).Accept), arg0) + return &QUICEarlyListenerAcceptCall{Call: call} +} + +// QUICEarlyListenerAcceptCall wrap *gomock.Call +type QUICEarlyListenerAcceptCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICEarlyListenerAcceptCall) Return(arg0 quic.EarlyConnection, arg1 error) *QUICEarlyListenerAcceptCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICEarlyListenerAcceptCall) Do(f func(context.Context) (quic.EarlyConnection, error)) *QUICEarlyListenerAcceptCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICEarlyListenerAcceptCall) DoAndReturn(f func(context.Context) (quic.EarlyConnection, error)) *QUICEarlyListenerAcceptCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Addr mocks base method. @@ -64,9 +88,33 @@ func (m *MockQUICEarlyListener) Addr() net.Addr { } // Addr indicates an expected call of Addr. -func (mr *MockQUICEarlyListenerMockRecorder) Addr() *gomock.Call { +func (mr *MockQUICEarlyListenerMockRecorder) Addr() *QUICEarlyListenerAddrCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Addr", reflect.TypeOf((*MockQUICEarlyListener)(nil).Addr)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Addr", reflect.TypeOf((*MockQUICEarlyListener)(nil).Addr)) + return &QUICEarlyListenerAddrCall{Call: call} +} + +// QUICEarlyListenerAddrCall wrap *gomock.Call +type QUICEarlyListenerAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICEarlyListenerAddrCall) Return(arg0 net.Addr) *QUICEarlyListenerAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICEarlyListenerAddrCall) Do(f func() net.Addr) *QUICEarlyListenerAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICEarlyListenerAddrCall) DoAndReturn(f func() net.Addr) *QUICEarlyListenerAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Close mocks base method. @@ -78,7 +126,31 @@ func (m *MockQUICEarlyListener) Close() error { } // Close indicates an expected call of Close. -func (mr *MockQUICEarlyListenerMockRecorder) Close() *gomock.Call { +func (mr *MockQUICEarlyListenerMockRecorder) Close() *QUICEarlyListenerCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockQUICEarlyListener)(nil).Close)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockQUICEarlyListener)(nil).Close)) + return &QUICEarlyListenerCloseCall{Call: call} +} + +// QUICEarlyListenerCloseCall wrap *gomock.Call +type QUICEarlyListenerCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICEarlyListenerCloseCall) Return(arg0 error) *QUICEarlyListenerCloseCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICEarlyListenerCloseCall) Do(f func() error) *QUICEarlyListenerCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICEarlyListenerCloseCall) DoAndReturn(f func() error) *QUICEarlyListenerCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/http3/mock_roundtripcloser_test.go b/http3/mock_roundtripcloser_test.go index 2aa3558d95f..e0e06f99c4a 100644 --- a/http3/mock_roundtripcloser_test.go +++ b/http3/mock_roundtripcloser_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package http3 -destination mock_roundtripcloser_test.go github.com/quic-go/quic-go/http3 RoundTripCloser +// mockgen -typed -build_flags=-tags=gomock -package http3 -destination mock_roundtripcloser_test.go github.com/quic-go/quic-go/http3 RoundTripCloser // // Package http3 is a generated GoMock package. package http3 @@ -47,9 +47,33 @@ func (m *MockRoundTripCloser) Close() error { } // Close indicates an expected call of Close. -func (mr *MockRoundTripCloserMockRecorder) Close() *gomock.Call { +func (mr *MockRoundTripCloserMockRecorder) Close() *RoundTripCloserCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockRoundTripCloser)(nil).Close)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockRoundTripCloser)(nil).Close)) + return &RoundTripCloserCloseCall{Call: call} +} + +// RoundTripCloserCloseCall wrap *gomock.Call +type RoundTripCloserCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RoundTripCloserCloseCall) Return(arg0 error) *RoundTripCloserCloseCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RoundTripCloserCloseCall) Do(f func() error) *RoundTripCloserCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RoundTripCloserCloseCall) DoAndReturn(f func() error) *RoundTripCloserCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // HandshakeComplete mocks base method. @@ -61,9 +85,33 @@ func (m *MockRoundTripCloser) HandshakeComplete() bool { } // HandshakeComplete indicates an expected call of HandshakeComplete. -func (mr *MockRoundTripCloserMockRecorder) HandshakeComplete() *gomock.Call { +func (mr *MockRoundTripCloserMockRecorder) HandshakeComplete() *RoundTripCloserHandshakeCompleteCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandshakeComplete", reflect.TypeOf((*MockRoundTripCloser)(nil).HandshakeComplete)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandshakeComplete", reflect.TypeOf((*MockRoundTripCloser)(nil).HandshakeComplete)) + return &RoundTripCloserHandshakeCompleteCall{Call: call} +} + +// RoundTripCloserHandshakeCompleteCall wrap *gomock.Call +type RoundTripCloserHandshakeCompleteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RoundTripCloserHandshakeCompleteCall) Return(arg0 bool) *RoundTripCloserHandshakeCompleteCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RoundTripCloserHandshakeCompleteCall) Do(f func() bool) *RoundTripCloserHandshakeCompleteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RoundTripCloserHandshakeCompleteCall) DoAndReturn(f func() bool) *RoundTripCloserHandshakeCompleteCall { + c.Call = c.Call.DoAndReturn(f) + return c } // RoundTripOpt mocks base method. @@ -76,7 +124,31 @@ func (m *MockRoundTripCloser) RoundTripOpt(arg0 *http.Request, arg1 RoundTripOpt } // RoundTripOpt indicates an expected call of RoundTripOpt. -func (mr *MockRoundTripCloserMockRecorder) RoundTripOpt(arg0, arg1 any) *gomock.Call { +func (mr *MockRoundTripCloserMockRecorder) RoundTripOpt(arg0, arg1 any) *RoundTripCloserRoundTripOptCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RoundTripOpt", reflect.TypeOf((*MockRoundTripCloser)(nil).RoundTripOpt), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RoundTripOpt", reflect.TypeOf((*MockRoundTripCloser)(nil).RoundTripOpt), arg0, arg1) + return &RoundTripCloserRoundTripOptCall{Call: call} +} + +// RoundTripCloserRoundTripOptCall wrap *gomock.Call +type RoundTripCloserRoundTripOptCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RoundTripCloserRoundTripOptCall) Return(arg0 *http.Response, arg1 error) *RoundTripCloserRoundTripOptCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RoundTripCloserRoundTripOptCall) Do(f func(*http.Request, RoundTripOpt) (*http.Response, error)) *RoundTripCloserRoundTripOptCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RoundTripCloserRoundTripOptCall) DoAndReturn(f func(*http.Request, RoundTripOpt) (*http.Response, error)) *RoundTripCloserRoundTripOptCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/http3/mockgen.go b/http3/mockgen.go index ad0a8a26e85..57af7972cfe 100644 --- a/http3/mockgen.go +++ b/http3/mockgen.go @@ -2,7 +2,7 @@ package http3 -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package http3 -destination mock_roundtripcloser_test.go github.com/quic-go/quic-go/http3 RoundTripCloser" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package http3 -destination mock_roundtripcloser_test.go github.com/quic-go/quic-go/http3 RoundTripCloser" type RoundTripCloser = roundTripCloser -//go:generate sh -c "go run go.uber.org/mock/mockgen -package http3 -destination mock_quic_early_listener_test.go github.com/quic-go/quic-go/http3 QUICEarlyListener" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -package http3 -destination mock_quic_early_listener_test.go github.com/quic-go/quic-go/http3 QUICEarlyListener" diff --git a/http3/server_test.go b/http3/server_test.go index 486d31352d5..28e89ab99aa 100644 --- a/http3/server_test.go +++ b/http3/server_test.go @@ -513,9 +513,7 @@ var _ = Describe("Server", func() { str := mockquic.NewMockStream(mockCtrl) str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes() done := make(chan struct{}) - str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError)).Do(func(code quic.StreamErrorCode) { - close(done) - }) + str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError)).Do(func(quic.StreamErrorCode) { close(done) }) conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) { return str, nil @@ -542,10 +540,9 @@ var _ = Describe("Server", func() { return nil, errors.New("test done") }) done := make(chan struct{}) - conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { - defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(ErrCodeMissingSettings)) + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeMissingSettings), gomock.Any()).Do(func(quic.ApplicationErrorCode, string) error { close(done) + return nil }) s.handleConn(conn) Eventually(done).Should(BeClosed()) @@ -565,10 +562,9 @@ var _ = Describe("Server", func() { return nil, errors.New("test done") }) done := make(chan struct{}) - conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { - defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(ErrCodeFrameError)) + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameError), gomock.Any()).Do(func(quic.ApplicationErrorCode, string) error { close(done) + return nil }) s.handleConn(conn) Eventually(done).Should(BeClosed()) @@ -588,10 +584,9 @@ var _ = Describe("Server", func() { return nil, errors.New("test done") }) done := make(chan struct{}) - conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { - defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(ErrCodeStreamCreationError)) + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeStreamCreationError), gomock.Any()).Do(func(quic.ApplicationErrorCode, string) error { close(done) + return nil }) s.handleConn(conn) Eventually(done).Should(BeClosed()) @@ -613,11 +608,9 @@ var _ = Describe("Server", func() { }) conn.EXPECT().ConnectionState().Return(quic.ConnectionState{SupportsDatagrams: false}) done := make(chan struct{}) - conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, reason string) { - defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(ErrCodeSettingsError)) - Expect(reason).To(Equal("missing QUIC Datagram support")) + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeSettingsError), "missing QUIC Datagram support").Do(func(quic.ApplicationErrorCode, string) error { close(done) + return nil }) s.handleConn(conn) Eventually(done).Should(BeClosed()) @@ -663,7 +656,7 @@ var _ = Describe("Server", func() { str.EXPECT().Context().Return(reqContext) str.EXPECT().Write(gomock.Any()).DoAndReturn(responseBuf.Write).AnyTimes() str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeNoError)) - str.EXPECT().Close().Do(func() { close(done) }) + str.EXPECT().Close().Do(func() error { close(done); return nil }) s.handleConn(conn) Eventually(done).Should(BeClosed()) @@ -738,9 +731,9 @@ var _ = Describe("Server", func() { }).AnyTimes() done := make(chan struct{}) - conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { - Expect(code).To(Equal(quic.ApplicationErrorCode(ErrCodeFrameUnexpected))) + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), gomock.Any()).Do(func(quic.ApplicationErrorCode, string) error { close(done) + return nil }) s.handleConn(conn) Eventually(done).Should(BeClosed()) @@ -1050,7 +1043,7 @@ var _ = Describe("Server", func() { } stopAccept := make(chan struct{}) - ln.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.Connection, error) { + ln.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.EarlyConnection, error) { <-stopAccept return nil, errors.New("closed") }) @@ -1063,7 +1056,7 @@ var _ = Describe("Server", func() { }() Consistently(done).ShouldNot(BeClosed()) - ln.EXPECT().Close().Do(func() { close(stopAccept) }) + ln.EXPECT().Close().Do(func() error { close(stopAccept); return nil }) Expect(s.Close()).To(Succeed()) Eventually(done).Should(BeClosed()) }) @@ -1085,13 +1078,13 @@ var _ = Describe("Server", func() { } stopAccept1 := make(chan struct{}) - ln1.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.Connection, error) { + ln1.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.EarlyConnection, error) { <-stopAccept1 return nil, errors.New("closed") }) ln1.EXPECT().Addr() // generate alt-svc headers stopAccept2 := make(chan struct{}) - ln2.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.Connection, error) { + ln2.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.EarlyConnection, error) { <-stopAccept2 return nil, errors.New("closed") }) @@ -1112,8 +1105,8 @@ var _ = Describe("Server", func() { Consistently(done1).ShouldNot(BeClosed()) Expect(done2).ToNot(BeClosed()) - ln1.EXPECT().Close().Do(func() { close(stopAccept1) }) - ln2.EXPECT().Close().Do(func() { close(stopAccept2) }) + ln1.EXPECT().Close().Do(func() error { close(stopAccept1); return nil }) + ln2.EXPECT().Close().Do(func() error { close(stopAccept2); return nil }) Expect(s.Close()).To(Succeed()) Eventually(done1).Should(BeClosed()) Eventually(done2).Should(BeClosed()) @@ -1138,7 +1131,7 @@ var _ = Describe("Server", func() { s := &Server{} stopAccept := make(chan struct{}) - ln.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.Connection, error) { + ln.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.EarlyConnection, error) { <-stopAccept return nil, errors.New("closed") }) @@ -1152,7 +1145,7 @@ var _ = Describe("Server", func() { Consistently(func() int32 { return atomic.LoadInt32(&called) }).Should(Equal(int32(0))) Consistently(done).ShouldNot(BeClosed()) - ln.EXPECT().Close().Do(func() { close(stopAccept) }) + ln.EXPECT().Close().Do(func() error { close(stopAccept); return nil }) Expect(s.Close()).To(Succeed()) Eventually(done).Should(BeClosed()) }) @@ -1172,13 +1165,13 @@ var _ = Describe("Server", func() { s := &Server{} stopAccept1 := make(chan struct{}) - ln1.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.Connection, error) { + ln1.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.EarlyConnection, error) { <-stopAccept1 return nil, errors.New("closed") }) ln1.EXPECT().Addr() // generate alt-svc headers stopAccept2 := make(chan struct{}) - ln2.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.Connection, error) { + ln2.EXPECT().Accept(gomock.Any()).DoAndReturn(func(context.Context) (quic.EarlyConnection, error) { <-stopAccept2 return nil, errors.New("closed") }) @@ -1200,8 +1193,8 @@ var _ = Describe("Server", func() { Consistently(func() int32 { return atomic.LoadInt32(&called) }).Should(Equal(int32(0))) Consistently(done1).ShouldNot(BeClosed()) Expect(done2).ToNot(BeClosed()) - ln1.EXPECT().Close().Do(func() { close(stopAccept1) }) - ln2.EXPECT().Close().Do(func() { close(stopAccept2) }) + ln1.EXPECT().Close().Do(func() error { close(stopAccept1); return nil }) + ln2.EXPECT().Close().Do(func() error { close(stopAccept2); return nil }) Expect(s.Close()).To(Succeed()) Eventually(done1).Should(BeClosed()) Eventually(done2).Should(BeClosed()) diff --git a/internal/ackhandler/mock_sent_packet_tracker_test.go b/internal/ackhandler/mock_sent_packet_tracker_test.go index aa8c8674526..3e41b255147 100644 --- a/internal/ackhandler/mock_sent_packet_tracker_test.go +++ b/internal/ackhandler/mock_sent_packet_tracker_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package ackhandler -destination mock_sent_packet_tracker_test.go github.com/quic-go/quic-go/internal/ackhandler SentPacketTracker +// mockgen -typed -build_flags=-tags=gomock -package ackhandler -destination mock_sent_packet_tracker_test.go github.com/quic-go/quic-go/internal/ackhandler SentPacketTracker // // Package ackhandler is a generated GoMock package. package ackhandler @@ -47,9 +47,33 @@ func (m *MockSentPacketTracker) GetLowestPacketNotConfirmedAcked() protocol.Pack } // GetLowestPacketNotConfirmedAcked indicates an expected call of GetLowestPacketNotConfirmedAcked. -func (mr *MockSentPacketTrackerMockRecorder) GetLowestPacketNotConfirmedAcked() *gomock.Call { +func (mr *MockSentPacketTrackerMockRecorder) GetLowestPacketNotConfirmedAcked() *SentPacketTrackerGetLowestPacketNotConfirmedAckedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLowestPacketNotConfirmedAcked", reflect.TypeOf((*MockSentPacketTracker)(nil).GetLowestPacketNotConfirmedAcked)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLowestPacketNotConfirmedAcked", reflect.TypeOf((*MockSentPacketTracker)(nil).GetLowestPacketNotConfirmedAcked)) + return &SentPacketTrackerGetLowestPacketNotConfirmedAckedCall{Call: call} +} + +// SentPacketTrackerGetLowestPacketNotConfirmedAckedCall wrap *gomock.Call +type SentPacketTrackerGetLowestPacketNotConfirmedAckedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketTrackerGetLowestPacketNotConfirmedAckedCall) Return(arg0 protocol.PacketNumber) *SentPacketTrackerGetLowestPacketNotConfirmedAckedCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketTrackerGetLowestPacketNotConfirmedAckedCall) Do(f func() protocol.PacketNumber) *SentPacketTrackerGetLowestPacketNotConfirmedAckedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketTrackerGetLowestPacketNotConfirmedAckedCall) DoAndReturn(f func() protocol.PacketNumber) *SentPacketTrackerGetLowestPacketNotConfirmedAckedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReceivedPacket mocks base method. @@ -59,7 +83,31 @@ func (m *MockSentPacketTracker) ReceivedPacket(arg0 protocol.EncryptionLevel) { } // ReceivedPacket indicates an expected call of ReceivedPacket. -func (mr *MockSentPacketTrackerMockRecorder) ReceivedPacket(arg0 any) *gomock.Call { +func (mr *MockSentPacketTrackerMockRecorder) ReceivedPacket(arg0 any) *SentPacketTrackerReceivedPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedPacket", reflect.TypeOf((*MockSentPacketTracker)(nil).ReceivedPacket), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedPacket", reflect.TypeOf((*MockSentPacketTracker)(nil).ReceivedPacket), arg0) + return &SentPacketTrackerReceivedPacketCall{Call: call} +} + +// SentPacketTrackerReceivedPacketCall wrap *gomock.Call +type SentPacketTrackerReceivedPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketTrackerReceivedPacketCall) Return() *SentPacketTrackerReceivedPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketTrackerReceivedPacketCall) Do(f func(protocol.EncryptionLevel)) *SentPacketTrackerReceivedPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketTrackerReceivedPacketCall) DoAndReturn(f func(protocol.EncryptionLevel)) *SentPacketTrackerReceivedPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/ackhandler/mockgen.go b/internal/ackhandler/mockgen.go index dbf6ee2d1e7..0031e6b1c8a 100644 --- a/internal/ackhandler/mockgen.go +++ b/internal/ackhandler/mockgen.go @@ -2,7 +2,7 @@ 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/quic-go/quic-go/internal/ackhandler SentPacketTracker" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package ackhandler -destination mock_sent_packet_tracker_test.go github.com/quic-go/quic-go/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" diff --git a/internal/mocks/ackhandler/received_packet_handler.go b/internal/mocks/ackhandler/received_packet_handler.go index 6455ec1c33b..c94cd889bfc 100644 --- a/internal/mocks/ackhandler/received_packet_handler.go +++ b/internal/mocks/ackhandler/received_packet_handler.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mockackhandler -destination ackhandler/received_packet_handler.go github.com/quic-go/quic-go/internal/ackhandler ReceivedPacketHandler +// mockgen -typed -build_flags=-tags=gomock -package mockackhandler -destination ackhandler/received_packet_handler.go github.com/quic-go/quic-go/internal/ackhandler ReceivedPacketHandler // // Package mockackhandler is a generated GoMock package. package mockackhandler @@ -47,9 +47,33 @@ func (m *MockReceivedPacketHandler) DropPackets(arg0 protocol.EncryptionLevel) { } // DropPackets indicates an expected call of DropPackets. -func (mr *MockReceivedPacketHandlerMockRecorder) DropPackets(arg0 any) *gomock.Call { +func (mr *MockReceivedPacketHandlerMockRecorder) DropPackets(arg0 any) *ReceivedPacketHandlerDropPacketsCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropPackets", reflect.TypeOf((*MockReceivedPacketHandler)(nil).DropPackets), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropPackets", reflect.TypeOf((*MockReceivedPacketHandler)(nil).DropPackets), arg0) + return &ReceivedPacketHandlerDropPacketsCall{Call: call} +} + +// ReceivedPacketHandlerDropPacketsCall wrap *gomock.Call +type ReceivedPacketHandlerDropPacketsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceivedPacketHandlerDropPacketsCall) Return() *ReceivedPacketHandlerDropPacketsCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceivedPacketHandlerDropPacketsCall) Do(f func(protocol.EncryptionLevel)) *ReceivedPacketHandlerDropPacketsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceivedPacketHandlerDropPacketsCall) DoAndReturn(f func(protocol.EncryptionLevel)) *ReceivedPacketHandlerDropPacketsCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetAckFrame mocks base method. @@ -61,9 +85,33 @@ func (m *MockReceivedPacketHandler) GetAckFrame(arg0 protocol.EncryptionLevel, a } // GetAckFrame indicates an expected call of GetAckFrame. -func (mr *MockReceivedPacketHandlerMockRecorder) GetAckFrame(arg0, arg1 any) *gomock.Call { +func (mr *MockReceivedPacketHandlerMockRecorder) GetAckFrame(arg0, arg1 any) *ReceivedPacketHandlerGetAckFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAckFrame", reflect.TypeOf((*MockReceivedPacketHandler)(nil).GetAckFrame), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAckFrame", reflect.TypeOf((*MockReceivedPacketHandler)(nil).GetAckFrame), arg0, arg1) + return &ReceivedPacketHandlerGetAckFrameCall{Call: call} +} + +// ReceivedPacketHandlerGetAckFrameCall wrap *gomock.Call +type ReceivedPacketHandlerGetAckFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceivedPacketHandlerGetAckFrameCall) Return(arg0 *wire.AckFrame) *ReceivedPacketHandlerGetAckFrameCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceivedPacketHandlerGetAckFrameCall) Do(f func(protocol.EncryptionLevel, bool) *wire.AckFrame) *ReceivedPacketHandlerGetAckFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceivedPacketHandlerGetAckFrameCall) DoAndReturn(f func(protocol.EncryptionLevel, bool) *wire.AckFrame) *ReceivedPacketHandlerGetAckFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetAlarmTimeout mocks base method. @@ -75,9 +123,33 @@ func (m *MockReceivedPacketHandler) GetAlarmTimeout() time.Time { } // GetAlarmTimeout indicates an expected call of GetAlarmTimeout. -func (mr *MockReceivedPacketHandlerMockRecorder) GetAlarmTimeout() *gomock.Call { +func (mr *MockReceivedPacketHandlerMockRecorder) GetAlarmTimeout() *ReceivedPacketHandlerGetAlarmTimeoutCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlarmTimeout", reflect.TypeOf((*MockReceivedPacketHandler)(nil).GetAlarmTimeout)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlarmTimeout", reflect.TypeOf((*MockReceivedPacketHandler)(nil).GetAlarmTimeout)) + return &ReceivedPacketHandlerGetAlarmTimeoutCall{Call: call} +} + +// ReceivedPacketHandlerGetAlarmTimeoutCall wrap *gomock.Call +type ReceivedPacketHandlerGetAlarmTimeoutCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceivedPacketHandlerGetAlarmTimeoutCall) Return(arg0 time.Time) *ReceivedPacketHandlerGetAlarmTimeoutCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceivedPacketHandlerGetAlarmTimeoutCall) Do(f func() time.Time) *ReceivedPacketHandlerGetAlarmTimeoutCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceivedPacketHandlerGetAlarmTimeoutCall) DoAndReturn(f func() time.Time) *ReceivedPacketHandlerGetAlarmTimeoutCall { + c.Call = c.Call.DoAndReturn(f) + return c } // IsPotentiallyDuplicate mocks base method. @@ -89,9 +161,33 @@ func (m *MockReceivedPacketHandler) IsPotentiallyDuplicate(arg0 protocol.PacketN } // IsPotentiallyDuplicate indicates an expected call of IsPotentiallyDuplicate. -func (mr *MockReceivedPacketHandlerMockRecorder) IsPotentiallyDuplicate(arg0, arg1 any) *gomock.Call { +func (mr *MockReceivedPacketHandlerMockRecorder) IsPotentiallyDuplicate(arg0, arg1 any) *ReceivedPacketHandlerIsPotentiallyDuplicateCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsPotentiallyDuplicate", reflect.TypeOf((*MockReceivedPacketHandler)(nil).IsPotentiallyDuplicate), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsPotentiallyDuplicate", reflect.TypeOf((*MockReceivedPacketHandler)(nil).IsPotentiallyDuplicate), arg0, arg1) + return &ReceivedPacketHandlerIsPotentiallyDuplicateCall{Call: call} +} + +// ReceivedPacketHandlerIsPotentiallyDuplicateCall wrap *gomock.Call +type ReceivedPacketHandlerIsPotentiallyDuplicateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceivedPacketHandlerIsPotentiallyDuplicateCall) Return(arg0 bool) *ReceivedPacketHandlerIsPotentiallyDuplicateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceivedPacketHandlerIsPotentiallyDuplicateCall) Do(f func(protocol.PacketNumber, protocol.EncryptionLevel) bool) *ReceivedPacketHandlerIsPotentiallyDuplicateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceivedPacketHandlerIsPotentiallyDuplicateCall) DoAndReturn(f func(protocol.PacketNumber, protocol.EncryptionLevel) bool) *ReceivedPacketHandlerIsPotentiallyDuplicateCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReceivedPacket mocks base method. @@ -103,7 +199,31 @@ func (m *MockReceivedPacketHandler) ReceivedPacket(arg0 protocol.PacketNumber, a } // ReceivedPacket indicates an expected call of ReceivedPacket. -func (mr *MockReceivedPacketHandlerMockRecorder) ReceivedPacket(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { +func (mr *MockReceivedPacketHandlerMockRecorder) ReceivedPacket(arg0, arg1, arg2, arg3, arg4 any) *ReceivedPacketHandlerReceivedPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedPacket", reflect.TypeOf((*MockReceivedPacketHandler)(nil).ReceivedPacket), arg0, arg1, arg2, arg3, arg4) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedPacket", reflect.TypeOf((*MockReceivedPacketHandler)(nil).ReceivedPacket), arg0, arg1, arg2, arg3, arg4) + return &ReceivedPacketHandlerReceivedPacketCall{Call: call} +} + +// ReceivedPacketHandlerReceivedPacketCall wrap *gomock.Call +type ReceivedPacketHandlerReceivedPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceivedPacketHandlerReceivedPacketCall) Return(arg0 error) *ReceivedPacketHandlerReceivedPacketCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceivedPacketHandlerReceivedPacketCall) Do(f func(protocol.PacketNumber, protocol.ECN, protocol.EncryptionLevel, time.Time, bool) error) *ReceivedPacketHandlerReceivedPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceivedPacketHandlerReceivedPacketCall) DoAndReturn(f func(protocol.PacketNumber, protocol.ECN, protocol.EncryptionLevel, time.Time, bool) error) *ReceivedPacketHandlerReceivedPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/ackhandler/sent_packet_handler.go b/internal/mocks/ackhandler/sent_packet_handler.go index 6cbde5dceb8..343b4b6eb22 100644 --- a/internal/mocks/ackhandler/sent_packet_handler.go +++ b/internal/mocks/ackhandler/sent_packet_handler.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mockackhandler -destination ackhandler/sent_packet_handler.go github.com/quic-go/quic-go/internal/ackhandler SentPacketHandler +// mockgen -typed -build_flags=-tags=gomock -package mockackhandler -destination ackhandler/sent_packet_handler.go github.com/quic-go/quic-go/internal/ackhandler SentPacketHandler // // Package mockackhandler is a generated GoMock package. package mockackhandler @@ -48,9 +48,33 @@ func (m *MockSentPacketHandler) DropPackets(arg0 protocol.EncryptionLevel) { } // DropPackets indicates an expected call of DropPackets. -func (mr *MockSentPacketHandlerMockRecorder) DropPackets(arg0 any) *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) DropPackets(arg0 any) *SentPacketHandlerDropPacketsCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropPackets", reflect.TypeOf((*MockSentPacketHandler)(nil).DropPackets), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropPackets", reflect.TypeOf((*MockSentPacketHandler)(nil).DropPackets), arg0) + return &SentPacketHandlerDropPacketsCall{Call: call} +} + +// SentPacketHandlerDropPacketsCall wrap *gomock.Call +type SentPacketHandlerDropPacketsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerDropPacketsCall) Return() *SentPacketHandlerDropPacketsCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerDropPacketsCall) Do(f func(protocol.EncryptionLevel)) *SentPacketHandlerDropPacketsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerDropPacketsCall) DoAndReturn(f func(protocol.EncryptionLevel)) *SentPacketHandlerDropPacketsCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ECNMode mocks base method. @@ -62,9 +86,33 @@ func (m *MockSentPacketHandler) ECNMode(arg0 bool) protocol.ECN { } // ECNMode indicates an expected call of ECNMode. -func (mr *MockSentPacketHandlerMockRecorder) ECNMode(arg0 any) *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) ECNMode(arg0 any) *SentPacketHandlerECNModeCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNMode", reflect.TypeOf((*MockSentPacketHandler)(nil).ECNMode), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNMode", reflect.TypeOf((*MockSentPacketHandler)(nil).ECNMode), arg0) + return &SentPacketHandlerECNModeCall{Call: call} +} + +// SentPacketHandlerECNModeCall wrap *gomock.Call +type SentPacketHandlerECNModeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerECNModeCall) Return(arg0 protocol.ECN) *SentPacketHandlerECNModeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerECNModeCall) Do(f func(bool) protocol.ECN) *SentPacketHandlerECNModeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerECNModeCall) DoAndReturn(f func(bool) protocol.ECN) *SentPacketHandlerECNModeCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetLossDetectionTimeout mocks base method. @@ -76,9 +124,33 @@ func (m *MockSentPacketHandler) GetLossDetectionTimeout() time.Time { } // GetLossDetectionTimeout indicates an expected call of GetLossDetectionTimeout. -func (mr *MockSentPacketHandlerMockRecorder) GetLossDetectionTimeout() *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) GetLossDetectionTimeout() *SentPacketHandlerGetLossDetectionTimeoutCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLossDetectionTimeout", reflect.TypeOf((*MockSentPacketHandler)(nil).GetLossDetectionTimeout)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLossDetectionTimeout", reflect.TypeOf((*MockSentPacketHandler)(nil).GetLossDetectionTimeout)) + return &SentPacketHandlerGetLossDetectionTimeoutCall{Call: call} +} + +// SentPacketHandlerGetLossDetectionTimeoutCall wrap *gomock.Call +type SentPacketHandlerGetLossDetectionTimeoutCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerGetLossDetectionTimeoutCall) Return(arg0 time.Time) *SentPacketHandlerGetLossDetectionTimeoutCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerGetLossDetectionTimeoutCall) Do(f func() time.Time) *SentPacketHandlerGetLossDetectionTimeoutCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerGetLossDetectionTimeoutCall) DoAndReturn(f func() time.Time) *SentPacketHandlerGetLossDetectionTimeoutCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OnLossDetectionTimeout mocks base method. @@ -90,9 +162,33 @@ func (m *MockSentPacketHandler) OnLossDetectionTimeout() error { } // OnLossDetectionTimeout indicates an expected call of OnLossDetectionTimeout. -func (mr *MockSentPacketHandlerMockRecorder) OnLossDetectionTimeout() *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) OnLossDetectionTimeout() *SentPacketHandlerOnLossDetectionTimeoutCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnLossDetectionTimeout", reflect.TypeOf((*MockSentPacketHandler)(nil).OnLossDetectionTimeout)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnLossDetectionTimeout", reflect.TypeOf((*MockSentPacketHandler)(nil).OnLossDetectionTimeout)) + return &SentPacketHandlerOnLossDetectionTimeoutCall{Call: call} +} + +// SentPacketHandlerOnLossDetectionTimeoutCall wrap *gomock.Call +type SentPacketHandlerOnLossDetectionTimeoutCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerOnLossDetectionTimeoutCall) Return(arg0 error) *SentPacketHandlerOnLossDetectionTimeoutCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerOnLossDetectionTimeoutCall) Do(f func() error) *SentPacketHandlerOnLossDetectionTimeoutCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerOnLossDetectionTimeoutCall) DoAndReturn(f func() error) *SentPacketHandlerOnLossDetectionTimeoutCall { + c.Call = c.Call.DoAndReturn(f) + return c } // PeekPacketNumber mocks base method. @@ -105,9 +201,33 @@ func (m *MockSentPacketHandler) PeekPacketNumber(arg0 protocol.EncryptionLevel) } // PeekPacketNumber indicates an expected call of PeekPacketNumber. -func (mr *MockSentPacketHandlerMockRecorder) PeekPacketNumber(arg0 any) *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) PeekPacketNumber(arg0 any) *SentPacketHandlerPeekPacketNumberCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeekPacketNumber", reflect.TypeOf((*MockSentPacketHandler)(nil).PeekPacketNumber), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeekPacketNumber", reflect.TypeOf((*MockSentPacketHandler)(nil).PeekPacketNumber), arg0) + return &SentPacketHandlerPeekPacketNumberCall{Call: call} +} + +// SentPacketHandlerPeekPacketNumberCall wrap *gomock.Call +type SentPacketHandlerPeekPacketNumberCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerPeekPacketNumberCall) Return(arg0 protocol.PacketNumber, arg1 protocol.PacketNumberLen) *SentPacketHandlerPeekPacketNumberCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerPeekPacketNumberCall) Do(f func(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen)) *SentPacketHandlerPeekPacketNumberCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerPeekPacketNumberCall) DoAndReturn(f func(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen)) *SentPacketHandlerPeekPacketNumberCall { + c.Call = c.Call.DoAndReturn(f) + return c } // PopPacketNumber mocks base method. @@ -119,9 +239,33 @@ func (m *MockSentPacketHandler) PopPacketNumber(arg0 protocol.EncryptionLevel) p } // PopPacketNumber indicates an expected call of PopPacketNumber. -func (mr *MockSentPacketHandlerMockRecorder) PopPacketNumber(arg0 any) *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) PopPacketNumber(arg0 any) *SentPacketHandlerPopPacketNumberCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PopPacketNumber", reflect.TypeOf((*MockSentPacketHandler)(nil).PopPacketNumber), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PopPacketNumber", reflect.TypeOf((*MockSentPacketHandler)(nil).PopPacketNumber), arg0) + return &SentPacketHandlerPopPacketNumberCall{Call: call} +} + +// SentPacketHandlerPopPacketNumberCall wrap *gomock.Call +type SentPacketHandlerPopPacketNumberCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerPopPacketNumberCall) Return(arg0 protocol.PacketNumber) *SentPacketHandlerPopPacketNumberCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerPopPacketNumberCall) Do(f func(protocol.EncryptionLevel) protocol.PacketNumber) *SentPacketHandlerPopPacketNumberCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerPopPacketNumberCall) DoAndReturn(f func(protocol.EncryptionLevel) protocol.PacketNumber) *SentPacketHandlerPopPacketNumberCall { + c.Call = c.Call.DoAndReturn(f) + return c } // QueueProbePacket mocks base method. @@ -133,9 +277,33 @@ func (m *MockSentPacketHandler) QueueProbePacket(arg0 protocol.EncryptionLevel) } // QueueProbePacket indicates an expected call of QueueProbePacket. -func (mr *MockSentPacketHandlerMockRecorder) QueueProbePacket(arg0 any) *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) QueueProbePacket(arg0 any) *SentPacketHandlerQueueProbePacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueueProbePacket", reflect.TypeOf((*MockSentPacketHandler)(nil).QueueProbePacket), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueueProbePacket", reflect.TypeOf((*MockSentPacketHandler)(nil).QueueProbePacket), arg0) + return &SentPacketHandlerQueueProbePacketCall{Call: call} +} + +// SentPacketHandlerQueueProbePacketCall wrap *gomock.Call +type SentPacketHandlerQueueProbePacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerQueueProbePacketCall) Return(arg0 bool) *SentPacketHandlerQueueProbePacketCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerQueueProbePacketCall) Do(f func(protocol.EncryptionLevel) bool) *SentPacketHandlerQueueProbePacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerQueueProbePacketCall) DoAndReturn(f func(protocol.EncryptionLevel) bool) *SentPacketHandlerQueueProbePacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReceivedAck mocks base method. @@ -148,9 +316,33 @@ func (m *MockSentPacketHandler) ReceivedAck(arg0 *wire.AckFrame, arg1 protocol.E } // ReceivedAck indicates an expected call of ReceivedAck. -func (mr *MockSentPacketHandlerMockRecorder) ReceivedAck(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) ReceivedAck(arg0, arg1, arg2 any) *SentPacketHandlerReceivedAckCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedAck", reflect.TypeOf((*MockSentPacketHandler)(nil).ReceivedAck), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedAck", reflect.TypeOf((*MockSentPacketHandler)(nil).ReceivedAck), arg0, arg1, arg2) + return &SentPacketHandlerReceivedAckCall{Call: call} +} + +// SentPacketHandlerReceivedAckCall wrap *gomock.Call +type SentPacketHandlerReceivedAckCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerReceivedAckCall) Return(arg0 bool, arg1 error) *SentPacketHandlerReceivedAckCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerReceivedAckCall) Do(f func(*wire.AckFrame, protocol.EncryptionLevel, time.Time) (bool, error)) *SentPacketHandlerReceivedAckCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerReceivedAckCall) DoAndReturn(f func(*wire.AckFrame, protocol.EncryptionLevel, time.Time) (bool, error)) *SentPacketHandlerReceivedAckCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReceivedBytes mocks base method. @@ -160,9 +352,33 @@ func (m *MockSentPacketHandler) ReceivedBytes(arg0 protocol.ByteCount) { } // ReceivedBytes indicates an expected call of ReceivedBytes. -func (mr *MockSentPacketHandlerMockRecorder) ReceivedBytes(arg0 any) *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) ReceivedBytes(arg0 any) *SentPacketHandlerReceivedBytesCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedBytes", reflect.TypeOf((*MockSentPacketHandler)(nil).ReceivedBytes), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedBytes", reflect.TypeOf((*MockSentPacketHandler)(nil).ReceivedBytes), arg0) + return &SentPacketHandlerReceivedBytesCall{Call: call} +} + +// SentPacketHandlerReceivedBytesCall wrap *gomock.Call +type SentPacketHandlerReceivedBytesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerReceivedBytesCall) Return() *SentPacketHandlerReceivedBytesCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerReceivedBytesCall) Do(f func(protocol.ByteCount)) *SentPacketHandlerReceivedBytesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerReceivedBytesCall) DoAndReturn(f func(protocol.ByteCount)) *SentPacketHandlerReceivedBytesCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ResetForRetry mocks base method. @@ -174,9 +390,33 @@ func (m *MockSentPacketHandler) ResetForRetry(arg0 time.Time) error { } // ResetForRetry indicates an expected call of ResetForRetry. -func (mr *MockSentPacketHandlerMockRecorder) ResetForRetry(arg0 any) *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) ResetForRetry(arg0 any) *SentPacketHandlerResetForRetryCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetForRetry", reflect.TypeOf((*MockSentPacketHandler)(nil).ResetForRetry), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetForRetry", reflect.TypeOf((*MockSentPacketHandler)(nil).ResetForRetry), arg0) + return &SentPacketHandlerResetForRetryCall{Call: call} +} + +// SentPacketHandlerResetForRetryCall wrap *gomock.Call +type SentPacketHandlerResetForRetryCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerResetForRetryCall) Return(arg0 error) *SentPacketHandlerResetForRetryCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerResetForRetryCall) Do(f func(time.Time) error) *SentPacketHandlerResetForRetryCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerResetForRetryCall) DoAndReturn(f func(time.Time) error) *SentPacketHandlerResetForRetryCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SendMode mocks base method. @@ -188,9 +428,33 @@ func (m *MockSentPacketHandler) SendMode(arg0 time.Time) ackhandler.SendMode { } // SendMode indicates an expected call of SendMode. -func (mr *MockSentPacketHandlerMockRecorder) SendMode(arg0 any) *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) SendMode(arg0 any) *SentPacketHandlerSendModeCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMode", reflect.TypeOf((*MockSentPacketHandler)(nil).SendMode), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMode", reflect.TypeOf((*MockSentPacketHandler)(nil).SendMode), arg0) + return &SentPacketHandlerSendModeCall{Call: call} +} + +// SentPacketHandlerSendModeCall wrap *gomock.Call +type SentPacketHandlerSendModeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerSendModeCall) Return(arg0 ackhandler.SendMode) *SentPacketHandlerSendModeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerSendModeCall) Do(f func(time.Time) ackhandler.SendMode) *SentPacketHandlerSendModeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerSendModeCall) DoAndReturn(f func(time.Time) ackhandler.SendMode) *SentPacketHandlerSendModeCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SentPacket mocks base method. @@ -200,9 +464,33 @@ func (m *MockSentPacketHandler) SentPacket(arg0 time.Time, arg1, arg2 protocol.P } // SentPacket indicates an expected call of SentPacket. -func (mr *MockSentPacketHandlerMockRecorder) SentPacket(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 any) *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) SentPacket(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 any) *SentPacketHandlerSentPacketCall { 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, arg8) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockSentPacketHandler)(nil).SentPacket), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + return &SentPacketHandlerSentPacketCall{Call: call} +} + +// SentPacketHandlerSentPacketCall wrap *gomock.Call +type SentPacketHandlerSentPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerSentPacketCall) Return() *SentPacketHandlerSentPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerSentPacketCall) Do(f func(time.Time, protocol.PacketNumber, protocol.PacketNumber, []ackhandler.StreamFrame, []ackhandler.Frame, protocol.EncryptionLevel, protocol.ECN, protocol.ByteCount, bool)) *SentPacketHandlerSentPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerSentPacketCall) DoAndReturn(f func(time.Time, protocol.PacketNumber, protocol.PacketNumber, []ackhandler.StreamFrame, []ackhandler.Frame, protocol.EncryptionLevel, protocol.ECN, protocol.ByteCount, bool)) *SentPacketHandlerSentPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetHandshakeConfirmed mocks base method. @@ -212,9 +500,33 @@ func (m *MockSentPacketHandler) SetHandshakeConfirmed() { } // SetHandshakeConfirmed indicates an expected call of SetHandshakeConfirmed. -func (mr *MockSentPacketHandlerMockRecorder) SetHandshakeConfirmed() *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) SetHandshakeConfirmed() *SentPacketHandlerSetHandshakeConfirmedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHandshakeConfirmed", reflect.TypeOf((*MockSentPacketHandler)(nil).SetHandshakeConfirmed)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHandshakeConfirmed", reflect.TypeOf((*MockSentPacketHandler)(nil).SetHandshakeConfirmed)) + return &SentPacketHandlerSetHandshakeConfirmedCall{Call: call} +} + +// SentPacketHandlerSetHandshakeConfirmedCall wrap *gomock.Call +type SentPacketHandlerSetHandshakeConfirmedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerSetHandshakeConfirmedCall) Return() *SentPacketHandlerSetHandshakeConfirmedCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerSetHandshakeConfirmedCall) Do(f func()) *SentPacketHandlerSetHandshakeConfirmedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerSetHandshakeConfirmedCall) DoAndReturn(f func()) *SentPacketHandlerSetHandshakeConfirmedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetMaxDatagramSize mocks base method. @@ -224,9 +536,33 @@ func (m *MockSentPacketHandler) SetMaxDatagramSize(arg0 protocol.ByteCount) { } // SetMaxDatagramSize indicates an expected call of SetMaxDatagramSize. -func (mr *MockSentPacketHandlerMockRecorder) SetMaxDatagramSize(arg0 any) *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) SetMaxDatagramSize(arg0 any) *SentPacketHandlerSetMaxDatagramSizeCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxDatagramSize", reflect.TypeOf((*MockSentPacketHandler)(nil).SetMaxDatagramSize), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxDatagramSize", reflect.TypeOf((*MockSentPacketHandler)(nil).SetMaxDatagramSize), arg0) + return &SentPacketHandlerSetMaxDatagramSizeCall{Call: call} +} + +// SentPacketHandlerSetMaxDatagramSizeCall wrap *gomock.Call +type SentPacketHandlerSetMaxDatagramSizeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerSetMaxDatagramSizeCall) Return() *SentPacketHandlerSetMaxDatagramSizeCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerSetMaxDatagramSizeCall) Do(f func(protocol.ByteCount)) *SentPacketHandlerSetMaxDatagramSizeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerSetMaxDatagramSizeCall) DoAndReturn(f func(protocol.ByteCount)) *SentPacketHandlerSetMaxDatagramSizeCall { + c.Call = c.Call.DoAndReturn(f) + return c } // TimeUntilSend mocks base method. @@ -238,7 +574,31 @@ func (m *MockSentPacketHandler) TimeUntilSend() time.Time { } // TimeUntilSend indicates an expected call of TimeUntilSend. -func (mr *MockSentPacketHandlerMockRecorder) TimeUntilSend() *gomock.Call { +func (mr *MockSentPacketHandlerMockRecorder) TimeUntilSend() *SentPacketHandlerTimeUntilSendCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TimeUntilSend", reflect.TypeOf((*MockSentPacketHandler)(nil).TimeUntilSend)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TimeUntilSend", reflect.TypeOf((*MockSentPacketHandler)(nil).TimeUntilSend)) + return &SentPacketHandlerTimeUntilSendCall{Call: call} +} + +// SentPacketHandlerTimeUntilSendCall wrap *gomock.Call +type SentPacketHandlerTimeUntilSendCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SentPacketHandlerTimeUntilSendCall) Return(arg0 time.Time) *SentPacketHandlerTimeUntilSendCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SentPacketHandlerTimeUntilSendCall) Do(f func() time.Time) *SentPacketHandlerTimeUntilSendCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SentPacketHandlerTimeUntilSendCall) DoAndReturn(f func() time.Time) *SentPacketHandlerTimeUntilSendCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/congestion.go b/internal/mocks/congestion.go index 9a96239c0eb..14638b75b46 100644 --- a/internal/mocks/congestion.go +++ b/internal/mocks/congestion.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mocks -destination congestion.go github.com/quic-go/quic-go/internal/congestion SendAlgorithmWithDebugInfos +// mockgen -typed -build_flags=-tags=gomock -package mocks -destination congestion.go github.com/quic-go/quic-go/internal/congestion SendAlgorithmWithDebugInfos // // Package mocks is a generated GoMock package. package mocks @@ -48,9 +48,33 @@ func (m *MockSendAlgorithmWithDebugInfos) CanSend(arg0 protocol.ByteCount) bool } // CanSend indicates an expected call of CanSend. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) CanSend(arg0 any) *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) CanSend(arg0 any) *SendAlgorithmWithDebugInfosCanSendCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CanSend", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).CanSend), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CanSend", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).CanSend), arg0) + return &SendAlgorithmWithDebugInfosCanSendCall{Call: call} +} + +// SendAlgorithmWithDebugInfosCanSendCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosCanSendCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosCanSendCall) Return(arg0 bool) *SendAlgorithmWithDebugInfosCanSendCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosCanSendCall) Do(f func(protocol.ByteCount) bool) *SendAlgorithmWithDebugInfosCanSendCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosCanSendCall) DoAndReturn(f func(protocol.ByteCount) bool) *SendAlgorithmWithDebugInfosCanSendCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetCongestionWindow mocks base method. @@ -62,9 +86,33 @@ func (m *MockSendAlgorithmWithDebugInfos) GetCongestionWindow() protocol.ByteCou } // GetCongestionWindow indicates an expected call of GetCongestionWindow. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) GetCongestionWindow() *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) GetCongestionWindow() *SendAlgorithmWithDebugInfosGetCongestionWindowCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCongestionWindow", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).GetCongestionWindow)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCongestionWindow", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).GetCongestionWindow)) + return &SendAlgorithmWithDebugInfosGetCongestionWindowCall{Call: call} +} + +// SendAlgorithmWithDebugInfosGetCongestionWindowCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosGetCongestionWindowCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosGetCongestionWindowCall) Return(arg0 protocol.ByteCount) *SendAlgorithmWithDebugInfosGetCongestionWindowCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosGetCongestionWindowCall) Do(f func() protocol.ByteCount) *SendAlgorithmWithDebugInfosGetCongestionWindowCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosGetCongestionWindowCall) DoAndReturn(f func() protocol.ByteCount) *SendAlgorithmWithDebugInfosGetCongestionWindowCall { + c.Call = c.Call.DoAndReturn(f) + return c } // HasPacingBudget mocks base method. @@ -76,9 +124,33 @@ func (m *MockSendAlgorithmWithDebugInfos) HasPacingBudget(arg0 time.Time) bool { } // HasPacingBudget indicates an expected call of HasPacingBudget. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) HasPacingBudget(arg0 any) *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) HasPacingBudget(arg0 any) *SendAlgorithmWithDebugInfosHasPacingBudgetCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasPacingBudget", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).HasPacingBudget), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasPacingBudget", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).HasPacingBudget), arg0) + return &SendAlgorithmWithDebugInfosHasPacingBudgetCall{Call: call} +} + +// SendAlgorithmWithDebugInfosHasPacingBudgetCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosHasPacingBudgetCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosHasPacingBudgetCall) Return(arg0 bool) *SendAlgorithmWithDebugInfosHasPacingBudgetCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosHasPacingBudgetCall) Do(f func(time.Time) bool) *SendAlgorithmWithDebugInfosHasPacingBudgetCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosHasPacingBudgetCall) DoAndReturn(f func(time.Time) bool) *SendAlgorithmWithDebugInfosHasPacingBudgetCall { + c.Call = c.Call.DoAndReturn(f) + return c } // InRecovery mocks base method. @@ -90,9 +162,33 @@ func (m *MockSendAlgorithmWithDebugInfos) InRecovery() bool { } // InRecovery indicates an expected call of InRecovery. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) InRecovery() *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) InRecovery() *SendAlgorithmWithDebugInfosInRecoveryCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InRecovery", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).InRecovery)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InRecovery", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).InRecovery)) + return &SendAlgorithmWithDebugInfosInRecoveryCall{Call: call} +} + +// SendAlgorithmWithDebugInfosInRecoveryCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosInRecoveryCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosInRecoveryCall) Return(arg0 bool) *SendAlgorithmWithDebugInfosInRecoveryCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosInRecoveryCall) Do(f func() bool) *SendAlgorithmWithDebugInfosInRecoveryCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosInRecoveryCall) DoAndReturn(f func() bool) *SendAlgorithmWithDebugInfosInRecoveryCall { + c.Call = c.Call.DoAndReturn(f) + return c } // InSlowStart mocks base method. @@ -104,9 +200,33 @@ func (m *MockSendAlgorithmWithDebugInfos) InSlowStart() bool { } // InSlowStart indicates an expected call of InSlowStart. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) InSlowStart() *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) InSlowStart() *SendAlgorithmWithDebugInfosInSlowStartCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InSlowStart", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).InSlowStart)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InSlowStart", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).InSlowStart)) + return &SendAlgorithmWithDebugInfosInSlowStartCall{Call: call} +} + +// SendAlgorithmWithDebugInfosInSlowStartCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosInSlowStartCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosInSlowStartCall) Return(arg0 bool) *SendAlgorithmWithDebugInfosInSlowStartCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosInSlowStartCall) Do(f func() bool) *SendAlgorithmWithDebugInfosInSlowStartCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosInSlowStartCall) DoAndReturn(f func() bool) *SendAlgorithmWithDebugInfosInSlowStartCall { + c.Call = c.Call.DoAndReturn(f) + return c } // MaybeExitSlowStart mocks base method. @@ -116,9 +236,33 @@ func (m *MockSendAlgorithmWithDebugInfos) MaybeExitSlowStart() { } // MaybeExitSlowStart indicates an expected call of MaybeExitSlowStart. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) MaybeExitSlowStart() *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) MaybeExitSlowStart() *SendAlgorithmWithDebugInfosMaybeExitSlowStartCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaybeExitSlowStart", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).MaybeExitSlowStart)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaybeExitSlowStart", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).MaybeExitSlowStart)) + return &SendAlgorithmWithDebugInfosMaybeExitSlowStartCall{Call: call} +} + +// SendAlgorithmWithDebugInfosMaybeExitSlowStartCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosMaybeExitSlowStartCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosMaybeExitSlowStartCall) Return() *SendAlgorithmWithDebugInfosMaybeExitSlowStartCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosMaybeExitSlowStartCall) Do(f func()) *SendAlgorithmWithDebugInfosMaybeExitSlowStartCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosMaybeExitSlowStartCall) DoAndReturn(f func()) *SendAlgorithmWithDebugInfosMaybeExitSlowStartCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OnCongestionEvent mocks base method. @@ -128,9 +272,33 @@ func (m *MockSendAlgorithmWithDebugInfos) OnCongestionEvent(arg0 protocol.Packet } // OnCongestionEvent indicates an expected call of OnCongestionEvent. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnCongestionEvent(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnCongestionEvent(arg0, arg1, arg2 any) *SendAlgorithmWithDebugInfosOnCongestionEventCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnCongestionEvent", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnCongestionEvent), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnCongestionEvent", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnCongestionEvent), arg0, arg1, arg2) + return &SendAlgorithmWithDebugInfosOnCongestionEventCall{Call: call} +} + +// SendAlgorithmWithDebugInfosOnCongestionEventCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosOnCongestionEventCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosOnCongestionEventCall) Return() *SendAlgorithmWithDebugInfosOnCongestionEventCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosOnCongestionEventCall) Do(f func(protocol.PacketNumber, protocol.ByteCount, protocol.ByteCount)) *SendAlgorithmWithDebugInfosOnCongestionEventCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosOnCongestionEventCall) DoAndReturn(f func(protocol.PacketNumber, protocol.ByteCount, protocol.ByteCount)) *SendAlgorithmWithDebugInfosOnCongestionEventCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OnPacketAcked mocks base method. @@ -140,9 +308,33 @@ func (m *MockSendAlgorithmWithDebugInfos) OnPacketAcked(arg0 protocol.PacketNumb } // OnPacketAcked indicates an expected call of OnPacketAcked. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketAcked(arg0, arg1, arg2, arg3 any) *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketAcked(arg0, arg1, arg2, arg3 any) *SendAlgorithmWithDebugInfosOnPacketAckedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketAcked", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketAcked), arg0, arg1, arg2, arg3) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketAcked", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketAcked), arg0, arg1, arg2, arg3) + return &SendAlgorithmWithDebugInfosOnPacketAckedCall{Call: call} +} + +// SendAlgorithmWithDebugInfosOnPacketAckedCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosOnPacketAckedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosOnPacketAckedCall) Return() *SendAlgorithmWithDebugInfosOnPacketAckedCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosOnPacketAckedCall) Do(f func(protocol.PacketNumber, protocol.ByteCount, protocol.ByteCount, time.Time)) *SendAlgorithmWithDebugInfosOnPacketAckedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosOnPacketAckedCall) DoAndReturn(f func(protocol.PacketNumber, protocol.ByteCount, protocol.ByteCount, time.Time)) *SendAlgorithmWithDebugInfosOnPacketAckedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OnPacketSent mocks base method. @@ -152,9 +344,33 @@ 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 any) *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketSent(arg0, arg1, arg2, arg3, arg4 any) *SendAlgorithmWithDebugInfosOnPacketSentCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketSent", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketSent), arg0, arg1, arg2, arg3, arg4) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketSent", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketSent), arg0, arg1, arg2, arg3, arg4) + return &SendAlgorithmWithDebugInfosOnPacketSentCall{Call: call} +} + +// SendAlgorithmWithDebugInfosOnPacketSentCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosOnPacketSentCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosOnPacketSentCall) Return() *SendAlgorithmWithDebugInfosOnPacketSentCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosOnPacketSentCall) Do(f func(time.Time, protocol.ByteCount, protocol.PacketNumber, protocol.ByteCount, bool)) *SendAlgorithmWithDebugInfosOnPacketSentCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosOnPacketSentCall) DoAndReturn(f func(time.Time, protocol.ByteCount, protocol.PacketNumber, protocol.ByteCount, bool)) *SendAlgorithmWithDebugInfosOnPacketSentCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OnRetransmissionTimeout mocks base method. @@ -164,9 +380,33 @@ func (m *MockSendAlgorithmWithDebugInfos) OnRetransmissionTimeout(arg0 bool) { } // OnRetransmissionTimeout indicates an expected call of OnRetransmissionTimeout. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnRetransmissionTimeout(arg0 any) *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnRetransmissionTimeout(arg0 any) *SendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnRetransmissionTimeout", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnRetransmissionTimeout), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnRetransmissionTimeout", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnRetransmissionTimeout), arg0) + return &SendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall{Call: call} +} + +// SendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall) Return() *SendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall) Do(f func(bool)) *SendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall) DoAndReturn(f func(bool)) *SendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetMaxDatagramSize mocks base method. @@ -176,9 +416,33 @@ func (m *MockSendAlgorithmWithDebugInfos) SetMaxDatagramSize(arg0 protocol.ByteC } // SetMaxDatagramSize indicates an expected call of SetMaxDatagramSize. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) SetMaxDatagramSize(arg0 any) *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) SetMaxDatagramSize(arg0 any) *SendAlgorithmWithDebugInfosSetMaxDatagramSizeCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxDatagramSize", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).SetMaxDatagramSize), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxDatagramSize", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).SetMaxDatagramSize), arg0) + return &SendAlgorithmWithDebugInfosSetMaxDatagramSizeCall{Call: call} +} + +// SendAlgorithmWithDebugInfosSetMaxDatagramSizeCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosSetMaxDatagramSizeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosSetMaxDatagramSizeCall) Return() *SendAlgorithmWithDebugInfosSetMaxDatagramSizeCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosSetMaxDatagramSizeCall) Do(f func(protocol.ByteCount)) *SendAlgorithmWithDebugInfosSetMaxDatagramSizeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosSetMaxDatagramSizeCall) DoAndReturn(f func(protocol.ByteCount)) *SendAlgorithmWithDebugInfosSetMaxDatagramSizeCall { + c.Call = c.Call.DoAndReturn(f) + return c } // TimeUntilSend mocks base method. @@ -190,7 +454,31 @@ func (m *MockSendAlgorithmWithDebugInfos) TimeUntilSend(arg0 protocol.ByteCount) } // TimeUntilSend indicates an expected call of TimeUntilSend. -func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) TimeUntilSend(arg0 any) *gomock.Call { +func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) TimeUntilSend(arg0 any) *SendAlgorithmWithDebugInfosTimeUntilSendCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TimeUntilSend", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).TimeUntilSend), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TimeUntilSend", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).TimeUntilSend), arg0) + return &SendAlgorithmWithDebugInfosTimeUntilSendCall{Call: call} +} + +// SendAlgorithmWithDebugInfosTimeUntilSendCall wrap *gomock.Call +type SendAlgorithmWithDebugInfosTimeUntilSendCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendAlgorithmWithDebugInfosTimeUntilSendCall) Return(arg0 time.Time) *SendAlgorithmWithDebugInfosTimeUntilSendCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendAlgorithmWithDebugInfosTimeUntilSendCall) Do(f func(protocol.ByteCount) time.Time) *SendAlgorithmWithDebugInfosTimeUntilSendCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendAlgorithmWithDebugInfosTimeUntilSendCall) DoAndReturn(f func(protocol.ByteCount) time.Time) *SendAlgorithmWithDebugInfosTimeUntilSendCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/connection_flow_controller.go b/internal/mocks/connection_flow_controller.go index 7407054ce86..ac328602279 100644 --- a/internal/mocks/connection_flow_controller.go +++ b/internal/mocks/connection_flow_controller.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mocks -destination connection_flow_controller.go github.com/quic-go/quic-go/internal/flowcontrol ConnectionFlowController +// mockgen -typed -build_flags=-tags=gomock -package mocks -destination connection_flow_controller.go github.com/quic-go/quic-go/internal/flowcontrol ConnectionFlowController // // Package mocks is a generated GoMock package. package mocks @@ -45,9 +45,33 @@ func (m *MockConnectionFlowController) AddBytesRead(arg0 protocol.ByteCount) { } // AddBytesRead indicates an expected call of AddBytesRead. -func (mr *MockConnectionFlowControllerMockRecorder) AddBytesRead(arg0 any) *gomock.Call { +func (mr *MockConnectionFlowControllerMockRecorder) AddBytesRead(arg0 any) *ConnectionFlowControllerAddBytesReadCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesRead", reflect.TypeOf((*MockConnectionFlowController)(nil).AddBytesRead), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesRead", reflect.TypeOf((*MockConnectionFlowController)(nil).AddBytesRead), arg0) + return &ConnectionFlowControllerAddBytesReadCall{Call: call} +} + +// ConnectionFlowControllerAddBytesReadCall wrap *gomock.Call +type ConnectionFlowControllerAddBytesReadCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionFlowControllerAddBytesReadCall) Return() *ConnectionFlowControllerAddBytesReadCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionFlowControllerAddBytesReadCall) Do(f func(protocol.ByteCount)) *ConnectionFlowControllerAddBytesReadCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionFlowControllerAddBytesReadCall) DoAndReturn(f func(protocol.ByteCount)) *ConnectionFlowControllerAddBytesReadCall { + c.Call = c.Call.DoAndReturn(f) + return c } // AddBytesSent mocks base method. @@ -57,9 +81,33 @@ func (m *MockConnectionFlowController) AddBytesSent(arg0 protocol.ByteCount) { } // AddBytesSent indicates an expected call of AddBytesSent. -func (mr *MockConnectionFlowControllerMockRecorder) AddBytesSent(arg0 any) *gomock.Call { +func (mr *MockConnectionFlowControllerMockRecorder) AddBytesSent(arg0 any) *ConnectionFlowControllerAddBytesSentCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesSent", reflect.TypeOf((*MockConnectionFlowController)(nil).AddBytesSent), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesSent", reflect.TypeOf((*MockConnectionFlowController)(nil).AddBytesSent), arg0) + return &ConnectionFlowControllerAddBytesSentCall{Call: call} +} + +// ConnectionFlowControllerAddBytesSentCall wrap *gomock.Call +type ConnectionFlowControllerAddBytesSentCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionFlowControllerAddBytesSentCall) Return() *ConnectionFlowControllerAddBytesSentCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionFlowControllerAddBytesSentCall) Do(f func(protocol.ByteCount)) *ConnectionFlowControllerAddBytesSentCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionFlowControllerAddBytesSentCall) DoAndReturn(f func(protocol.ByteCount)) *ConnectionFlowControllerAddBytesSentCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetWindowUpdate mocks base method. @@ -71,9 +119,33 @@ func (m *MockConnectionFlowController) GetWindowUpdate() protocol.ByteCount { } // GetWindowUpdate indicates an expected call of GetWindowUpdate. -func (mr *MockConnectionFlowControllerMockRecorder) GetWindowUpdate() *gomock.Call { +func (mr *MockConnectionFlowControllerMockRecorder) GetWindowUpdate() *ConnectionFlowControllerGetWindowUpdateCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWindowUpdate", reflect.TypeOf((*MockConnectionFlowController)(nil).GetWindowUpdate)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWindowUpdate", reflect.TypeOf((*MockConnectionFlowController)(nil).GetWindowUpdate)) + return &ConnectionFlowControllerGetWindowUpdateCall{Call: call} +} + +// ConnectionFlowControllerGetWindowUpdateCall wrap *gomock.Call +type ConnectionFlowControllerGetWindowUpdateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionFlowControllerGetWindowUpdateCall) Return(arg0 protocol.ByteCount) *ConnectionFlowControllerGetWindowUpdateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionFlowControllerGetWindowUpdateCall) Do(f func() protocol.ByteCount) *ConnectionFlowControllerGetWindowUpdateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionFlowControllerGetWindowUpdateCall) DoAndReturn(f func() protocol.ByteCount) *ConnectionFlowControllerGetWindowUpdateCall { + c.Call = c.Call.DoAndReturn(f) + return c } // IsNewlyBlocked mocks base method. @@ -86,9 +158,33 @@ func (m *MockConnectionFlowController) IsNewlyBlocked() (bool, protocol.ByteCoun } // IsNewlyBlocked indicates an expected call of IsNewlyBlocked. -func (mr *MockConnectionFlowControllerMockRecorder) IsNewlyBlocked() *gomock.Call { +func (mr *MockConnectionFlowControllerMockRecorder) IsNewlyBlocked() *ConnectionFlowControllerIsNewlyBlockedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsNewlyBlocked", reflect.TypeOf((*MockConnectionFlowController)(nil).IsNewlyBlocked)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsNewlyBlocked", reflect.TypeOf((*MockConnectionFlowController)(nil).IsNewlyBlocked)) + return &ConnectionFlowControllerIsNewlyBlockedCall{Call: call} +} + +// ConnectionFlowControllerIsNewlyBlockedCall wrap *gomock.Call +type ConnectionFlowControllerIsNewlyBlockedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionFlowControllerIsNewlyBlockedCall) Return(arg0 bool, arg1 protocol.ByteCount) *ConnectionFlowControllerIsNewlyBlockedCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionFlowControllerIsNewlyBlockedCall) Do(f func() (bool, protocol.ByteCount)) *ConnectionFlowControllerIsNewlyBlockedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionFlowControllerIsNewlyBlockedCall) DoAndReturn(f func() (bool, protocol.ByteCount)) *ConnectionFlowControllerIsNewlyBlockedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Reset mocks base method. @@ -100,9 +196,33 @@ func (m *MockConnectionFlowController) Reset() error { } // Reset indicates an expected call of Reset. -func (mr *MockConnectionFlowControllerMockRecorder) Reset() *gomock.Call { +func (mr *MockConnectionFlowControllerMockRecorder) Reset() *ConnectionFlowControllerResetCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reset", reflect.TypeOf((*MockConnectionFlowController)(nil).Reset)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reset", reflect.TypeOf((*MockConnectionFlowController)(nil).Reset)) + return &ConnectionFlowControllerResetCall{Call: call} +} + +// ConnectionFlowControllerResetCall wrap *gomock.Call +type ConnectionFlowControllerResetCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionFlowControllerResetCall) Return(arg0 error) *ConnectionFlowControllerResetCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionFlowControllerResetCall) Do(f func() error) *ConnectionFlowControllerResetCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionFlowControllerResetCall) DoAndReturn(f func() error) *ConnectionFlowControllerResetCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SendWindowSize mocks base method. @@ -114,9 +234,33 @@ func (m *MockConnectionFlowController) SendWindowSize() protocol.ByteCount { } // SendWindowSize indicates an expected call of SendWindowSize. -func (mr *MockConnectionFlowControllerMockRecorder) SendWindowSize() *gomock.Call { +func (mr *MockConnectionFlowControllerMockRecorder) SendWindowSize() *ConnectionFlowControllerSendWindowSizeCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendWindowSize", reflect.TypeOf((*MockConnectionFlowController)(nil).SendWindowSize)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendWindowSize", reflect.TypeOf((*MockConnectionFlowController)(nil).SendWindowSize)) + return &ConnectionFlowControllerSendWindowSizeCall{Call: call} +} + +// ConnectionFlowControllerSendWindowSizeCall wrap *gomock.Call +type ConnectionFlowControllerSendWindowSizeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionFlowControllerSendWindowSizeCall) Return(arg0 protocol.ByteCount) *ConnectionFlowControllerSendWindowSizeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionFlowControllerSendWindowSizeCall) Do(f func() protocol.ByteCount) *ConnectionFlowControllerSendWindowSizeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionFlowControllerSendWindowSizeCall) DoAndReturn(f func() protocol.ByteCount) *ConnectionFlowControllerSendWindowSizeCall { + c.Call = c.Call.DoAndReturn(f) + return c } // UpdateSendWindow mocks base method. @@ -126,7 +270,31 @@ func (m *MockConnectionFlowController) UpdateSendWindow(arg0 protocol.ByteCount) } // UpdateSendWindow indicates an expected call of UpdateSendWindow. -func (mr *MockConnectionFlowControllerMockRecorder) UpdateSendWindow(arg0 any) *gomock.Call { +func (mr *MockConnectionFlowControllerMockRecorder) UpdateSendWindow(arg0 any) *ConnectionFlowControllerUpdateSendWindowCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSendWindow", reflect.TypeOf((*MockConnectionFlowController)(nil).UpdateSendWindow), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSendWindow", reflect.TypeOf((*MockConnectionFlowController)(nil).UpdateSendWindow), arg0) + return &ConnectionFlowControllerUpdateSendWindowCall{Call: call} +} + +// ConnectionFlowControllerUpdateSendWindowCall wrap *gomock.Call +type ConnectionFlowControllerUpdateSendWindowCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionFlowControllerUpdateSendWindowCall) Return() *ConnectionFlowControllerUpdateSendWindowCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionFlowControllerUpdateSendWindowCall) Do(f func(protocol.ByteCount)) *ConnectionFlowControllerUpdateSendWindowCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionFlowControllerUpdateSendWindowCall) DoAndReturn(f func(protocol.ByteCount)) *ConnectionFlowControllerUpdateSendWindowCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/crypto_setup.go b/internal/mocks/crypto_setup.go index 1e4278ecad2..91f2586edc9 100644 --- a/internal/mocks/crypto_setup.go +++ b/internal/mocks/crypto_setup.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mocks -destination crypto_setup_tmp.go github.com/quic-go/quic-go/internal/handshake CryptoSetup +// mockgen -typed -build_flags=-tags=gomock -package mocks -destination crypto_setup_tmp.go github.com/quic-go/quic-go/internal/handshake CryptoSetup // // Package mocks is a generated GoMock package. package mocks @@ -46,9 +46,33 @@ func (m *MockCryptoSetup) ChangeConnectionID(arg0 protocol.ConnectionID) { } // ChangeConnectionID indicates an expected call of ChangeConnectionID. -func (mr *MockCryptoSetupMockRecorder) ChangeConnectionID(arg0 any) *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) ChangeConnectionID(arg0 any) *CryptoSetupChangeConnectionIDCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangeConnectionID", reflect.TypeOf((*MockCryptoSetup)(nil).ChangeConnectionID), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangeConnectionID", reflect.TypeOf((*MockCryptoSetup)(nil).ChangeConnectionID), arg0) + return &CryptoSetupChangeConnectionIDCall{Call: call} +} + +// CryptoSetupChangeConnectionIDCall wrap *gomock.Call +type CryptoSetupChangeConnectionIDCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupChangeConnectionIDCall) Return() *CryptoSetupChangeConnectionIDCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupChangeConnectionIDCall) Do(f func(protocol.ConnectionID)) *CryptoSetupChangeConnectionIDCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupChangeConnectionIDCall) DoAndReturn(f func(protocol.ConnectionID)) *CryptoSetupChangeConnectionIDCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Close mocks base method. @@ -60,9 +84,33 @@ func (m *MockCryptoSetup) Close() error { } // Close indicates an expected call of Close. -func (mr *MockCryptoSetupMockRecorder) Close() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) Close() *CryptoSetupCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockCryptoSetup)(nil).Close)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockCryptoSetup)(nil).Close)) + return &CryptoSetupCloseCall{Call: call} +} + +// CryptoSetupCloseCall wrap *gomock.Call +type CryptoSetupCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupCloseCall) Return(arg0 error) *CryptoSetupCloseCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupCloseCall) Do(f func() error) *CryptoSetupCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupCloseCall) DoAndReturn(f func() error) *CryptoSetupCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ConnectionState mocks base method. @@ -74,9 +122,33 @@ func (m *MockCryptoSetup) ConnectionState() handshake.ConnectionState { } // ConnectionState indicates an expected call of ConnectionState. -func (mr *MockCryptoSetupMockRecorder) ConnectionState() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) ConnectionState() *CryptoSetupConnectionStateCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectionState", reflect.TypeOf((*MockCryptoSetup)(nil).ConnectionState)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectionState", reflect.TypeOf((*MockCryptoSetup)(nil).ConnectionState)) + return &CryptoSetupConnectionStateCall{Call: call} +} + +// CryptoSetupConnectionStateCall wrap *gomock.Call +type CryptoSetupConnectionStateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupConnectionStateCall) Return(arg0 handshake.ConnectionState) *CryptoSetupConnectionStateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupConnectionStateCall) Do(f func() handshake.ConnectionState) *CryptoSetupConnectionStateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupConnectionStateCall) DoAndReturn(f func() handshake.ConnectionState) *CryptoSetupConnectionStateCall { + c.Call = c.Call.DoAndReturn(f) + return c } // DiscardInitialKeys mocks base method. @@ -86,9 +158,33 @@ func (m *MockCryptoSetup) DiscardInitialKeys() { } // DiscardInitialKeys indicates an expected call of DiscardInitialKeys. -func (mr *MockCryptoSetupMockRecorder) DiscardInitialKeys() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) DiscardInitialKeys() *CryptoSetupDiscardInitialKeysCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DiscardInitialKeys", reflect.TypeOf((*MockCryptoSetup)(nil).DiscardInitialKeys)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DiscardInitialKeys", reflect.TypeOf((*MockCryptoSetup)(nil).DiscardInitialKeys)) + return &CryptoSetupDiscardInitialKeysCall{Call: call} +} + +// CryptoSetupDiscardInitialKeysCall wrap *gomock.Call +type CryptoSetupDiscardInitialKeysCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupDiscardInitialKeysCall) Return() *CryptoSetupDiscardInitialKeysCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupDiscardInitialKeysCall) Do(f func()) *CryptoSetupDiscardInitialKeysCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupDiscardInitialKeysCall) DoAndReturn(f func()) *CryptoSetupDiscardInitialKeysCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Get0RTTOpener mocks base method. @@ -101,9 +197,33 @@ func (m *MockCryptoSetup) Get0RTTOpener() (handshake.LongHeaderOpener, error) { } // Get0RTTOpener indicates an expected call of Get0RTTOpener. -func (mr *MockCryptoSetupMockRecorder) Get0RTTOpener() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) Get0RTTOpener() *CryptoSetupGet0RTTOpenerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get0RTTOpener", reflect.TypeOf((*MockCryptoSetup)(nil).Get0RTTOpener)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get0RTTOpener", reflect.TypeOf((*MockCryptoSetup)(nil).Get0RTTOpener)) + return &CryptoSetupGet0RTTOpenerCall{Call: call} +} + +// CryptoSetupGet0RTTOpenerCall wrap *gomock.Call +type CryptoSetupGet0RTTOpenerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupGet0RTTOpenerCall) Return(arg0 handshake.LongHeaderOpener, arg1 error) *CryptoSetupGet0RTTOpenerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupGet0RTTOpenerCall) Do(f func() (handshake.LongHeaderOpener, error)) *CryptoSetupGet0RTTOpenerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupGet0RTTOpenerCall) DoAndReturn(f func() (handshake.LongHeaderOpener, error)) *CryptoSetupGet0RTTOpenerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Get0RTTSealer mocks base method. @@ -116,9 +236,33 @@ func (m *MockCryptoSetup) Get0RTTSealer() (handshake.LongHeaderSealer, error) { } // Get0RTTSealer indicates an expected call of Get0RTTSealer. -func (mr *MockCryptoSetupMockRecorder) Get0RTTSealer() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) Get0RTTSealer() *CryptoSetupGet0RTTSealerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get0RTTSealer", reflect.TypeOf((*MockCryptoSetup)(nil).Get0RTTSealer)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get0RTTSealer", reflect.TypeOf((*MockCryptoSetup)(nil).Get0RTTSealer)) + return &CryptoSetupGet0RTTSealerCall{Call: call} +} + +// CryptoSetupGet0RTTSealerCall wrap *gomock.Call +type CryptoSetupGet0RTTSealerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupGet0RTTSealerCall) Return(arg0 handshake.LongHeaderSealer, arg1 error) *CryptoSetupGet0RTTSealerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupGet0RTTSealerCall) Do(f func() (handshake.LongHeaderSealer, error)) *CryptoSetupGet0RTTSealerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupGet0RTTSealerCall) DoAndReturn(f func() (handshake.LongHeaderSealer, error)) *CryptoSetupGet0RTTSealerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Get1RTTOpener mocks base method. @@ -131,9 +275,33 @@ func (m *MockCryptoSetup) Get1RTTOpener() (handshake.ShortHeaderOpener, error) { } // Get1RTTOpener indicates an expected call of Get1RTTOpener. -func (mr *MockCryptoSetupMockRecorder) Get1RTTOpener() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) Get1RTTOpener() *CryptoSetupGet1RTTOpenerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get1RTTOpener", reflect.TypeOf((*MockCryptoSetup)(nil).Get1RTTOpener)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get1RTTOpener", reflect.TypeOf((*MockCryptoSetup)(nil).Get1RTTOpener)) + return &CryptoSetupGet1RTTOpenerCall{Call: call} +} + +// CryptoSetupGet1RTTOpenerCall wrap *gomock.Call +type CryptoSetupGet1RTTOpenerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupGet1RTTOpenerCall) Return(arg0 handshake.ShortHeaderOpener, arg1 error) *CryptoSetupGet1RTTOpenerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupGet1RTTOpenerCall) Do(f func() (handshake.ShortHeaderOpener, error)) *CryptoSetupGet1RTTOpenerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupGet1RTTOpenerCall) DoAndReturn(f func() (handshake.ShortHeaderOpener, error)) *CryptoSetupGet1RTTOpenerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Get1RTTSealer mocks base method. @@ -146,9 +314,33 @@ func (m *MockCryptoSetup) Get1RTTSealer() (handshake.ShortHeaderSealer, error) { } // Get1RTTSealer indicates an expected call of Get1RTTSealer. -func (mr *MockCryptoSetupMockRecorder) Get1RTTSealer() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) Get1RTTSealer() *CryptoSetupGet1RTTSealerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get1RTTSealer", reflect.TypeOf((*MockCryptoSetup)(nil).Get1RTTSealer)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get1RTTSealer", reflect.TypeOf((*MockCryptoSetup)(nil).Get1RTTSealer)) + return &CryptoSetupGet1RTTSealerCall{Call: call} +} + +// CryptoSetupGet1RTTSealerCall wrap *gomock.Call +type CryptoSetupGet1RTTSealerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupGet1RTTSealerCall) Return(arg0 handshake.ShortHeaderSealer, arg1 error) *CryptoSetupGet1RTTSealerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupGet1RTTSealerCall) Do(f func() (handshake.ShortHeaderSealer, error)) *CryptoSetupGet1RTTSealerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupGet1RTTSealerCall) DoAndReturn(f func() (handshake.ShortHeaderSealer, error)) *CryptoSetupGet1RTTSealerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetHandshakeOpener mocks base method. @@ -161,9 +353,33 @@ func (m *MockCryptoSetup) GetHandshakeOpener() (handshake.LongHeaderOpener, erro } // GetHandshakeOpener indicates an expected call of GetHandshakeOpener. -func (mr *MockCryptoSetupMockRecorder) GetHandshakeOpener() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) GetHandshakeOpener() *CryptoSetupGetHandshakeOpenerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHandshakeOpener", reflect.TypeOf((*MockCryptoSetup)(nil).GetHandshakeOpener)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHandshakeOpener", reflect.TypeOf((*MockCryptoSetup)(nil).GetHandshakeOpener)) + return &CryptoSetupGetHandshakeOpenerCall{Call: call} +} + +// CryptoSetupGetHandshakeOpenerCall wrap *gomock.Call +type CryptoSetupGetHandshakeOpenerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupGetHandshakeOpenerCall) Return(arg0 handshake.LongHeaderOpener, arg1 error) *CryptoSetupGetHandshakeOpenerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupGetHandshakeOpenerCall) Do(f func() (handshake.LongHeaderOpener, error)) *CryptoSetupGetHandshakeOpenerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupGetHandshakeOpenerCall) DoAndReturn(f func() (handshake.LongHeaderOpener, error)) *CryptoSetupGetHandshakeOpenerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetHandshakeSealer mocks base method. @@ -176,9 +392,33 @@ func (m *MockCryptoSetup) GetHandshakeSealer() (handshake.LongHeaderSealer, erro } // GetHandshakeSealer indicates an expected call of GetHandshakeSealer. -func (mr *MockCryptoSetupMockRecorder) GetHandshakeSealer() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) GetHandshakeSealer() *CryptoSetupGetHandshakeSealerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHandshakeSealer", reflect.TypeOf((*MockCryptoSetup)(nil).GetHandshakeSealer)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHandshakeSealer", reflect.TypeOf((*MockCryptoSetup)(nil).GetHandshakeSealer)) + return &CryptoSetupGetHandshakeSealerCall{Call: call} +} + +// CryptoSetupGetHandshakeSealerCall wrap *gomock.Call +type CryptoSetupGetHandshakeSealerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupGetHandshakeSealerCall) Return(arg0 handshake.LongHeaderSealer, arg1 error) *CryptoSetupGetHandshakeSealerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupGetHandshakeSealerCall) Do(f func() (handshake.LongHeaderSealer, error)) *CryptoSetupGetHandshakeSealerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupGetHandshakeSealerCall) DoAndReturn(f func() (handshake.LongHeaderSealer, error)) *CryptoSetupGetHandshakeSealerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetInitialOpener mocks base method. @@ -191,9 +431,33 @@ func (m *MockCryptoSetup) GetInitialOpener() (handshake.LongHeaderOpener, error) } // GetInitialOpener indicates an expected call of GetInitialOpener. -func (mr *MockCryptoSetupMockRecorder) GetInitialOpener() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) GetInitialOpener() *CryptoSetupGetInitialOpenerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInitialOpener", reflect.TypeOf((*MockCryptoSetup)(nil).GetInitialOpener)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInitialOpener", reflect.TypeOf((*MockCryptoSetup)(nil).GetInitialOpener)) + return &CryptoSetupGetInitialOpenerCall{Call: call} +} + +// CryptoSetupGetInitialOpenerCall wrap *gomock.Call +type CryptoSetupGetInitialOpenerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupGetInitialOpenerCall) Return(arg0 handshake.LongHeaderOpener, arg1 error) *CryptoSetupGetInitialOpenerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupGetInitialOpenerCall) Do(f func() (handshake.LongHeaderOpener, error)) *CryptoSetupGetInitialOpenerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupGetInitialOpenerCall) DoAndReturn(f func() (handshake.LongHeaderOpener, error)) *CryptoSetupGetInitialOpenerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetInitialSealer mocks base method. @@ -206,9 +470,33 @@ func (m *MockCryptoSetup) GetInitialSealer() (handshake.LongHeaderSealer, error) } // GetInitialSealer indicates an expected call of GetInitialSealer. -func (mr *MockCryptoSetupMockRecorder) GetInitialSealer() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) GetInitialSealer() *CryptoSetupGetInitialSealerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInitialSealer", reflect.TypeOf((*MockCryptoSetup)(nil).GetInitialSealer)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInitialSealer", reflect.TypeOf((*MockCryptoSetup)(nil).GetInitialSealer)) + return &CryptoSetupGetInitialSealerCall{Call: call} +} + +// CryptoSetupGetInitialSealerCall wrap *gomock.Call +type CryptoSetupGetInitialSealerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupGetInitialSealerCall) Return(arg0 handshake.LongHeaderSealer, arg1 error) *CryptoSetupGetInitialSealerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupGetInitialSealerCall) Do(f func() (handshake.LongHeaderSealer, error)) *CryptoSetupGetInitialSealerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupGetInitialSealerCall) DoAndReturn(f func() (handshake.LongHeaderSealer, error)) *CryptoSetupGetInitialSealerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetSessionTicket mocks base method. @@ -221,9 +509,33 @@ func (m *MockCryptoSetup) GetSessionTicket() ([]byte, error) { } // GetSessionTicket indicates an expected call of GetSessionTicket. -func (mr *MockCryptoSetupMockRecorder) GetSessionTicket() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) GetSessionTicket() *CryptoSetupGetSessionTicketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSessionTicket", reflect.TypeOf((*MockCryptoSetup)(nil).GetSessionTicket)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSessionTicket", reflect.TypeOf((*MockCryptoSetup)(nil).GetSessionTicket)) + return &CryptoSetupGetSessionTicketCall{Call: call} +} + +// CryptoSetupGetSessionTicketCall wrap *gomock.Call +type CryptoSetupGetSessionTicketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupGetSessionTicketCall) Return(arg0 []byte, arg1 error) *CryptoSetupGetSessionTicketCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupGetSessionTicketCall) Do(f func() ([]byte, error)) *CryptoSetupGetSessionTicketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupGetSessionTicketCall) DoAndReturn(f func() ([]byte, error)) *CryptoSetupGetSessionTicketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // HandleMessage mocks base method. @@ -235,9 +547,33 @@ func (m *MockCryptoSetup) HandleMessage(arg0 []byte, arg1 protocol.EncryptionLev } // HandleMessage indicates an expected call of HandleMessage. -func (mr *MockCryptoSetupMockRecorder) HandleMessage(arg0, arg1 any) *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) HandleMessage(arg0, arg1 any) *CryptoSetupHandleMessageCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMessage", reflect.TypeOf((*MockCryptoSetup)(nil).HandleMessage), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMessage", reflect.TypeOf((*MockCryptoSetup)(nil).HandleMessage), arg0, arg1) + return &CryptoSetupHandleMessageCall{Call: call} +} + +// CryptoSetupHandleMessageCall wrap *gomock.Call +type CryptoSetupHandleMessageCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupHandleMessageCall) Return(arg0 error) *CryptoSetupHandleMessageCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupHandleMessageCall) Do(f func([]byte, protocol.EncryptionLevel) error) *CryptoSetupHandleMessageCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupHandleMessageCall) DoAndReturn(f func([]byte, protocol.EncryptionLevel) error) *CryptoSetupHandleMessageCall { + c.Call = c.Call.DoAndReturn(f) + return c } // NextEvent mocks base method. @@ -249,9 +585,33 @@ func (m *MockCryptoSetup) NextEvent() handshake.Event { } // NextEvent indicates an expected call of NextEvent. -func (mr *MockCryptoSetupMockRecorder) NextEvent() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) NextEvent() *CryptoSetupNextEventCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NextEvent", reflect.TypeOf((*MockCryptoSetup)(nil).NextEvent)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NextEvent", reflect.TypeOf((*MockCryptoSetup)(nil).NextEvent)) + return &CryptoSetupNextEventCall{Call: call} +} + +// CryptoSetupNextEventCall wrap *gomock.Call +type CryptoSetupNextEventCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupNextEventCall) Return(arg0 handshake.Event) *CryptoSetupNextEventCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupNextEventCall) Do(f func() handshake.Event) *CryptoSetupNextEventCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupNextEventCall) DoAndReturn(f func() handshake.Event) *CryptoSetupNextEventCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetHandshakeConfirmed mocks base method. @@ -261,9 +621,33 @@ func (m *MockCryptoSetup) SetHandshakeConfirmed() { } // SetHandshakeConfirmed indicates an expected call of SetHandshakeConfirmed. -func (mr *MockCryptoSetupMockRecorder) SetHandshakeConfirmed() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) SetHandshakeConfirmed() *CryptoSetupSetHandshakeConfirmedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHandshakeConfirmed", reflect.TypeOf((*MockCryptoSetup)(nil).SetHandshakeConfirmed)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHandshakeConfirmed", reflect.TypeOf((*MockCryptoSetup)(nil).SetHandshakeConfirmed)) + return &CryptoSetupSetHandshakeConfirmedCall{Call: call} +} + +// CryptoSetupSetHandshakeConfirmedCall wrap *gomock.Call +type CryptoSetupSetHandshakeConfirmedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupSetHandshakeConfirmedCall) Return() *CryptoSetupSetHandshakeConfirmedCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupSetHandshakeConfirmedCall) Do(f func()) *CryptoSetupSetHandshakeConfirmedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupSetHandshakeConfirmedCall) DoAndReturn(f func()) *CryptoSetupSetHandshakeConfirmedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetLargest1RTTAcked mocks base method. @@ -275,9 +659,33 @@ func (m *MockCryptoSetup) SetLargest1RTTAcked(arg0 protocol.PacketNumber) error } // SetLargest1RTTAcked indicates an expected call of SetLargest1RTTAcked. -func (mr *MockCryptoSetupMockRecorder) SetLargest1RTTAcked(arg0 any) *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) SetLargest1RTTAcked(arg0 any) *CryptoSetupSetLargest1RTTAckedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLargest1RTTAcked", reflect.TypeOf((*MockCryptoSetup)(nil).SetLargest1RTTAcked), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLargest1RTTAcked", reflect.TypeOf((*MockCryptoSetup)(nil).SetLargest1RTTAcked), arg0) + return &CryptoSetupSetLargest1RTTAckedCall{Call: call} +} + +// CryptoSetupSetLargest1RTTAckedCall wrap *gomock.Call +type CryptoSetupSetLargest1RTTAckedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupSetLargest1RTTAckedCall) Return(arg0 error) *CryptoSetupSetLargest1RTTAckedCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupSetLargest1RTTAckedCall) Do(f func(protocol.PacketNumber) error) *CryptoSetupSetLargest1RTTAckedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupSetLargest1RTTAckedCall) DoAndReturn(f func(protocol.PacketNumber) error) *CryptoSetupSetLargest1RTTAckedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // StartHandshake mocks base method. @@ -289,7 +697,31 @@ func (m *MockCryptoSetup) StartHandshake() error { } // StartHandshake indicates an expected call of StartHandshake. -func (mr *MockCryptoSetupMockRecorder) StartHandshake() *gomock.Call { +func (mr *MockCryptoSetupMockRecorder) StartHandshake() *CryptoSetupStartHandshakeCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartHandshake", reflect.TypeOf((*MockCryptoSetup)(nil).StartHandshake)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartHandshake", reflect.TypeOf((*MockCryptoSetup)(nil).StartHandshake)) + return &CryptoSetupStartHandshakeCall{Call: call} +} + +// CryptoSetupStartHandshakeCall wrap *gomock.Call +type CryptoSetupStartHandshakeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoSetupStartHandshakeCall) Return(arg0 error) *CryptoSetupStartHandshakeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoSetupStartHandshakeCall) Do(f func() error) *CryptoSetupStartHandshakeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoSetupStartHandshakeCall) DoAndReturn(f func() error) *CryptoSetupStartHandshakeCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/logging/internal/connection_tracer.go b/internal/mocks/logging/internal/connection_tracer.go index 5131453a4a6..b83831a20d7 100644 --- a/internal/mocks/logging/internal/connection_tracer.go +++ b/internal/mocks/logging/internal/connection_tracer.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package internal -destination internal/connection_tracer.go github.com/quic-go/quic-go/internal/mocks/logging ConnectionTracer +// mockgen -typed -build_flags=-tags=gomock -package internal -destination internal/connection_tracer.go github.com/quic-go/quic-go/internal/mocks/logging ConnectionTracer // // Package internal is a generated GoMock package. package internal @@ -50,9 +50,33 @@ func (m *MockConnectionTracer) AcknowledgedPacket(arg0 protocol.EncryptionLevel, } // AcknowledgedPacket indicates an expected call of AcknowledgedPacket. -func (mr *MockConnectionTracerMockRecorder) AcknowledgedPacket(arg0, arg1 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) AcknowledgedPacket(arg0, arg1 any) *ConnectionTracerAcknowledgedPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcknowledgedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).AcknowledgedPacket), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcknowledgedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).AcknowledgedPacket), arg0, arg1) + return &ConnectionTracerAcknowledgedPacketCall{Call: call} +} + +// ConnectionTracerAcknowledgedPacketCall wrap *gomock.Call +type ConnectionTracerAcknowledgedPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerAcknowledgedPacketCall) Return() *ConnectionTracerAcknowledgedPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerAcknowledgedPacketCall) Do(f func(protocol.EncryptionLevel, protocol.PacketNumber)) *ConnectionTracerAcknowledgedPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerAcknowledgedPacketCall) DoAndReturn(f func(protocol.EncryptionLevel, protocol.PacketNumber)) *ConnectionTracerAcknowledgedPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // BufferedPacket mocks base method. @@ -62,9 +86,33 @@ func (m *MockConnectionTracer) BufferedPacket(arg0 logging.PacketType, arg1 prot } // BufferedPacket indicates an expected call of BufferedPacket. -func (mr *MockConnectionTracerMockRecorder) BufferedPacket(arg0, arg1 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) BufferedPacket(arg0, arg1 any) *ConnectionTracerBufferedPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BufferedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).BufferedPacket), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BufferedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).BufferedPacket), arg0, arg1) + return &ConnectionTracerBufferedPacketCall{Call: call} +} + +// ConnectionTracerBufferedPacketCall wrap *gomock.Call +type ConnectionTracerBufferedPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerBufferedPacketCall) Return() *ConnectionTracerBufferedPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerBufferedPacketCall) Do(f func(logging.PacketType, protocol.ByteCount)) *ConnectionTracerBufferedPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerBufferedPacketCall) DoAndReturn(f func(logging.PacketType, protocol.ByteCount)) *ConnectionTracerBufferedPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Close mocks base method. @@ -74,9 +122,33 @@ func (m *MockConnectionTracer) Close() { } // Close indicates an expected call of Close. -func (mr *MockConnectionTracerMockRecorder) Close() *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) Close() *ConnectionTracerCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockConnectionTracer)(nil).Close)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockConnectionTracer)(nil).Close)) + return &ConnectionTracerCloseCall{Call: call} +} + +// ConnectionTracerCloseCall wrap *gomock.Call +type ConnectionTracerCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerCloseCall) Return() *ConnectionTracerCloseCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerCloseCall) Do(f func()) *ConnectionTracerCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerCloseCall) DoAndReturn(f func()) *ConnectionTracerCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ClosedConnection mocks base method. @@ -86,9 +158,33 @@ func (m *MockConnectionTracer) ClosedConnection(arg0 error) { } // ClosedConnection indicates an expected call of ClosedConnection. -func (mr *MockConnectionTracerMockRecorder) ClosedConnection(arg0 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) ClosedConnection(arg0 any) *ConnectionTracerClosedConnectionCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClosedConnection", reflect.TypeOf((*MockConnectionTracer)(nil).ClosedConnection), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClosedConnection", reflect.TypeOf((*MockConnectionTracer)(nil).ClosedConnection), arg0) + return &ConnectionTracerClosedConnectionCall{Call: call} +} + +// ConnectionTracerClosedConnectionCall wrap *gomock.Call +type ConnectionTracerClosedConnectionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerClosedConnectionCall) Return() *ConnectionTracerClosedConnectionCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerClosedConnectionCall) Do(f func(error)) *ConnectionTracerClosedConnectionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerClosedConnectionCall) DoAndReturn(f func(error)) *ConnectionTracerClosedConnectionCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Debug mocks base method. @@ -98,9 +194,33 @@ func (m *MockConnectionTracer) Debug(arg0, arg1 string) { } // Debug indicates an expected call of Debug. -func (mr *MockConnectionTracerMockRecorder) Debug(arg0, arg1 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) Debug(arg0, arg1 any) *ConnectionTracerDebugCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockConnectionTracer)(nil).Debug), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockConnectionTracer)(nil).Debug), arg0, arg1) + return &ConnectionTracerDebugCall{Call: call} +} + +// ConnectionTracerDebugCall wrap *gomock.Call +type ConnectionTracerDebugCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerDebugCall) Return() *ConnectionTracerDebugCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerDebugCall) Do(f func(string, string)) *ConnectionTracerDebugCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerDebugCall) DoAndReturn(f func(string, string)) *ConnectionTracerDebugCall { + c.Call = c.Call.DoAndReturn(f) + return c } // DroppedEncryptionLevel mocks base method. @@ -110,9 +230,33 @@ func (m *MockConnectionTracer) DroppedEncryptionLevel(arg0 protocol.EncryptionLe } // DroppedEncryptionLevel indicates an expected call of DroppedEncryptionLevel. -func (mr *MockConnectionTracerMockRecorder) DroppedEncryptionLevel(arg0 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) DroppedEncryptionLevel(arg0 any) *ConnectionTracerDroppedEncryptionLevelCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedEncryptionLevel", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedEncryptionLevel), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedEncryptionLevel", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedEncryptionLevel), arg0) + return &ConnectionTracerDroppedEncryptionLevelCall{Call: call} +} + +// ConnectionTracerDroppedEncryptionLevelCall wrap *gomock.Call +type ConnectionTracerDroppedEncryptionLevelCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerDroppedEncryptionLevelCall) Return() *ConnectionTracerDroppedEncryptionLevelCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerDroppedEncryptionLevelCall) Do(f func(protocol.EncryptionLevel)) *ConnectionTracerDroppedEncryptionLevelCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerDroppedEncryptionLevelCall) DoAndReturn(f func(protocol.EncryptionLevel)) *ConnectionTracerDroppedEncryptionLevelCall { + c.Call = c.Call.DoAndReturn(f) + return c } // DroppedKey mocks base method. @@ -122,9 +266,33 @@ func (m *MockConnectionTracer) DroppedKey(arg0 protocol.KeyPhase) { } // DroppedKey indicates an expected call of DroppedKey. -func (mr *MockConnectionTracerMockRecorder) DroppedKey(arg0 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) DroppedKey(arg0 any) *ConnectionTracerDroppedKeyCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedKey", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedKey), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedKey", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedKey), arg0) + return &ConnectionTracerDroppedKeyCall{Call: call} +} + +// ConnectionTracerDroppedKeyCall wrap *gomock.Call +type ConnectionTracerDroppedKeyCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerDroppedKeyCall) Return() *ConnectionTracerDroppedKeyCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerDroppedKeyCall) Do(f func(protocol.KeyPhase)) *ConnectionTracerDroppedKeyCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerDroppedKeyCall) DoAndReturn(f func(protocol.KeyPhase)) *ConnectionTracerDroppedKeyCall { + c.Call = c.Call.DoAndReturn(f) + return c } // DroppedPacket mocks base method. @@ -134,9 +302,33 @@ func (m *MockConnectionTracer) DroppedPacket(arg0 logging.PacketType, arg1 proto } // DroppedPacket indicates an expected call of DroppedPacket. -func (mr *MockConnectionTracerMockRecorder) DroppedPacket(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) DroppedPacket(arg0, arg1, arg2 any) *ConnectionTracerDroppedPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedPacket), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedPacket), arg0, arg1, arg2) + return &ConnectionTracerDroppedPacketCall{Call: call} +} + +// ConnectionTracerDroppedPacketCall wrap *gomock.Call +type ConnectionTracerDroppedPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerDroppedPacketCall) Return() *ConnectionTracerDroppedPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerDroppedPacketCall) Do(f func(logging.PacketType, protocol.ByteCount, logging.PacketDropReason)) *ConnectionTracerDroppedPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerDroppedPacketCall) DoAndReturn(f func(logging.PacketType, protocol.ByteCount, logging.PacketDropReason)) *ConnectionTracerDroppedPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ECNStateUpdated mocks base method. @@ -146,9 +338,33 @@ func (m *MockConnectionTracer) ECNStateUpdated(arg0 logging.ECNState, arg1 loggi } // ECNStateUpdated indicates an expected call of ECNStateUpdated. -func (mr *MockConnectionTracerMockRecorder) ECNStateUpdated(arg0, arg1 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) ECNStateUpdated(arg0, arg1 any) *ConnectionTracerECNStateUpdatedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNStateUpdated", reflect.TypeOf((*MockConnectionTracer)(nil).ECNStateUpdated), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNStateUpdated", reflect.TypeOf((*MockConnectionTracer)(nil).ECNStateUpdated), arg0, arg1) + return &ConnectionTracerECNStateUpdatedCall{Call: call} +} + +// ConnectionTracerECNStateUpdatedCall wrap *gomock.Call +type ConnectionTracerECNStateUpdatedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerECNStateUpdatedCall) Return() *ConnectionTracerECNStateUpdatedCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerECNStateUpdatedCall) Do(f func(logging.ECNState, logging.ECNStateTrigger)) *ConnectionTracerECNStateUpdatedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerECNStateUpdatedCall) DoAndReturn(f func(logging.ECNState, logging.ECNStateTrigger)) *ConnectionTracerECNStateUpdatedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // LossTimerCanceled mocks base method. @@ -158,9 +374,33 @@ func (m *MockConnectionTracer) LossTimerCanceled() { } // LossTimerCanceled indicates an expected call of LossTimerCanceled. -func (mr *MockConnectionTracerMockRecorder) LossTimerCanceled() *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) LossTimerCanceled() *ConnectionTracerLossTimerCanceledCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LossTimerCanceled", reflect.TypeOf((*MockConnectionTracer)(nil).LossTimerCanceled)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LossTimerCanceled", reflect.TypeOf((*MockConnectionTracer)(nil).LossTimerCanceled)) + return &ConnectionTracerLossTimerCanceledCall{Call: call} +} + +// ConnectionTracerLossTimerCanceledCall wrap *gomock.Call +type ConnectionTracerLossTimerCanceledCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerLossTimerCanceledCall) Return() *ConnectionTracerLossTimerCanceledCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerLossTimerCanceledCall) Do(f func()) *ConnectionTracerLossTimerCanceledCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerLossTimerCanceledCall) DoAndReturn(f func()) *ConnectionTracerLossTimerCanceledCall { + c.Call = c.Call.DoAndReturn(f) + return c } // LossTimerExpired mocks base method. @@ -170,9 +410,33 @@ func (m *MockConnectionTracer) LossTimerExpired(arg0 logging.TimerType, arg1 pro } // LossTimerExpired indicates an expected call of LossTimerExpired. -func (mr *MockConnectionTracerMockRecorder) LossTimerExpired(arg0, arg1 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) LossTimerExpired(arg0, arg1 any) *ConnectionTracerLossTimerExpiredCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LossTimerExpired", reflect.TypeOf((*MockConnectionTracer)(nil).LossTimerExpired), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LossTimerExpired", reflect.TypeOf((*MockConnectionTracer)(nil).LossTimerExpired), arg0, arg1) + return &ConnectionTracerLossTimerExpiredCall{Call: call} +} + +// ConnectionTracerLossTimerExpiredCall wrap *gomock.Call +type ConnectionTracerLossTimerExpiredCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerLossTimerExpiredCall) Return() *ConnectionTracerLossTimerExpiredCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerLossTimerExpiredCall) Do(f func(logging.TimerType, protocol.EncryptionLevel)) *ConnectionTracerLossTimerExpiredCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerLossTimerExpiredCall) DoAndReturn(f func(logging.TimerType, protocol.EncryptionLevel)) *ConnectionTracerLossTimerExpiredCall { + c.Call = c.Call.DoAndReturn(f) + return c } // LostPacket mocks base method. @@ -182,9 +446,33 @@ func (m *MockConnectionTracer) LostPacket(arg0 protocol.EncryptionLevel, arg1 pr } // LostPacket indicates an expected call of LostPacket. -func (mr *MockConnectionTracerMockRecorder) LostPacket(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) LostPacket(arg0, arg1, arg2 any) *ConnectionTracerLostPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LostPacket", reflect.TypeOf((*MockConnectionTracer)(nil).LostPacket), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LostPacket", reflect.TypeOf((*MockConnectionTracer)(nil).LostPacket), arg0, arg1, arg2) + return &ConnectionTracerLostPacketCall{Call: call} +} + +// ConnectionTracerLostPacketCall wrap *gomock.Call +type ConnectionTracerLostPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerLostPacketCall) Return() *ConnectionTracerLostPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerLostPacketCall) Do(f func(protocol.EncryptionLevel, protocol.PacketNumber, logging.PacketLossReason)) *ConnectionTracerLostPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerLostPacketCall) DoAndReturn(f func(protocol.EncryptionLevel, protocol.PacketNumber, logging.PacketLossReason)) *ConnectionTracerLostPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // NegotiatedVersion mocks base method. @@ -194,9 +482,33 @@ func (m *MockConnectionTracer) NegotiatedVersion(arg0 protocol.VersionNumber, ar } // NegotiatedVersion indicates an expected call of NegotiatedVersion. -func (mr *MockConnectionTracerMockRecorder) NegotiatedVersion(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) NegotiatedVersion(arg0, arg1, arg2 any) *ConnectionTracerNegotiatedVersionCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NegotiatedVersion", reflect.TypeOf((*MockConnectionTracer)(nil).NegotiatedVersion), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NegotiatedVersion", reflect.TypeOf((*MockConnectionTracer)(nil).NegotiatedVersion), arg0, arg1, arg2) + return &ConnectionTracerNegotiatedVersionCall{Call: call} +} + +// ConnectionTracerNegotiatedVersionCall wrap *gomock.Call +type ConnectionTracerNegotiatedVersionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerNegotiatedVersionCall) Return() *ConnectionTracerNegotiatedVersionCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerNegotiatedVersionCall) Do(f func(protocol.VersionNumber, []protocol.VersionNumber, []protocol.VersionNumber)) *ConnectionTracerNegotiatedVersionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerNegotiatedVersionCall) DoAndReturn(f func(protocol.VersionNumber, []protocol.VersionNumber, []protocol.VersionNumber)) *ConnectionTracerNegotiatedVersionCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReceivedLongHeaderPacket mocks base method. @@ -206,9 +518,33 @@ func (m *MockConnectionTracer) ReceivedLongHeaderPacket(arg0 *wire.ExtendedHeade } // ReceivedLongHeaderPacket indicates an expected call of ReceivedLongHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) ReceivedLongHeaderPacket(arg0, arg1, arg2, arg3 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) ReceivedLongHeaderPacket(arg0, arg1, arg2, arg3 any) *ConnectionTracerReceivedLongHeaderPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedLongHeaderPacket), arg0, arg1, arg2, arg3) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedLongHeaderPacket), arg0, arg1, arg2, arg3) + return &ConnectionTracerReceivedLongHeaderPacketCall{Call: call} +} + +// ConnectionTracerReceivedLongHeaderPacketCall wrap *gomock.Call +type ConnectionTracerReceivedLongHeaderPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerReceivedLongHeaderPacketCall) Return() *ConnectionTracerReceivedLongHeaderPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerReceivedLongHeaderPacketCall) Do(f func(*wire.ExtendedHeader, protocol.ByteCount, protocol.ECN, []logging.Frame)) *ConnectionTracerReceivedLongHeaderPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerReceivedLongHeaderPacketCall) DoAndReturn(f func(*wire.ExtendedHeader, protocol.ByteCount, protocol.ECN, []logging.Frame)) *ConnectionTracerReceivedLongHeaderPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReceivedRetry mocks base method. @@ -218,9 +554,33 @@ func (m *MockConnectionTracer) ReceivedRetry(arg0 *wire.Header) { } // ReceivedRetry indicates an expected call of ReceivedRetry. -func (mr *MockConnectionTracerMockRecorder) ReceivedRetry(arg0 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) ReceivedRetry(arg0 any) *ConnectionTracerReceivedRetryCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedRetry", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedRetry), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedRetry", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedRetry), arg0) + return &ConnectionTracerReceivedRetryCall{Call: call} +} + +// ConnectionTracerReceivedRetryCall wrap *gomock.Call +type ConnectionTracerReceivedRetryCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerReceivedRetryCall) Return() *ConnectionTracerReceivedRetryCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerReceivedRetryCall) Do(f func(*wire.Header)) *ConnectionTracerReceivedRetryCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerReceivedRetryCall) DoAndReturn(f func(*wire.Header)) *ConnectionTracerReceivedRetryCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReceivedShortHeaderPacket mocks base method. @@ -230,9 +590,33 @@ func (m *MockConnectionTracer) ReceivedShortHeaderPacket(arg0 *logging.ShortHead } // ReceivedShortHeaderPacket indicates an expected call of ReceivedShortHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) ReceivedShortHeaderPacket(arg0, arg1, arg2, arg3 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) ReceivedShortHeaderPacket(arg0, arg1, arg2, arg3 any) *ConnectionTracerReceivedShortHeaderPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedShortHeaderPacket), arg0, arg1, arg2, arg3) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedShortHeaderPacket), arg0, arg1, arg2, arg3) + return &ConnectionTracerReceivedShortHeaderPacketCall{Call: call} +} + +// ConnectionTracerReceivedShortHeaderPacketCall wrap *gomock.Call +type ConnectionTracerReceivedShortHeaderPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerReceivedShortHeaderPacketCall) Return() *ConnectionTracerReceivedShortHeaderPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerReceivedShortHeaderPacketCall) Do(f func(*logging.ShortHeader, protocol.ByteCount, protocol.ECN, []logging.Frame)) *ConnectionTracerReceivedShortHeaderPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerReceivedShortHeaderPacketCall) DoAndReturn(f func(*logging.ShortHeader, protocol.ByteCount, protocol.ECN, []logging.Frame)) *ConnectionTracerReceivedShortHeaderPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReceivedTransportParameters mocks base method. @@ -242,9 +626,33 @@ func (m *MockConnectionTracer) ReceivedTransportParameters(arg0 *wire.TransportP } // ReceivedTransportParameters indicates an expected call of ReceivedTransportParameters. -func (mr *MockConnectionTracerMockRecorder) ReceivedTransportParameters(arg0 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) ReceivedTransportParameters(arg0 any) *ConnectionTracerReceivedTransportParametersCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedTransportParameters), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedTransportParameters), arg0) + return &ConnectionTracerReceivedTransportParametersCall{Call: call} +} + +// ConnectionTracerReceivedTransportParametersCall wrap *gomock.Call +type ConnectionTracerReceivedTransportParametersCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerReceivedTransportParametersCall) Return() *ConnectionTracerReceivedTransportParametersCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerReceivedTransportParametersCall) Do(f func(*wire.TransportParameters)) *ConnectionTracerReceivedTransportParametersCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerReceivedTransportParametersCall) DoAndReturn(f func(*wire.TransportParameters)) *ConnectionTracerReceivedTransportParametersCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReceivedVersionNegotiationPacket mocks base method. @@ -254,9 +662,33 @@ func (m *MockConnectionTracer) ReceivedVersionNegotiationPacket(arg0, arg1 proto } // ReceivedVersionNegotiationPacket indicates an expected call of ReceivedVersionNegotiationPacket. -func (mr *MockConnectionTracerMockRecorder) ReceivedVersionNegotiationPacket(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) ReceivedVersionNegotiationPacket(arg0, arg1, arg2 any) *ConnectionTracerReceivedVersionNegotiationPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedVersionNegotiationPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedVersionNegotiationPacket), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedVersionNegotiationPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedVersionNegotiationPacket), arg0, arg1, arg2) + return &ConnectionTracerReceivedVersionNegotiationPacketCall{Call: call} +} + +// ConnectionTracerReceivedVersionNegotiationPacketCall wrap *gomock.Call +type ConnectionTracerReceivedVersionNegotiationPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerReceivedVersionNegotiationPacketCall) Return() *ConnectionTracerReceivedVersionNegotiationPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerReceivedVersionNegotiationPacketCall) Do(f func(protocol.ArbitraryLenConnectionID, protocol.ArbitraryLenConnectionID, []protocol.VersionNumber)) *ConnectionTracerReceivedVersionNegotiationPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerReceivedVersionNegotiationPacketCall) DoAndReturn(f func(protocol.ArbitraryLenConnectionID, protocol.ArbitraryLenConnectionID, []protocol.VersionNumber)) *ConnectionTracerReceivedVersionNegotiationPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // RestoredTransportParameters mocks base method. @@ -266,9 +698,33 @@ func (m *MockConnectionTracer) RestoredTransportParameters(arg0 *wire.TransportP } // RestoredTransportParameters indicates an expected call of RestoredTransportParameters. -func (mr *MockConnectionTracerMockRecorder) RestoredTransportParameters(arg0 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) RestoredTransportParameters(arg0 any) *ConnectionTracerRestoredTransportParametersCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestoredTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).RestoredTransportParameters), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestoredTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).RestoredTransportParameters), arg0) + return &ConnectionTracerRestoredTransportParametersCall{Call: call} +} + +// ConnectionTracerRestoredTransportParametersCall wrap *gomock.Call +type ConnectionTracerRestoredTransportParametersCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerRestoredTransportParametersCall) Return() *ConnectionTracerRestoredTransportParametersCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerRestoredTransportParametersCall) Do(f func(*wire.TransportParameters)) *ConnectionTracerRestoredTransportParametersCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerRestoredTransportParametersCall) DoAndReturn(f func(*wire.TransportParameters)) *ConnectionTracerRestoredTransportParametersCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SentLongHeaderPacket mocks base method. @@ -278,9 +734,33 @@ func (m *MockConnectionTracer) SentLongHeaderPacket(arg0 *wire.ExtendedHeader, a } // SentLongHeaderPacket indicates an expected call of SentLongHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) SentLongHeaderPacket(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) SentLongHeaderPacket(arg0, arg1, arg2, arg3, arg4 any) *ConnectionTracerSentLongHeaderPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentLongHeaderPacket), arg0, arg1, arg2, arg3, arg4) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentLongHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentLongHeaderPacket), arg0, arg1, arg2, arg3, arg4) + return &ConnectionTracerSentLongHeaderPacketCall{Call: call} +} + +// ConnectionTracerSentLongHeaderPacketCall wrap *gomock.Call +type ConnectionTracerSentLongHeaderPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerSentLongHeaderPacketCall) Return() *ConnectionTracerSentLongHeaderPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerSentLongHeaderPacketCall) Do(f func(*wire.ExtendedHeader, protocol.ByteCount, protocol.ECN, *wire.AckFrame, []logging.Frame)) *ConnectionTracerSentLongHeaderPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerSentLongHeaderPacketCall) DoAndReturn(f func(*wire.ExtendedHeader, protocol.ByteCount, protocol.ECN, *wire.AckFrame, []logging.Frame)) *ConnectionTracerSentLongHeaderPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SentShortHeaderPacket mocks base method. @@ -290,9 +770,33 @@ func (m *MockConnectionTracer) SentShortHeaderPacket(arg0 *logging.ShortHeader, } // SentShortHeaderPacket indicates an expected call of SentShortHeaderPacket. -func (mr *MockConnectionTracerMockRecorder) SentShortHeaderPacket(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) SentShortHeaderPacket(arg0, arg1, arg2, arg3, arg4 any) *ConnectionTracerSentShortHeaderPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentShortHeaderPacket), arg0, arg1, arg2, arg3, arg4) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentShortHeaderPacket", reflect.TypeOf((*MockConnectionTracer)(nil).SentShortHeaderPacket), arg0, arg1, arg2, arg3, arg4) + return &ConnectionTracerSentShortHeaderPacketCall{Call: call} +} + +// ConnectionTracerSentShortHeaderPacketCall wrap *gomock.Call +type ConnectionTracerSentShortHeaderPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerSentShortHeaderPacketCall) Return() *ConnectionTracerSentShortHeaderPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerSentShortHeaderPacketCall) Do(f func(*logging.ShortHeader, protocol.ByteCount, protocol.ECN, *wire.AckFrame, []logging.Frame)) *ConnectionTracerSentShortHeaderPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerSentShortHeaderPacketCall) DoAndReturn(f func(*logging.ShortHeader, protocol.ByteCount, protocol.ECN, *wire.AckFrame, []logging.Frame)) *ConnectionTracerSentShortHeaderPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SentTransportParameters mocks base method. @@ -302,9 +806,33 @@ func (m *MockConnectionTracer) SentTransportParameters(arg0 *wire.TransportParam } // SentTransportParameters indicates an expected call of SentTransportParameters. -func (mr *MockConnectionTracerMockRecorder) SentTransportParameters(arg0 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) SentTransportParameters(arg0 any) *ConnectionTracerSentTransportParametersCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).SentTransportParameters), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).SentTransportParameters), arg0) + return &ConnectionTracerSentTransportParametersCall{Call: call} +} + +// ConnectionTracerSentTransportParametersCall wrap *gomock.Call +type ConnectionTracerSentTransportParametersCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerSentTransportParametersCall) Return() *ConnectionTracerSentTransportParametersCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerSentTransportParametersCall) Do(f func(*wire.TransportParameters)) *ConnectionTracerSentTransportParametersCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerSentTransportParametersCall) DoAndReturn(f func(*wire.TransportParameters)) *ConnectionTracerSentTransportParametersCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetLossTimer mocks base method. @@ -314,9 +842,33 @@ func (m *MockConnectionTracer) SetLossTimer(arg0 logging.TimerType, arg1 protoco } // SetLossTimer indicates an expected call of SetLossTimer. -func (mr *MockConnectionTracerMockRecorder) SetLossTimer(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) SetLossTimer(arg0, arg1, arg2 any) *ConnectionTracerSetLossTimerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLossTimer", reflect.TypeOf((*MockConnectionTracer)(nil).SetLossTimer), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLossTimer", reflect.TypeOf((*MockConnectionTracer)(nil).SetLossTimer), arg0, arg1, arg2) + return &ConnectionTracerSetLossTimerCall{Call: call} +} + +// ConnectionTracerSetLossTimerCall wrap *gomock.Call +type ConnectionTracerSetLossTimerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerSetLossTimerCall) Return() *ConnectionTracerSetLossTimerCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerSetLossTimerCall) Do(f func(logging.TimerType, protocol.EncryptionLevel, time.Time)) *ConnectionTracerSetLossTimerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerSetLossTimerCall) DoAndReturn(f func(logging.TimerType, protocol.EncryptionLevel, time.Time)) *ConnectionTracerSetLossTimerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // StartedConnection mocks base method. @@ -326,9 +878,33 @@ 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 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) StartedConnection(arg0, arg1, arg2, arg3 any) *ConnectionTracerStartedConnectionCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartedConnection", reflect.TypeOf((*MockConnectionTracer)(nil).StartedConnection), arg0, arg1, arg2, arg3) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartedConnection", reflect.TypeOf((*MockConnectionTracer)(nil).StartedConnection), arg0, arg1, arg2, arg3) + return &ConnectionTracerStartedConnectionCall{Call: call} +} + +// ConnectionTracerStartedConnectionCall wrap *gomock.Call +type ConnectionTracerStartedConnectionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerStartedConnectionCall) Return() *ConnectionTracerStartedConnectionCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerStartedConnectionCall) Do(f func(net.Addr, net.Addr, protocol.ConnectionID, protocol.ConnectionID)) *ConnectionTracerStartedConnectionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerStartedConnectionCall) DoAndReturn(f func(net.Addr, net.Addr, protocol.ConnectionID, protocol.ConnectionID)) *ConnectionTracerStartedConnectionCall { + c.Call = c.Call.DoAndReturn(f) + return c } // UpdatedCongestionState mocks base method. @@ -338,9 +914,33 @@ func (m *MockConnectionTracer) UpdatedCongestionState(arg0 logging.CongestionSta } // UpdatedCongestionState indicates an expected call of UpdatedCongestionState. -func (mr *MockConnectionTracerMockRecorder) UpdatedCongestionState(arg0 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) UpdatedCongestionState(arg0 any) *ConnectionTracerUpdatedCongestionStateCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedCongestionState", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedCongestionState), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedCongestionState", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedCongestionState), arg0) + return &ConnectionTracerUpdatedCongestionStateCall{Call: call} +} + +// ConnectionTracerUpdatedCongestionStateCall wrap *gomock.Call +type ConnectionTracerUpdatedCongestionStateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerUpdatedCongestionStateCall) Return() *ConnectionTracerUpdatedCongestionStateCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerUpdatedCongestionStateCall) Do(f func(logging.CongestionState)) *ConnectionTracerUpdatedCongestionStateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerUpdatedCongestionStateCall) DoAndReturn(f func(logging.CongestionState)) *ConnectionTracerUpdatedCongestionStateCall { + c.Call = c.Call.DoAndReturn(f) + return c } // UpdatedKey mocks base method. @@ -350,9 +950,33 @@ func (m *MockConnectionTracer) UpdatedKey(arg0 protocol.KeyPhase, arg1 bool) { } // UpdatedKey indicates an expected call of UpdatedKey. -func (mr *MockConnectionTracerMockRecorder) UpdatedKey(arg0, arg1 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) UpdatedKey(arg0, arg1 any) *ConnectionTracerUpdatedKeyCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedKey", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedKey), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedKey", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedKey), arg0, arg1) + return &ConnectionTracerUpdatedKeyCall{Call: call} +} + +// ConnectionTracerUpdatedKeyCall wrap *gomock.Call +type ConnectionTracerUpdatedKeyCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerUpdatedKeyCall) Return() *ConnectionTracerUpdatedKeyCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerUpdatedKeyCall) Do(f func(protocol.KeyPhase, bool)) *ConnectionTracerUpdatedKeyCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerUpdatedKeyCall) DoAndReturn(f func(protocol.KeyPhase, bool)) *ConnectionTracerUpdatedKeyCall { + c.Call = c.Call.DoAndReturn(f) + return c } // UpdatedKeyFromTLS mocks base method. @@ -362,9 +986,33 @@ func (m *MockConnectionTracer) UpdatedKeyFromTLS(arg0 protocol.EncryptionLevel, } // UpdatedKeyFromTLS indicates an expected call of UpdatedKeyFromTLS. -func (mr *MockConnectionTracerMockRecorder) UpdatedKeyFromTLS(arg0, arg1 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) UpdatedKeyFromTLS(arg0, arg1 any) *ConnectionTracerUpdatedKeyFromTLSCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedKeyFromTLS", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedKeyFromTLS), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedKeyFromTLS", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedKeyFromTLS), arg0, arg1) + return &ConnectionTracerUpdatedKeyFromTLSCall{Call: call} +} + +// ConnectionTracerUpdatedKeyFromTLSCall wrap *gomock.Call +type ConnectionTracerUpdatedKeyFromTLSCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerUpdatedKeyFromTLSCall) Return() *ConnectionTracerUpdatedKeyFromTLSCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerUpdatedKeyFromTLSCall) Do(f func(protocol.EncryptionLevel, protocol.Perspective)) *ConnectionTracerUpdatedKeyFromTLSCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerUpdatedKeyFromTLSCall) DoAndReturn(f func(protocol.EncryptionLevel, protocol.Perspective)) *ConnectionTracerUpdatedKeyFromTLSCall { + c.Call = c.Call.DoAndReturn(f) + return c } // UpdatedMetrics mocks base method. @@ -374,9 +1022,33 @@ 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 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) UpdatedMetrics(arg0, arg1, arg2, arg3 any) *ConnectionTracerUpdatedMetricsCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedMetrics", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedMetrics), arg0, arg1, arg2, arg3) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedMetrics", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedMetrics), arg0, arg1, arg2, arg3) + return &ConnectionTracerUpdatedMetricsCall{Call: call} +} + +// ConnectionTracerUpdatedMetricsCall wrap *gomock.Call +type ConnectionTracerUpdatedMetricsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerUpdatedMetricsCall) Return() *ConnectionTracerUpdatedMetricsCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerUpdatedMetricsCall) Do(f func(*utils.RTTStats, protocol.ByteCount, protocol.ByteCount, int)) *ConnectionTracerUpdatedMetricsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerUpdatedMetricsCall) DoAndReturn(f func(*utils.RTTStats, protocol.ByteCount, protocol.ByteCount, int)) *ConnectionTracerUpdatedMetricsCall { + c.Call = c.Call.DoAndReturn(f) + return c } // UpdatedPTOCount mocks base method. @@ -386,7 +1058,31 @@ func (m *MockConnectionTracer) UpdatedPTOCount(arg0 uint32) { } // UpdatedPTOCount indicates an expected call of UpdatedPTOCount. -func (mr *MockConnectionTracerMockRecorder) UpdatedPTOCount(arg0 any) *gomock.Call { +func (mr *MockConnectionTracerMockRecorder) UpdatedPTOCount(arg0 any) *ConnectionTracerUpdatedPTOCountCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedPTOCount", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedPTOCount), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedPTOCount", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedPTOCount), arg0) + return &ConnectionTracerUpdatedPTOCountCall{Call: call} +} + +// ConnectionTracerUpdatedPTOCountCall wrap *gomock.Call +type ConnectionTracerUpdatedPTOCountCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerUpdatedPTOCountCall) Return() *ConnectionTracerUpdatedPTOCountCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerUpdatedPTOCountCall) Do(f func(uint32)) *ConnectionTracerUpdatedPTOCountCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerUpdatedPTOCountCall) DoAndReturn(f func(uint32)) *ConnectionTracerUpdatedPTOCountCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/logging/internal/tracer.go b/internal/mocks/logging/internal/tracer.go index 14ce172c415..59edf187211 100644 --- a/internal/mocks/logging/internal/tracer.go +++ b/internal/mocks/logging/internal/tracer.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package internal -destination internal/tracer.go github.com/quic-go/quic-go/internal/mocks/logging Tracer +// mockgen -typed -build_flags=-tags=gomock -package internal -destination internal/tracer.go github.com/quic-go/quic-go/internal/mocks/logging Tracer // // Package internal is a generated GoMock package. package internal @@ -48,9 +48,33 @@ func (m *MockTracer) DroppedPacket(arg0 net.Addr, arg1 logging.PacketType, arg2 } // DroppedPacket indicates an expected call of DroppedPacket. -func (mr *MockTracerMockRecorder) DroppedPacket(arg0, arg1, arg2, arg3 any) *gomock.Call { +func (mr *MockTracerMockRecorder) DroppedPacket(arg0, arg1, arg2, arg3 any) *TracerDroppedPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockTracer)(nil).DroppedPacket), arg0, arg1, arg2, arg3) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockTracer)(nil).DroppedPacket), arg0, arg1, arg2, arg3) + return &TracerDroppedPacketCall{Call: call} +} + +// TracerDroppedPacketCall wrap *gomock.Call +type TracerDroppedPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TracerDroppedPacketCall) Return() *TracerDroppedPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TracerDroppedPacketCall) Do(f func(net.Addr, logging.PacketType, protocol.ByteCount, logging.PacketDropReason)) *TracerDroppedPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TracerDroppedPacketCall) DoAndReturn(f func(net.Addr, logging.PacketType, protocol.ByteCount, logging.PacketDropReason)) *TracerDroppedPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SentPacket mocks base method. @@ -60,9 +84,33 @@ func (m *MockTracer) SentPacket(arg0 net.Addr, arg1 *wire.Header, arg2 protocol. } // SentPacket indicates an expected call of SentPacket. -func (mr *MockTracerMockRecorder) SentPacket(arg0, arg1, arg2, arg3 any) *gomock.Call { +func (mr *MockTracerMockRecorder) SentPacket(arg0, arg1, arg2, arg3 any) *TracerSentPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockTracer)(nil).SentPacket), arg0, arg1, arg2, arg3) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockTracer)(nil).SentPacket), arg0, arg1, arg2, arg3) + return &TracerSentPacketCall{Call: call} +} + +// TracerSentPacketCall wrap *gomock.Call +type TracerSentPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TracerSentPacketCall) Return() *TracerSentPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TracerSentPacketCall) Do(f func(net.Addr, *wire.Header, protocol.ByteCount, []logging.Frame)) *TracerSentPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TracerSentPacketCall) DoAndReturn(f func(net.Addr, *wire.Header, protocol.ByteCount, []logging.Frame)) *TracerSentPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SentVersionNegotiationPacket mocks base method. @@ -72,7 +120,31 @@ 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 any) *gomock.Call { +func (mr *MockTracerMockRecorder) SentVersionNegotiationPacket(arg0, arg1, arg2, arg3 any) *TracerSentVersionNegotiationPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentVersionNegotiationPacket", reflect.TypeOf((*MockTracer)(nil).SentVersionNegotiationPacket), arg0, arg1, arg2, arg3) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentVersionNegotiationPacket", reflect.TypeOf((*MockTracer)(nil).SentVersionNegotiationPacket), arg0, arg1, arg2, arg3) + return &TracerSentVersionNegotiationPacketCall{Call: call} +} + +// TracerSentVersionNegotiationPacketCall wrap *gomock.Call +type TracerSentVersionNegotiationPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TracerSentVersionNegotiationPacketCall) Return() *TracerSentVersionNegotiationPacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TracerSentVersionNegotiationPacketCall) Do(f func(net.Addr, protocol.ArbitraryLenConnectionID, protocol.ArbitraryLenConnectionID, []protocol.VersionNumber)) *TracerSentVersionNegotiationPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TracerSentVersionNegotiationPacketCall) DoAndReturn(f func(net.Addr, protocol.ArbitraryLenConnectionID, protocol.ArbitraryLenConnectionID, []protocol.VersionNumber)) *TracerSentVersionNegotiationPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/logging/mockgen.go b/internal/mocks/logging/mockgen.go index 8bf08dc8ecc..b808ee6d1c0 100644 --- a/internal/mocks/logging/mockgen.go +++ b/internal/mocks/logging/mockgen.go @@ -9,14 +9,14 @@ import ( "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" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -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" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -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) diff --git a/internal/mocks/long_header_opener.go b/internal/mocks/long_header_opener.go index ad5d6b69f81..b1c608a0b2b 100644 --- a/internal/mocks/long_header_opener.go +++ b/internal/mocks/long_header_opener.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mocks -destination long_header_opener.go github.com/quic-go/quic-go/internal/handshake LongHeaderOpener +// mockgen -typed -build_flags=-tags=gomock -package mocks -destination long_header_opener.go github.com/quic-go/quic-go/internal/handshake LongHeaderOpener // // Package mocks is a generated GoMock package. package mocks @@ -47,9 +47,33 @@ func (m *MockLongHeaderOpener) DecodePacketNumber(arg0 protocol.PacketNumber, ar } // DecodePacketNumber indicates an expected call of DecodePacketNumber. -func (mr *MockLongHeaderOpenerMockRecorder) DecodePacketNumber(arg0, arg1 any) *gomock.Call { +func (mr *MockLongHeaderOpenerMockRecorder) DecodePacketNumber(arg0, arg1 any) *LongHeaderOpenerDecodePacketNumberCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodePacketNumber", reflect.TypeOf((*MockLongHeaderOpener)(nil).DecodePacketNumber), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodePacketNumber", reflect.TypeOf((*MockLongHeaderOpener)(nil).DecodePacketNumber), arg0, arg1) + return &LongHeaderOpenerDecodePacketNumberCall{Call: call} +} + +// LongHeaderOpenerDecodePacketNumberCall wrap *gomock.Call +type LongHeaderOpenerDecodePacketNumberCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *LongHeaderOpenerDecodePacketNumberCall) Return(arg0 protocol.PacketNumber) *LongHeaderOpenerDecodePacketNumberCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *LongHeaderOpenerDecodePacketNumberCall) Do(f func(protocol.PacketNumber, protocol.PacketNumberLen) protocol.PacketNumber) *LongHeaderOpenerDecodePacketNumberCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *LongHeaderOpenerDecodePacketNumberCall) DoAndReturn(f func(protocol.PacketNumber, protocol.PacketNumberLen) protocol.PacketNumber) *LongHeaderOpenerDecodePacketNumberCall { + c.Call = c.Call.DoAndReturn(f) + return c } // DecryptHeader mocks base method. @@ -59,9 +83,33 @@ func (m *MockLongHeaderOpener) DecryptHeader(arg0 []byte, arg1 *byte, arg2 []byt } // DecryptHeader indicates an expected call of DecryptHeader. -func (mr *MockLongHeaderOpenerMockRecorder) DecryptHeader(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockLongHeaderOpenerMockRecorder) DecryptHeader(arg0, arg1, arg2 any) *LongHeaderOpenerDecryptHeaderCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptHeader", reflect.TypeOf((*MockLongHeaderOpener)(nil).DecryptHeader), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptHeader", reflect.TypeOf((*MockLongHeaderOpener)(nil).DecryptHeader), arg0, arg1, arg2) + return &LongHeaderOpenerDecryptHeaderCall{Call: call} +} + +// LongHeaderOpenerDecryptHeaderCall wrap *gomock.Call +type LongHeaderOpenerDecryptHeaderCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *LongHeaderOpenerDecryptHeaderCall) Return() *LongHeaderOpenerDecryptHeaderCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *LongHeaderOpenerDecryptHeaderCall) Do(f func([]byte, *byte, []byte)) *LongHeaderOpenerDecryptHeaderCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *LongHeaderOpenerDecryptHeaderCall) DoAndReturn(f func([]byte, *byte, []byte)) *LongHeaderOpenerDecryptHeaderCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Open mocks base method. @@ -74,7 +122,31 @@ 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 any) *gomock.Call { +func (mr *MockLongHeaderOpenerMockRecorder) Open(arg0, arg1, arg2, arg3 any) *LongHeaderOpenerOpenCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockLongHeaderOpener)(nil).Open), arg0, arg1, arg2, arg3) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockLongHeaderOpener)(nil).Open), arg0, arg1, arg2, arg3) + return &LongHeaderOpenerOpenCall{Call: call} +} + +// LongHeaderOpenerOpenCall wrap *gomock.Call +type LongHeaderOpenerOpenCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *LongHeaderOpenerOpenCall) Return(arg0 []byte, arg1 error) *LongHeaderOpenerOpenCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *LongHeaderOpenerOpenCall) Do(f func([]byte, []byte, protocol.PacketNumber, []byte) ([]byte, error)) *LongHeaderOpenerOpenCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *LongHeaderOpenerOpenCall) DoAndReturn(f func([]byte, []byte, protocol.PacketNumber, []byte) ([]byte, error)) *LongHeaderOpenerOpenCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/mockgen.go b/internal/mocks/mockgen.go index 23bcda009f5..b736631d58d 100644 --- a/internal/mocks/mockgen.go +++ b/internal/mocks/mockgen.go @@ -2,18 +2,18 @@ package mocks -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package mockquic -destination quic/stream.go github.com/quic-go/quic-go 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/quic-go/quic-go 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/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/internal/handshake CryptoSetup && sed -E 's~github.com/quic-go/qtls[[:alnum:]_-]*~github.com/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/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/quic-go/quic-go/internal/ackhandler ReceivedPacketHandler" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mockquic -destination quic/stream.go github.com/quic-go/quic-go Stream" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mockquic -destination quic/early_conn_tmp.go github.com/quic-go/quic-go 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 -typed -build_flags=\"-tags=gomock\" -package mocks -destination short_header_sealer.go github.com/quic-go/quic-go/internal/handshake ShortHeaderSealer" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mocks -destination short_header_opener.go github.com/quic-go/quic-go/internal/handshake ShortHeaderOpener" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mocks -destination long_header_opener.go github.com/quic-go/quic-go/internal/handshake LongHeaderOpener" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mocks -destination crypto_setup_tmp.go github.com/quic-go/quic-go/internal/handshake CryptoSetup && sed -E 's~github.com/quic-go/qtls[[:alnum:]_-]*~github.com/quic-go/quic-go/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 -typed -build_flags=\"-tags=gomock\" -package mocks -destination stream_flow_controller.go github.com/quic-go/quic-go/internal/flowcontrol StreamFlowController" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mocks -destination congestion.go github.com/quic-go/quic-go/internal/congestion SendAlgorithmWithDebugInfos" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mocks -destination connection_flow_controller.go github.com/quic-go/quic-go/internal/flowcontrol ConnectionFlowController" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mockackhandler -destination ackhandler/sent_packet_handler.go github.com/quic-go/quic-go/internal/ackhandler SentPacketHandler" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mockackhandler -destination ackhandler/received_packet_handler.go github.com/quic-go/quic-go/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 -build_flags=\"-tags=gomock\" -package mocktls -destination tls/client_session_cache.go crypto/tls ClientSessionCache" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mocktls -destination tls/client_session_cache.go crypto/tls ClientSessionCache" diff --git a/internal/mocks/quic/early_conn.go b/internal/mocks/quic/early_conn.go index 205ed7f2281..223def6c5e9 100644 --- a/internal/mocks/quic/early_conn.go +++ b/internal/mocks/quic/early_conn.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mockquic -destination quic/early_conn_tmp.go github.com/quic-go/quic-go EarlyConnection +// mockgen -typed -build_flags=-tags=gomock -package mockquic -destination quic/early_conn_tmp.go github.com/quic-go/quic-go EarlyConnection // // Package mockquic is a generated GoMock package. package mockquic @@ -51,9 +51,33 @@ func (m *MockEarlyConnection) AcceptStream(arg0 context.Context) (quic.Stream, e } // AcceptStream indicates an expected call of AcceptStream. -func (mr *MockEarlyConnectionMockRecorder) AcceptStream(arg0 any) *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) AcceptStream(arg0 any) *EarlyConnectionAcceptStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptStream", reflect.TypeOf((*MockEarlyConnection)(nil).AcceptStream), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptStream", reflect.TypeOf((*MockEarlyConnection)(nil).AcceptStream), arg0) + return &EarlyConnectionAcceptStreamCall{Call: call} +} + +// EarlyConnectionAcceptStreamCall wrap *gomock.Call +type EarlyConnectionAcceptStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionAcceptStreamCall) Return(arg0 quic.Stream, arg1 error) *EarlyConnectionAcceptStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionAcceptStreamCall) Do(f func(context.Context) (quic.Stream, error)) *EarlyConnectionAcceptStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionAcceptStreamCall) DoAndReturn(f func(context.Context) (quic.Stream, error)) *EarlyConnectionAcceptStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // AcceptUniStream mocks base method. @@ -66,9 +90,33 @@ func (m *MockEarlyConnection) AcceptUniStream(arg0 context.Context) (quic.Receiv } // AcceptUniStream indicates an expected call of AcceptUniStream. -func (mr *MockEarlyConnectionMockRecorder) AcceptUniStream(arg0 any) *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) AcceptUniStream(arg0 any) *EarlyConnectionAcceptUniStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptUniStream", reflect.TypeOf((*MockEarlyConnection)(nil).AcceptUniStream), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptUniStream", reflect.TypeOf((*MockEarlyConnection)(nil).AcceptUniStream), arg0) + return &EarlyConnectionAcceptUniStreamCall{Call: call} +} + +// EarlyConnectionAcceptUniStreamCall wrap *gomock.Call +type EarlyConnectionAcceptUniStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionAcceptUniStreamCall) Return(arg0 quic.ReceiveStream, arg1 error) *EarlyConnectionAcceptUniStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionAcceptUniStreamCall) Do(f func(context.Context) (quic.ReceiveStream, error)) *EarlyConnectionAcceptUniStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionAcceptUniStreamCall) DoAndReturn(f func(context.Context) (quic.ReceiveStream, error)) *EarlyConnectionAcceptUniStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // CloseWithError mocks base method. @@ -80,9 +128,33 @@ func (m *MockEarlyConnection) CloseWithError(arg0 qerr.ApplicationErrorCode, arg } // CloseWithError indicates an expected call of CloseWithError. -func (mr *MockEarlyConnectionMockRecorder) CloseWithError(arg0, arg1 any) *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) CloseWithError(arg0, arg1 any) *EarlyConnectionCloseWithErrorCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseWithError", reflect.TypeOf((*MockEarlyConnection)(nil).CloseWithError), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseWithError", reflect.TypeOf((*MockEarlyConnection)(nil).CloseWithError), arg0, arg1) + return &EarlyConnectionCloseWithErrorCall{Call: call} +} + +// EarlyConnectionCloseWithErrorCall wrap *gomock.Call +type EarlyConnectionCloseWithErrorCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionCloseWithErrorCall) Return(arg0 error) *EarlyConnectionCloseWithErrorCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionCloseWithErrorCall) Do(f func(qerr.ApplicationErrorCode, string) error) *EarlyConnectionCloseWithErrorCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionCloseWithErrorCall) DoAndReturn(f func(qerr.ApplicationErrorCode, string) error) *EarlyConnectionCloseWithErrorCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ConnectionState mocks base method. @@ -94,9 +166,33 @@ func (m *MockEarlyConnection) ConnectionState() quic.ConnectionState { } // ConnectionState indicates an expected call of ConnectionState. -func (mr *MockEarlyConnectionMockRecorder) ConnectionState() *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) ConnectionState() *EarlyConnectionConnectionStateCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectionState", reflect.TypeOf((*MockEarlyConnection)(nil).ConnectionState)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectionState", reflect.TypeOf((*MockEarlyConnection)(nil).ConnectionState)) + return &EarlyConnectionConnectionStateCall{Call: call} +} + +// EarlyConnectionConnectionStateCall wrap *gomock.Call +type EarlyConnectionConnectionStateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionConnectionStateCall) Return(arg0 quic.ConnectionState) *EarlyConnectionConnectionStateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionConnectionStateCall) Do(f func() quic.ConnectionState) *EarlyConnectionConnectionStateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionConnectionStateCall) DoAndReturn(f func() quic.ConnectionState) *EarlyConnectionConnectionStateCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Context mocks base method. @@ -108,9 +204,33 @@ func (m *MockEarlyConnection) Context() context.Context { } // Context indicates an expected call of Context. -func (mr *MockEarlyConnectionMockRecorder) Context() *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) Context() *EarlyConnectionContextCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockEarlyConnection)(nil).Context)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockEarlyConnection)(nil).Context)) + return &EarlyConnectionContextCall{Call: call} +} + +// EarlyConnectionContextCall wrap *gomock.Call +type EarlyConnectionContextCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionContextCall) Return(arg0 context.Context) *EarlyConnectionContextCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionContextCall) Do(f func() context.Context) *EarlyConnectionContextCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionContextCall) DoAndReturn(f func() context.Context) *EarlyConnectionContextCall { + c.Call = c.Call.DoAndReturn(f) + return c } // HandshakeComplete mocks base method. @@ -122,9 +242,33 @@ func (m *MockEarlyConnection) HandshakeComplete() <-chan struct{} { } // HandshakeComplete indicates an expected call of HandshakeComplete. -func (mr *MockEarlyConnectionMockRecorder) HandshakeComplete() *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) HandshakeComplete() *EarlyConnectionHandshakeCompleteCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandshakeComplete", reflect.TypeOf((*MockEarlyConnection)(nil).HandshakeComplete)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandshakeComplete", reflect.TypeOf((*MockEarlyConnection)(nil).HandshakeComplete)) + return &EarlyConnectionHandshakeCompleteCall{Call: call} +} + +// EarlyConnectionHandshakeCompleteCall wrap *gomock.Call +type EarlyConnectionHandshakeCompleteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionHandshakeCompleteCall) Return(arg0 <-chan struct{}) *EarlyConnectionHandshakeCompleteCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionHandshakeCompleteCall) Do(f func() <-chan struct{}) *EarlyConnectionHandshakeCompleteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionHandshakeCompleteCall) DoAndReturn(f func() <-chan struct{}) *EarlyConnectionHandshakeCompleteCall { + c.Call = c.Call.DoAndReturn(f) + return c } // LocalAddr mocks base method. @@ -136,9 +280,33 @@ func (m *MockEarlyConnection) LocalAddr() net.Addr { } // LocalAddr indicates an expected call of LocalAddr. -func (mr *MockEarlyConnectionMockRecorder) LocalAddr() *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) LocalAddr() *EarlyConnectionLocalAddrCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockEarlyConnection)(nil).LocalAddr)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockEarlyConnection)(nil).LocalAddr)) + return &EarlyConnectionLocalAddrCall{Call: call} +} + +// EarlyConnectionLocalAddrCall wrap *gomock.Call +type EarlyConnectionLocalAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionLocalAddrCall) Return(arg0 net.Addr) *EarlyConnectionLocalAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionLocalAddrCall) Do(f func() net.Addr) *EarlyConnectionLocalAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionLocalAddrCall) DoAndReturn(f func() net.Addr) *EarlyConnectionLocalAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c } // NextConnection mocks base method. @@ -150,9 +318,33 @@ func (m *MockEarlyConnection) NextConnection() quic.Connection { } // NextConnection indicates an expected call of NextConnection. -func (mr *MockEarlyConnectionMockRecorder) NextConnection() *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) NextConnection() *EarlyConnectionNextConnectionCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NextConnection", reflect.TypeOf((*MockEarlyConnection)(nil).NextConnection)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NextConnection", reflect.TypeOf((*MockEarlyConnection)(nil).NextConnection)) + return &EarlyConnectionNextConnectionCall{Call: call} +} + +// EarlyConnectionNextConnectionCall wrap *gomock.Call +type EarlyConnectionNextConnectionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionNextConnectionCall) Return(arg0 quic.Connection) *EarlyConnectionNextConnectionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionNextConnectionCall) Do(f func() quic.Connection) *EarlyConnectionNextConnectionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionNextConnectionCall) DoAndReturn(f func() quic.Connection) *EarlyConnectionNextConnectionCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenStream mocks base method. @@ -165,9 +357,33 @@ func (m *MockEarlyConnection) OpenStream() (quic.Stream, error) { } // OpenStream indicates an expected call of OpenStream. -func (mr *MockEarlyConnectionMockRecorder) OpenStream() *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) OpenStream() *EarlyConnectionOpenStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStream", reflect.TypeOf((*MockEarlyConnection)(nil).OpenStream)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStream", reflect.TypeOf((*MockEarlyConnection)(nil).OpenStream)) + return &EarlyConnectionOpenStreamCall{Call: call} +} + +// EarlyConnectionOpenStreamCall wrap *gomock.Call +type EarlyConnectionOpenStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionOpenStreamCall) Return(arg0 quic.Stream, arg1 error) *EarlyConnectionOpenStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionOpenStreamCall) Do(f func() (quic.Stream, error)) *EarlyConnectionOpenStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionOpenStreamCall) DoAndReturn(f func() (quic.Stream, error)) *EarlyConnectionOpenStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenStreamSync mocks base method. @@ -180,9 +396,33 @@ func (m *MockEarlyConnection) OpenStreamSync(arg0 context.Context) (quic.Stream, } // OpenStreamSync indicates an expected call of OpenStreamSync. -func (mr *MockEarlyConnectionMockRecorder) OpenStreamSync(arg0 any) *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) OpenStreamSync(arg0 any) *EarlyConnectionOpenStreamSyncCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStreamSync", reflect.TypeOf((*MockEarlyConnection)(nil).OpenStreamSync), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStreamSync", reflect.TypeOf((*MockEarlyConnection)(nil).OpenStreamSync), arg0) + return &EarlyConnectionOpenStreamSyncCall{Call: call} +} + +// EarlyConnectionOpenStreamSyncCall wrap *gomock.Call +type EarlyConnectionOpenStreamSyncCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionOpenStreamSyncCall) Return(arg0 quic.Stream, arg1 error) *EarlyConnectionOpenStreamSyncCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionOpenStreamSyncCall) Do(f func(context.Context) (quic.Stream, error)) *EarlyConnectionOpenStreamSyncCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionOpenStreamSyncCall) DoAndReturn(f func(context.Context) (quic.Stream, error)) *EarlyConnectionOpenStreamSyncCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenUniStream mocks base method. @@ -195,9 +435,33 @@ func (m *MockEarlyConnection) OpenUniStream() (quic.SendStream, error) { } // OpenUniStream indicates an expected call of OpenUniStream. -func (mr *MockEarlyConnectionMockRecorder) OpenUniStream() *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) OpenUniStream() *EarlyConnectionOpenUniStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStream", reflect.TypeOf((*MockEarlyConnection)(nil).OpenUniStream)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStream", reflect.TypeOf((*MockEarlyConnection)(nil).OpenUniStream)) + return &EarlyConnectionOpenUniStreamCall{Call: call} +} + +// EarlyConnectionOpenUniStreamCall wrap *gomock.Call +type EarlyConnectionOpenUniStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionOpenUniStreamCall) Return(arg0 quic.SendStream, arg1 error) *EarlyConnectionOpenUniStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionOpenUniStreamCall) Do(f func() (quic.SendStream, error)) *EarlyConnectionOpenUniStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionOpenUniStreamCall) DoAndReturn(f func() (quic.SendStream, error)) *EarlyConnectionOpenUniStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenUniStreamSync mocks base method. @@ -210,9 +474,33 @@ func (m *MockEarlyConnection) OpenUniStreamSync(arg0 context.Context) (quic.Send } // OpenUniStreamSync indicates an expected call of OpenUniStreamSync. -func (mr *MockEarlyConnectionMockRecorder) OpenUniStreamSync(arg0 any) *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) OpenUniStreamSync(arg0 any) *EarlyConnectionOpenUniStreamSyncCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStreamSync", reflect.TypeOf((*MockEarlyConnection)(nil).OpenUniStreamSync), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStreamSync", reflect.TypeOf((*MockEarlyConnection)(nil).OpenUniStreamSync), arg0) + return &EarlyConnectionOpenUniStreamSyncCall{Call: call} +} + +// EarlyConnectionOpenUniStreamSyncCall wrap *gomock.Call +type EarlyConnectionOpenUniStreamSyncCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionOpenUniStreamSyncCall) Return(arg0 quic.SendStream, arg1 error) *EarlyConnectionOpenUniStreamSyncCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionOpenUniStreamSyncCall) Do(f func(context.Context) (quic.SendStream, error)) *EarlyConnectionOpenUniStreamSyncCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionOpenUniStreamSyncCall) DoAndReturn(f func(context.Context) (quic.SendStream, error)) *EarlyConnectionOpenUniStreamSyncCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReceiveMessage mocks base method. @@ -225,9 +513,33 @@ func (m *MockEarlyConnection) ReceiveMessage(arg0 context.Context) ([]byte, erro } // ReceiveMessage indicates an expected call of ReceiveMessage. -func (mr *MockEarlyConnectionMockRecorder) ReceiveMessage(arg0 any) *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) ReceiveMessage(arg0 any) *EarlyConnectionReceiveMessageCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveMessage", reflect.TypeOf((*MockEarlyConnection)(nil).ReceiveMessage), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveMessage", reflect.TypeOf((*MockEarlyConnection)(nil).ReceiveMessage), arg0) + return &EarlyConnectionReceiveMessageCall{Call: call} +} + +// EarlyConnectionReceiveMessageCall wrap *gomock.Call +type EarlyConnectionReceiveMessageCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionReceiveMessageCall) Return(arg0 []byte, arg1 error) *EarlyConnectionReceiveMessageCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionReceiveMessageCall) Do(f func(context.Context) ([]byte, error)) *EarlyConnectionReceiveMessageCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionReceiveMessageCall) DoAndReturn(f func(context.Context) ([]byte, error)) *EarlyConnectionReceiveMessageCall { + c.Call = c.Call.DoAndReturn(f) + return c } // RemoteAddr mocks base method. @@ -239,9 +551,33 @@ func (m *MockEarlyConnection) RemoteAddr() net.Addr { } // RemoteAddr indicates an expected call of RemoteAddr. -func (mr *MockEarlyConnectionMockRecorder) RemoteAddr() *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) RemoteAddr() *EarlyConnectionRemoteAddrCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockEarlyConnection)(nil).RemoteAddr)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockEarlyConnection)(nil).RemoteAddr)) + return &EarlyConnectionRemoteAddrCall{Call: call} +} + +// EarlyConnectionRemoteAddrCall wrap *gomock.Call +type EarlyConnectionRemoteAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionRemoteAddrCall) Return(arg0 net.Addr) *EarlyConnectionRemoteAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionRemoteAddrCall) Do(f func() net.Addr) *EarlyConnectionRemoteAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionRemoteAddrCall) DoAndReturn(f func() net.Addr) *EarlyConnectionRemoteAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SendMessage mocks base method. @@ -253,7 +589,31 @@ func (m *MockEarlyConnection) SendMessage(arg0 []byte) error { } // SendMessage indicates an expected call of SendMessage. -func (mr *MockEarlyConnectionMockRecorder) SendMessage(arg0 any) *gomock.Call { +func (mr *MockEarlyConnectionMockRecorder) SendMessage(arg0 any) *EarlyConnectionSendMessageCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockEarlyConnection)(nil).SendMessage), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockEarlyConnection)(nil).SendMessage), arg0) + return &EarlyConnectionSendMessageCall{Call: call} +} + +// EarlyConnectionSendMessageCall wrap *gomock.Call +type EarlyConnectionSendMessageCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *EarlyConnectionSendMessageCall) Return(arg0 error) *EarlyConnectionSendMessageCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *EarlyConnectionSendMessageCall) Do(f func([]byte) error) *EarlyConnectionSendMessageCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *EarlyConnectionSendMessageCall) DoAndReturn(f func([]byte) error) *EarlyConnectionSendMessageCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/quic/stream.go b/internal/mocks/quic/stream.go index 2043fdfb646..2999b269533 100644 --- a/internal/mocks/quic/stream.go +++ b/internal/mocks/quic/stream.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mockquic -destination quic/stream.go github.com/quic-go/quic-go Stream +// mockgen -typed -build_flags=-tags=gomock -package mockquic -destination quic/stream.go github.com/quic-go/quic-go Stream // // Package mockquic is a generated GoMock package. package mockquic @@ -48,9 +48,33 @@ func (m *MockStream) CancelRead(arg0 qerr.StreamErrorCode) { } // CancelRead indicates an expected call of CancelRead. -func (mr *MockStreamMockRecorder) CancelRead(arg0 any) *gomock.Call { +func (mr *MockStreamMockRecorder) CancelRead(arg0 any) *StreamCancelReadCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRead", reflect.TypeOf((*MockStream)(nil).CancelRead), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRead", reflect.TypeOf((*MockStream)(nil).CancelRead), arg0) + return &StreamCancelReadCall{Call: call} +} + +// StreamCancelReadCall wrap *gomock.Call +type StreamCancelReadCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamCancelReadCall) Return() *StreamCancelReadCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamCancelReadCall) Do(f func(qerr.StreamErrorCode)) *StreamCancelReadCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamCancelReadCall) DoAndReturn(f func(qerr.StreamErrorCode)) *StreamCancelReadCall { + c.Call = c.Call.DoAndReturn(f) + return c } // CancelWrite mocks base method. @@ -60,9 +84,33 @@ func (m *MockStream) CancelWrite(arg0 qerr.StreamErrorCode) { } // CancelWrite indicates an expected call of CancelWrite. -func (mr *MockStreamMockRecorder) CancelWrite(arg0 any) *gomock.Call { +func (mr *MockStreamMockRecorder) CancelWrite(arg0 any) *StreamCancelWriteCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelWrite", reflect.TypeOf((*MockStream)(nil).CancelWrite), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelWrite", reflect.TypeOf((*MockStream)(nil).CancelWrite), arg0) + return &StreamCancelWriteCall{Call: call} +} + +// StreamCancelWriteCall wrap *gomock.Call +type StreamCancelWriteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamCancelWriteCall) Return() *StreamCancelWriteCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamCancelWriteCall) Do(f func(qerr.StreamErrorCode)) *StreamCancelWriteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamCancelWriteCall) DoAndReturn(f func(qerr.StreamErrorCode)) *StreamCancelWriteCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Close mocks base method. @@ -74,9 +122,33 @@ func (m *MockStream) Close() error { } // Close indicates an expected call of Close. -func (mr *MockStreamMockRecorder) Close() *gomock.Call { +func (mr *MockStreamMockRecorder) Close() *StreamCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockStream)(nil).Close)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockStream)(nil).Close)) + return &StreamCloseCall{Call: call} +} + +// StreamCloseCall wrap *gomock.Call +type StreamCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamCloseCall) Return(arg0 error) *StreamCloseCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamCloseCall) Do(f func() error) *StreamCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamCloseCall) DoAndReturn(f func() error) *StreamCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Context mocks base method. @@ -88,9 +160,33 @@ func (m *MockStream) Context() context.Context { } // Context indicates an expected call of Context. -func (mr *MockStreamMockRecorder) Context() *gomock.Call { +func (mr *MockStreamMockRecorder) Context() *StreamContextCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockStream)(nil).Context)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockStream)(nil).Context)) + return &StreamContextCall{Call: call} +} + +// StreamContextCall wrap *gomock.Call +type StreamContextCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamContextCall) Return(arg0 context.Context) *StreamContextCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamContextCall) Do(f func() context.Context) *StreamContextCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamContextCall) DoAndReturn(f func() context.Context) *StreamContextCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Read mocks base method. @@ -103,9 +199,33 @@ func (m *MockStream) Read(arg0 []byte) (int, error) { } // Read indicates an expected call of Read. -func (mr *MockStreamMockRecorder) Read(arg0 any) *gomock.Call { +func (mr *MockStreamMockRecorder) Read(arg0 any) *StreamReadCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStream)(nil).Read), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStream)(nil).Read), arg0) + return &StreamReadCall{Call: call} +} + +// StreamReadCall wrap *gomock.Call +type StreamReadCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamReadCall) Return(arg0 int, arg1 error) *StreamReadCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamReadCall) Do(f func([]byte) (int, error)) *StreamReadCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamReadCall) DoAndReturn(f func([]byte) (int, error)) *StreamReadCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetDeadline mocks base method. @@ -117,9 +237,33 @@ func (m *MockStream) SetDeadline(arg0 time.Time) error { } // SetDeadline indicates an expected call of SetDeadline. -func (mr *MockStreamMockRecorder) SetDeadline(arg0 any) *gomock.Call { +func (mr *MockStreamMockRecorder) SetDeadline(arg0 any) *StreamSetDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStream)(nil).SetDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStream)(nil).SetDeadline), arg0) + return &StreamSetDeadlineCall{Call: call} +} + +// StreamSetDeadlineCall wrap *gomock.Call +type StreamSetDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamSetDeadlineCall) Return(arg0 error) *StreamSetDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamSetDeadlineCall) Do(f func(time.Time) error) *StreamSetDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamSetDeadlineCall) DoAndReturn(f func(time.Time) error) *StreamSetDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetReadDeadline mocks base method. @@ -131,9 +275,33 @@ func (m *MockStream) SetReadDeadline(arg0 time.Time) error { } // SetReadDeadline indicates an expected call of SetReadDeadline. -func (mr *MockStreamMockRecorder) SetReadDeadline(arg0 any) *gomock.Call { +func (mr *MockStreamMockRecorder) SetReadDeadline(arg0 any) *StreamSetReadDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStream)(nil).SetReadDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStream)(nil).SetReadDeadline), arg0) + return &StreamSetReadDeadlineCall{Call: call} +} + +// StreamSetReadDeadlineCall wrap *gomock.Call +type StreamSetReadDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamSetReadDeadlineCall) Return(arg0 error) *StreamSetReadDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamSetReadDeadlineCall) Do(f func(time.Time) error) *StreamSetReadDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamSetReadDeadlineCall) DoAndReturn(f func(time.Time) error) *StreamSetReadDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetWriteDeadline mocks base method. @@ -145,9 +313,33 @@ func (m *MockStream) SetWriteDeadline(arg0 time.Time) error { } // SetWriteDeadline indicates an expected call of SetWriteDeadline. -func (mr *MockStreamMockRecorder) SetWriteDeadline(arg0 any) *gomock.Call { +func (mr *MockStreamMockRecorder) SetWriteDeadline(arg0 any) *StreamSetWriteDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStream)(nil).SetWriteDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStream)(nil).SetWriteDeadline), arg0) + return &StreamSetWriteDeadlineCall{Call: call} +} + +// StreamSetWriteDeadlineCall wrap *gomock.Call +type StreamSetWriteDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamSetWriteDeadlineCall) Return(arg0 error) *StreamSetWriteDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamSetWriteDeadlineCall) Do(f func(time.Time) error) *StreamSetWriteDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamSetWriteDeadlineCall) DoAndReturn(f func(time.Time) error) *StreamSetWriteDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // StreamID mocks base method. @@ -159,9 +351,33 @@ func (m *MockStream) StreamID() protocol.StreamID { } // StreamID indicates an expected call of StreamID. -func (mr *MockStreamMockRecorder) StreamID() *gomock.Call { +func (mr *MockStreamMockRecorder) StreamID() *StreamStreamIDCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamID", reflect.TypeOf((*MockStream)(nil).StreamID)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamID", reflect.TypeOf((*MockStream)(nil).StreamID)) + return &StreamStreamIDCall{Call: call} +} + +// StreamStreamIDCall wrap *gomock.Call +type StreamStreamIDCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamStreamIDCall) Return(arg0 protocol.StreamID) *StreamStreamIDCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamStreamIDCall) Do(f func() protocol.StreamID) *StreamStreamIDCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamStreamIDCall) DoAndReturn(f func() protocol.StreamID) *StreamStreamIDCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Write mocks base method. @@ -174,7 +390,31 @@ func (m *MockStream) Write(arg0 []byte) (int, error) { } // Write indicates an expected call of Write. -func (mr *MockStreamMockRecorder) Write(arg0 any) *gomock.Call { +func (mr *MockStreamMockRecorder) Write(arg0 any) *StreamWriteCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStream)(nil).Write), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStream)(nil).Write), arg0) + return &StreamWriteCall{Call: call} +} + +// StreamWriteCall wrap *gomock.Call +type StreamWriteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamWriteCall) Return(arg0 int, arg1 error) *StreamWriteCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamWriteCall) Do(f func([]byte) (int, error)) *StreamWriteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamWriteCall) DoAndReturn(f func([]byte) (int, error)) *StreamWriteCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/short_header_opener.go b/internal/mocks/short_header_opener.go index 4b9f77f880c..859565a2c46 100644 --- a/internal/mocks/short_header_opener.go +++ b/internal/mocks/short_header_opener.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mocks -destination short_header_opener.go github.com/quic-go/quic-go/internal/handshake ShortHeaderOpener +// mockgen -typed -build_flags=-tags=gomock -package mocks -destination short_header_opener.go github.com/quic-go/quic-go/internal/handshake ShortHeaderOpener // // Package mocks is a generated GoMock package. package mocks @@ -48,9 +48,33 @@ func (m *MockShortHeaderOpener) DecodePacketNumber(arg0 protocol.PacketNumber, a } // DecodePacketNumber indicates an expected call of DecodePacketNumber. -func (mr *MockShortHeaderOpenerMockRecorder) DecodePacketNumber(arg0, arg1 any) *gomock.Call { +func (mr *MockShortHeaderOpenerMockRecorder) DecodePacketNumber(arg0, arg1 any) *ShortHeaderOpenerDecodePacketNumberCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodePacketNumber", reflect.TypeOf((*MockShortHeaderOpener)(nil).DecodePacketNumber), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodePacketNumber", reflect.TypeOf((*MockShortHeaderOpener)(nil).DecodePacketNumber), arg0, arg1) + return &ShortHeaderOpenerDecodePacketNumberCall{Call: call} +} + +// ShortHeaderOpenerDecodePacketNumberCall wrap *gomock.Call +type ShortHeaderOpenerDecodePacketNumberCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ShortHeaderOpenerDecodePacketNumberCall) Return(arg0 protocol.PacketNumber) *ShortHeaderOpenerDecodePacketNumberCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ShortHeaderOpenerDecodePacketNumberCall) Do(f func(protocol.PacketNumber, protocol.PacketNumberLen) protocol.PacketNumber) *ShortHeaderOpenerDecodePacketNumberCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ShortHeaderOpenerDecodePacketNumberCall) DoAndReturn(f func(protocol.PacketNumber, protocol.PacketNumberLen) protocol.PacketNumber) *ShortHeaderOpenerDecodePacketNumberCall { + c.Call = c.Call.DoAndReturn(f) + return c } // DecryptHeader mocks base method. @@ -60,9 +84,33 @@ func (m *MockShortHeaderOpener) DecryptHeader(arg0 []byte, arg1 *byte, arg2 []by } // DecryptHeader indicates an expected call of DecryptHeader. -func (mr *MockShortHeaderOpenerMockRecorder) DecryptHeader(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockShortHeaderOpenerMockRecorder) DecryptHeader(arg0, arg1, arg2 any) *ShortHeaderOpenerDecryptHeaderCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptHeader", reflect.TypeOf((*MockShortHeaderOpener)(nil).DecryptHeader), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptHeader", reflect.TypeOf((*MockShortHeaderOpener)(nil).DecryptHeader), arg0, arg1, arg2) + return &ShortHeaderOpenerDecryptHeaderCall{Call: call} +} + +// ShortHeaderOpenerDecryptHeaderCall wrap *gomock.Call +type ShortHeaderOpenerDecryptHeaderCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ShortHeaderOpenerDecryptHeaderCall) Return() *ShortHeaderOpenerDecryptHeaderCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ShortHeaderOpenerDecryptHeaderCall) Do(f func([]byte, *byte, []byte)) *ShortHeaderOpenerDecryptHeaderCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ShortHeaderOpenerDecryptHeaderCall) DoAndReturn(f func([]byte, *byte, []byte)) *ShortHeaderOpenerDecryptHeaderCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Open mocks base method. @@ -75,7 +123,31 @@ 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 any) *gomock.Call { +func (mr *MockShortHeaderOpenerMockRecorder) Open(arg0, arg1, arg2, arg3, arg4, arg5 any) *ShortHeaderOpenerOpenCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockShortHeaderOpener)(nil).Open), arg0, arg1, arg2, arg3, arg4, arg5) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockShortHeaderOpener)(nil).Open), arg0, arg1, arg2, arg3, arg4, arg5) + return &ShortHeaderOpenerOpenCall{Call: call} +} + +// ShortHeaderOpenerOpenCall wrap *gomock.Call +type ShortHeaderOpenerOpenCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ShortHeaderOpenerOpenCall) Return(arg0 []byte, arg1 error) *ShortHeaderOpenerOpenCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ShortHeaderOpenerOpenCall) Do(f func([]byte, []byte, time.Time, protocol.PacketNumber, protocol.KeyPhaseBit, []byte) ([]byte, error)) *ShortHeaderOpenerOpenCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ShortHeaderOpenerOpenCall) DoAndReturn(f func([]byte, []byte, time.Time, protocol.PacketNumber, protocol.KeyPhaseBit, []byte) ([]byte, error)) *ShortHeaderOpenerOpenCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/short_header_sealer.go b/internal/mocks/short_header_sealer.go index aabe6867abb..bd3333be9d5 100644 --- a/internal/mocks/short_header_sealer.go +++ b/internal/mocks/short_header_sealer.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mocks -destination short_header_sealer.go github.com/quic-go/quic-go/internal/handshake ShortHeaderSealer +// mockgen -typed -build_flags=-tags=gomock -package mocks -destination short_header_sealer.go github.com/quic-go/quic-go/internal/handshake ShortHeaderSealer // // Package mocks is a generated GoMock package. package mocks @@ -45,9 +45,33 @@ func (m *MockShortHeaderSealer) EncryptHeader(arg0 []byte, arg1 *byte, arg2 []by } // EncryptHeader indicates an expected call of EncryptHeader. -func (mr *MockShortHeaderSealerMockRecorder) EncryptHeader(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockShortHeaderSealerMockRecorder) EncryptHeader(arg0, arg1, arg2 any) *ShortHeaderSealerEncryptHeaderCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EncryptHeader", reflect.TypeOf((*MockShortHeaderSealer)(nil).EncryptHeader), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EncryptHeader", reflect.TypeOf((*MockShortHeaderSealer)(nil).EncryptHeader), arg0, arg1, arg2) + return &ShortHeaderSealerEncryptHeaderCall{Call: call} +} + +// ShortHeaderSealerEncryptHeaderCall wrap *gomock.Call +type ShortHeaderSealerEncryptHeaderCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ShortHeaderSealerEncryptHeaderCall) Return() *ShortHeaderSealerEncryptHeaderCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ShortHeaderSealerEncryptHeaderCall) Do(f func([]byte, *byte, []byte)) *ShortHeaderSealerEncryptHeaderCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ShortHeaderSealerEncryptHeaderCall) DoAndReturn(f func([]byte, *byte, []byte)) *ShortHeaderSealerEncryptHeaderCall { + c.Call = c.Call.DoAndReturn(f) + return c } // KeyPhase mocks base method. @@ -59,9 +83,33 @@ func (m *MockShortHeaderSealer) KeyPhase() protocol.KeyPhaseBit { } // KeyPhase indicates an expected call of KeyPhase. -func (mr *MockShortHeaderSealerMockRecorder) KeyPhase() *gomock.Call { +func (mr *MockShortHeaderSealerMockRecorder) KeyPhase() *ShortHeaderSealerKeyPhaseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "KeyPhase", reflect.TypeOf((*MockShortHeaderSealer)(nil).KeyPhase)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "KeyPhase", reflect.TypeOf((*MockShortHeaderSealer)(nil).KeyPhase)) + return &ShortHeaderSealerKeyPhaseCall{Call: call} +} + +// ShortHeaderSealerKeyPhaseCall wrap *gomock.Call +type ShortHeaderSealerKeyPhaseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ShortHeaderSealerKeyPhaseCall) Return(arg0 protocol.KeyPhaseBit) *ShortHeaderSealerKeyPhaseCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ShortHeaderSealerKeyPhaseCall) Do(f func() protocol.KeyPhaseBit) *ShortHeaderSealerKeyPhaseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ShortHeaderSealerKeyPhaseCall) DoAndReturn(f func() protocol.KeyPhaseBit) *ShortHeaderSealerKeyPhaseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Overhead mocks base method. @@ -73,9 +121,33 @@ func (m *MockShortHeaderSealer) Overhead() int { } // Overhead indicates an expected call of Overhead. -func (mr *MockShortHeaderSealerMockRecorder) Overhead() *gomock.Call { +func (mr *MockShortHeaderSealerMockRecorder) Overhead() *ShortHeaderSealerOverheadCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Overhead", reflect.TypeOf((*MockShortHeaderSealer)(nil).Overhead)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Overhead", reflect.TypeOf((*MockShortHeaderSealer)(nil).Overhead)) + return &ShortHeaderSealerOverheadCall{Call: call} +} + +// ShortHeaderSealerOverheadCall wrap *gomock.Call +type ShortHeaderSealerOverheadCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ShortHeaderSealerOverheadCall) Return(arg0 int) *ShortHeaderSealerOverheadCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ShortHeaderSealerOverheadCall) Do(f func() int) *ShortHeaderSealerOverheadCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ShortHeaderSealerOverheadCall) DoAndReturn(f func() int) *ShortHeaderSealerOverheadCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Seal mocks base method. @@ -87,7 +159,31 @@ 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 any) *gomock.Call { +func (mr *MockShortHeaderSealerMockRecorder) Seal(arg0, arg1, arg2, arg3 any) *ShortHeaderSealerSealCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Seal", reflect.TypeOf((*MockShortHeaderSealer)(nil).Seal), arg0, arg1, arg2, arg3) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Seal", reflect.TypeOf((*MockShortHeaderSealer)(nil).Seal), arg0, arg1, arg2, arg3) + return &ShortHeaderSealerSealCall{Call: call} +} + +// ShortHeaderSealerSealCall wrap *gomock.Call +type ShortHeaderSealerSealCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ShortHeaderSealerSealCall) Return(arg0 []byte) *ShortHeaderSealerSealCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ShortHeaderSealerSealCall) Do(f func([]byte, []byte, protocol.PacketNumber, []byte) []byte) *ShortHeaderSealerSealCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ShortHeaderSealerSealCall) DoAndReturn(f func([]byte, []byte, protocol.PacketNumber, []byte) []byte) *ShortHeaderSealerSealCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/stream_flow_controller.go b/internal/mocks/stream_flow_controller.go index 342661c9681..7207d76044a 100644 --- a/internal/mocks/stream_flow_controller.go +++ b/internal/mocks/stream_flow_controller.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mocks -destination stream_flow_controller.go github.com/quic-go/quic-go/internal/flowcontrol StreamFlowController +// mockgen -typed -build_flags=-tags=gomock -package mocks -destination stream_flow_controller.go github.com/quic-go/quic-go/internal/flowcontrol StreamFlowController // // Package mocks is a generated GoMock package. package mocks @@ -45,9 +45,33 @@ func (m *MockStreamFlowController) Abandon() { } // Abandon indicates an expected call of Abandon. -func (mr *MockStreamFlowControllerMockRecorder) Abandon() *gomock.Call { +func (mr *MockStreamFlowControllerMockRecorder) Abandon() *StreamFlowControllerAbandonCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Abandon", reflect.TypeOf((*MockStreamFlowController)(nil).Abandon)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Abandon", reflect.TypeOf((*MockStreamFlowController)(nil).Abandon)) + return &StreamFlowControllerAbandonCall{Call: call} +} + +// StreamFlowControllerAbandonCall wrap *gomock.Call +type StreamFlowControllerAbandonCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamFlowControllerAbandonCall) Return() *StreamFlowControllerAbandonCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamFlowControllerAbandonCall) Do(f func()) *StreamFlowControllerAbandonCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamFlowControllerAbandonCall) DoAndReturn(f func()) *StreamFlowControllerAbandonCall { + c.Call = c.Call.DoAndReturn(f) + return c } // AddBytesRead mocks base method. @@ -57,9 +81,33 @@ func (m *MockStreamFlowController) AddBytesRead(arg0 protocol.ByteCount) { } // AddBytesRead indicates an expected call of AddBytesRead. -func (mr *MockStreamFlowControllerMockRecorder) AddBytesRead(arg0 any) *gomock.Call { +func (mr *MockStreamFlowControllerMockRecorder) AddBytesRead(arg0 any) *StreamFlowControllerAddBytesReadCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesRead", reflect.TypeOf((*MockStreamFlowController)(nil).AddBytesRead), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesRead", reflect.TypeOf((*MockStreamFlowController)(nil).AddBytesRead), arg0) + return &StreamFlowControllerAddBytesReadCall{Call: call} +} + +// StreamFlowControllerAddBytesReadCall wrap *gomock.Call +type StreamFlowControllerAddBytesReadCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamFlowControllerAddBytesReadCall) Return() *StreamFlowControllerAddBytesReadCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamFlowControllerAddBytesReadCall) Do(f func(protocol.ByteCount)) *StreamFlowControllerAddBytesReadCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamFlowControllerAddBytesReadCall) DoAndReturn(f func(protocol.ByteCount)) *StreamFlowControllerAddBytesReadCall { + c.Call = c.Call.DoAndReturn(f) + return c } // AddBytesSent mocks base method. @@ -69,9 +117,33 @@ func (m *MockStreamFlowController) AddBytesSent(arg0 protocol.ByteCount) { } // AddBytesSent indicates an expected call of AddBytesSent. -func (mr *MockStreamFlowControllerMockRecorder) AddBytesSent(arg0 any) *gomock.Call { +func (mr *MockStreamFlowControllerMockRecorder) AddBytesSent(arg0 any) *StreamFlowControllerAddBytesSentCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesSent", reflect.TypeOf((*MockStreamFlowController)(nil).AddBytesSent), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBytesSent", reflect.TypeOf((*MockStreamFlowController)(nil).AddBytesSent), arg0) + return &StreamFlowControllerAddBytesSentCall{Call: call} +} + +// StreamFlowControllerAddBytesSentCall wrap *gomock.Call +type StreamFlowControllerAddBytesSentCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamFlowControllerAddBytesSentCall) Return() *StreamFlowControllerAddBytesSentCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamFlowControllerAddBytesSentCall) Do(f func(protocol.ByteCount)) *StreamFlowControllerAddBytesSentCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamFlowControllerAddBytesSentCall) DoAndReturn(f func(protocol.ByteCount)) *StreamFlowControllerAddBytesSentCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetWindowUpdate mocks base method. @@ -83,9 +155,33 @@ func (m *MockStreamFlowController) GetWindowUpdate() protocol.ByteCount { } // GetWindowUpdate indicates an expected call of GetWindowUpdate. -func (mr *MockStreamFlowControllerMockRecorder) GetWindowUpdate() *gomock.Call { +func (mr *MockStreamFlowControllerMockRecorder) GetWindowUpdate() *StreamFlowControllerGetWindowUpdateCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWindowUpdate", reflect.TypeOf((*MockStreamFlowController)(nil).GetWindowUpdate)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWindowUpdate", reflect.TypeOf((*MockStreamFlowController)(nil).GetWindowUpdate)) + return &StreamFlowControllerGetWindowUpdateCall{Call: call} +} + +// StreamFlowControllerGetWindowUpdateCall wrap *gomock.Call +type StreamFlowControllerGetWindowUpdateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamFlowControllerGetWindowUpdateCall) Return(arg0 protocol.ByteCount) *StreamFlowControllerGetWindowUpdateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamFlowControllerGetWindowUpdateCall) Do(f func() protocol.ByteCount) *StreamFlowControllerGetWindowUpdateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamFlowControllerGetWindowUpdateCall) DoAndReturn(f func() protocol.ByteCount) *StreamFlowControllerGetWindowUpdateCall { + c.Call = c.Call.DoAndReturn(f) + return c } // IsNewlyBlocked mocks base method. @@ -98,9 +194,33 @@ func (m *MockStreamFlowController) IsNewlyBlocked() (bool, protocol.ByteCount) { } // IsNewlyBlocked indicates an expected call of IsNewlyBlocked. -func (mr *MockStreamFlowControllerMockRecorder) IsNewlyBlocked() *gomock.Call { +func (mr *MockStreamFlowControllerMockRecorder) IsNewlyBlocked() *StreamFlowControllerIsNewlyBlockedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsNewlyBlocked", reflect.TypeOf((*MockStreamFlowController)(nil).IsNewlyBlocked)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsNewlyBlocked", reflect.TypeOf((*MockStreamFlowController)(nil).IsNewlyBlocked)) + return &StreamFlowControllerIsNewlyBlockedCall{Call: call} +} + +// StreamFlowControllerIsNewlyBlockedCall wrap *gomock.Call +type StreamFlowControllerIsNewlyBlockedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamFlowControllerIsNewlyBlockedCall) Return(arg0 bool, arg1 protocol.ByteCount) *StreamFlowControllerIsNewlyBlockedCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamFlowControllerIsNewlyBlockedCall) Do(f func() (bool, protocol.ByteCount)) *StreamFlowControllerIsNewlyBlockedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamFlowControllerIsNewlyBlockedCall) DoAndReturn(f func() (bool, protocol.ByteCount)) *StreamFlowControllerIsNewlyBlockedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SendWindowSize mocks base method. @@ -112,9 +232,33 @@ func (m *MockStreamFlowController) SendWindowSize() protocol.ByteCount { } // SendWindowSize indicates an expected call of SendWindowSize. -func (mr *MockStreamFlowControllerMockRecorder) SendWindowSize() *gomock.Call { +func (mr *MockStreamFlowControllerMockRecorder) SendWindowSize() *StreamFlowControllerSendWindowSizeCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendWindowSize", reflect.TypeOf((*MockStreamFlowController)(nil).SendWindowSize)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendWindowSize", reflect.TypeOf((*MockStreamFlowController)(nil).SendWindowSize)) + return &StreamFlowControllerSendWindowSizeCall{Call: call} +} + +// StreamFlowControllerSendWindowSizeCall wrap *gomock.Call +type StreamFlowControllerSendWindowSizeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamFlowControllerSendWindowSizeCall) Return(arg0 protocol.ByteCount) *StreamFlowControllerSendWindowSizeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamFlowControllerSendWindowSizeCall) Do(f func() protocol.ByteCount) *StreamFlowControllerSendWindowSizeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamFlowControllerSendWindowSizeCall) DoAndReturn(f func() protocol.ByteCount) *StreamFlowControllerSendWindowSizeCall { + c.Call = c.Call.DoAndReturn(f) + return c } // UpdateHighestReceived mocks base method. @@ -126,9 +270,33 @@ func (m *MockStreamFlowController) UpdateHighestReceived(arg0 protocol.ByteCount } // UpdateHighestReceived indicates an expected call of UpdateHighestReceived. -func (mr *MockStreamFlowControllerMockRecorder) UpdateHighestReceived(arg0, arg1 any) *gomock.Call { +func (mr *MockStreamFlowControllerMockRecorder) UpdateHighestReceived(arg0, arg1 any) *StreamFlowControllerUpdateHighestReceivedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateHighestReceived", reflect.TypeOf((*MockStreamFlowController)(nil).UpdateHighestReceived), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateHighestReceived", reflect.TypeOf((*MockStreamFlowController)(nil).UpdateHighestReceived), arg0, arg1) + return &StreamFlowControllerUpdateHighestReceivedCall{Call: call} +} + +// StreamFlowControllerUpdateHighestReceivedCall wrap *gomock.Call +type StreamFlowControllerUpdateHighestReceivedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamFlowControllerUpdateHighestReceivedCall) Return(arg0 error) *StreamFlowControllerUpdateHighestReceivedCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamFlowControllerUpdateHighestReceivedCall) Do(f func(protocol.ByteCount, bool) error) *StreamFlowControllerUpdateHighestReceivedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamFlowControllerUpdateHighestReceivedCall) DoAndReturn(f func(protocol.ByteCount, bool) error) *StreamFlowControllerUpdateHighestReceivedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // UpdateSendWindow mocks base method. @@ -138,7 +306,31 @@ func (m *MockStreamFlowController) UpdateSendWindow(arg0 protocol.ByteCount) { } // UpdateSendWindow indicates an expected call of UpdateSendWindow. -func (mr *MockStreamFlowControllerMockRecorder) UpdateSendWindow(arg0 any) *gomock.Call { +func (mr *MockStreamFlowControllerMockRecorder) UpdateSendWindow(arg0 any) *StreamFlowControllerUpdateSendWindowCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSendWindow", reflect.TypeOf((*MockStreamFlowController)(nil).UpdateSendWindow), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSendWindow", reflect.TypeOf((*MockStreamFlowController)(nil).UpdateSendWindow), arg0) + return &StreamFlowControllerUpdateSendWindowCall{Call: call} +} + +// StreamFlowControllerUpdateSendWindowCall wrap *gomock.Call +type StreamFlowControllerUpdateSendWindowCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamFlowControllerUpdateSendWindowCall) Return() *StreamFlowControllerUpdateSendWindowCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamFlowControllerUpdateSendWindowCall) Do(f func(protocol.ByteCount)) *StreamFlowControllerUpdateSendWindowCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamFlowControllerUpdateSendWindowCall) DoAndReturn(f func(protocol.ByteCount)) *StreamFlowControllerUpdateSendWindowCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/internal/mocks/tls/client_session_cache.go b/internal/mocks/tls/client_session_cache.go index 8837755facf..1f57522f700 100644 --- a/internal/mocks/tls/client_session_cache.go +++ b/internal/mocks/tls/client_session_cache.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package mocktls -destination tls/client_session_cache.go crypto/tls ClientSessionCache +// mockgen -typed -build_flags=-tags=gomock -package mocktls -destination tls/client_session_cache.go crypto/tls ClientSessionCache // // Package mocktls is a generated GoMock package. package mocktls @@ -48,9 +48,33 @@ func (m *MockClientSessionCache) Get(arg0 string) (*tls.ClientSessionState, bool } // Get indicates an expected call of Get. -func (mr *MockClientSessionCacheMockRecorder) Get(arg0 any) *gomock.Call { +func (mr *MockClientSessionCacheMockRecorder) Get(arg0 any) *ClientSessionCacheGetCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClientSessionCache)(nil).Get), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClientSessionCache)(nil).Get), arg0) + return &ClientSessionCacheGetCall{Call: call} +} + +// ClientSessionCacheGetCall wrap *gomock.Call +type ClientSessionCacheGetCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ClientSessionCacheGetCall) Return(arg0 *tls.ClientSessionState, arg1 bool) *ClientSessionCacheGetCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ClientSessionCacheGetCall) Do(f func(string) (*tls.ClientSessionState, bool)) *ClientSessionCacheGetCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ClientSessionCacheGetCall) DoAndReturn(f func(string) (*tls.ClientSessionState, bool)) *ClientSessionCacheGetCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Put mocks base method. @@ -60,7 +84,31 @@ func (m *MockClientSessionCache) Put(arg0 string, arg1 *tls.ClientSessionState) } // Put indicates an expected call of Put. -func (mr *MockClientSessionCacheMockRecorder) Put(arg0, arg1 any) *gomock.Call { +func (mr *MockClientSessionCacheMockRecorder) Put(arg0, arg1 any) *ClientSessionCachePutCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockClientSessionCache)(nil).Put), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockClientSessionCache)(nil).Put), arg0, arg1) + return &ClientSessionCachePutCall{Call: call} +} + +// ClientSessionCachePutCall wrap *gomock.Call +type ClientSessionCachePutCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ClientSessionCachePutCall) Return() *ClientSessionCachePutCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ClientSessionCachePutCall) Do(f func(string, *tls.ClientSessionState)) *ClientSessionCachePutCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ClientSessionCachePutCall) DoAndReturn(f func(string, *tls.ClientSessionState)) *ClientSessionCachePutCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_ack_frame_source_test.go b/mock_ack_frame_source_test.go index 4990e4722af..b29660cccab 100644 --- a/mock_ack_frame_source_test.go +++ b/mock_ack_frame_source_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_ack_frame_source_test.go github.com/quic-go/quic-go AckFrameSource +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_ack_frame_source_test.go github.com/quic-go/quic-go AckFrameSource // // Package quic is a generated GoMock package. package quic @@ -48,7 +48,31 @@ func (m *MockAckFrameSource) GetAckFrame(arg0 protocol.EncryptionLevel, arg1 boo } // GetAckFrame indicates an expected call of GetAckFrame. -func (mr *MockAckFrameSourceMockRecorder) GetAckFrame(arg0, arg1 any) *gomock.Call { +func (mr *MockAckFrameSourceMockRecorder) GetAckFrame(arg0, arg1 any) *AckFrameSourceGetAckFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAckFrame", reflect.TypeOf((*MockAckFrameSource)(nil).GetAckFrame), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAckFrame", reflect.TypeOf((*MockAckFrameSource)(nil).GetAckFrame), arg0, arg1) + return &AckFrameSourceGetAckFrameCall{Call: call} +} + +// AckFrameSourceGetAckFrameCall wrap *gomock.Call +type AckFrameSourceGetAckFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *AckFrameSourceGetAckFrameCall) Return(arg0 *wire.AckFrame) *AckFrameSourceGetAckFrameCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *AckFrameSourceGetAckFrameCall) Do(f func(protocol.EncryptionLevel, bool) *wire.AckFrame) *AckFrameSourceGetAckFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *AckFrameSourceGetAckFrameCall) DoAndReturn(f func(protocol.EncryptionLevel, bool) *wire.AckFrame) *AckFrameSourceGetAckFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_batch_conn_test.go b/mock_batch_conn_test.go index 1ecc4265f9b..5337e40c3d3 100644 --- a/mock_batch_conn_test.go +++ b/mock_batch_conn_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -package quic -self_package github.com/quic-go/quic-go -source sys_conn_oob.go -destination mock_batch_conn_test.go -mock_names batchConn=MockBatchConn +// mockgen -typed -package quic -self_package github.com/quic-go/quic-go -source sys_conn_oob.go -destination mock_batch_conn_test.go -mock_names batchConn=MockBatchConn // // Package quic is a generated GoMock package. package quic @@ -48,7 +48,31 @@ func (m *MockBatchConn) ReadBatch(ms []ipv4.Message, flags int) (int, error) { } // ReadBatch indicates an expected call of ReadBatch. -func (mr *MockBatchConnMockRecorder) ReadBatch(ms, flags any) *gomock.Call { +func (mr *MockBatchConnMockRecorder) ReadBatch(ms, flags any) *batchConnReadBatchCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadBatch", reflect.TypeOf((*MockBatchConn)(nil).ReadBatch), ms, flags) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadBatch", reflect.TypeOf((*MockBatchConn)(nil).ReadBatch), ms, flags) + return &batchConnReadBatchCall{Call: call} +} + +// batchConnReadBatchCall wrap *gomock.Call +type batchConnReadBatchCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *batchConnReadBatchCall) Return(arg0 int, arg1 error) *batchConnReadBatchCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *batchConnReadBatchCall) Do(f func([]ipv4.Message, int) (int, error)) *batchConnReadBatchCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *batchConnReadBatchCall) DoAndReturn(f func([]ipv4.Message, int) (int, error)) *batchConnReadBatchCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_conn_runner_test.go b/mock_conn_runner_test.go index 37c0f6cd2f9..b1fd19f419e 100644 --- a/mock_conn_runner_test.go +++ b/mock_conn_runner_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_conn_runner_test.go github.com/quic-go/quic-go ConnRunner +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_conn_runner_test.go github.com/quic-go/quic-go ConnRunner // // Package quic is a generated GoMock package. package quic @@ -47,9 +47,33 @@ func (m *MockConnRunner) Add(arg0 protocol.ConnectionID, arg1 packetHandler) boo } // Add indicates an expected call of Add. -func (mr *MockConnRunnerMockRecorder) Add(arg0, arg1 any) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) Add(arg0, arg1 any) *ConnRunnerAddCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockConnRunner)(nil).Add), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockConnRunner)(nil).Add), arg0, arg1) + return &ConnRunnerAddCall{Call: call} +} + +// ConnRunnerAddCall wrap *gomock.Call +type ConnRunnerAddCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnRunnerAddCall) Return(arg0 bool) *ConnRunnerAddCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnRunnerAddCall) Do(f func(protocol.ConnectionID, packetHandler) bool) *ConnRunnerAddCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnRunnerAddCall) DoAndReturn(f func(protocol.ConnectionID, packetHandler) bool) *ConnRunnerAddCall { + c.Call = c.Call.DoAndReturn(f) + return c } // AddResetToken mocks base method. @@ -59,9 +83,33 @@ func (m *MockConnRunner) AddResetToken(arg0 protocol.StatelessResetToken, arg1 p } // AddResetToken indicates an expected call of AddResetToken. -func (mr *MockConnRunnerMockRecorder) AddResetToken(arg0, arg1 any) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) AddResetToken(arg0, arg1 any) *ConnRunnerAddResetTokenCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddResetToken", reflect.TypeOf((*MockConnRunner)(nil).AddResetToken), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddResetToken", reflect.TypeOf((*MockConnRunner)(nil).AddResetToken), arg0, arg1) + return &ConnRunnerAddResetTokenCall{Call: call} +} + +// ConnRunnerAddResetTokenCall wrap *gomock.Call +type ConnRunnerAddResetTokenCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnRunnerAddResetTokenCall) Return() *ConnRunnerAddResetTokenCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnRunnerAddResetTokenCall) Do(f func(protocol.StatelessResetToken, packetHandler)) *ConnRunnerAddResetTokenCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnRunnerAddResetTokenCall) DoAndReturn(f func(protocol.StatelessResetToken, packetHandler)) *ConnRunnerAddResetTokenCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetStatelessResetToken mocks base method. @@ -73,9 +121,33 @@ func (m *MockConnRunner) GetStatelessResetToken(arg0 protocol.ConnectionID) prot } // GetStatelessResetToken indicates an expected call of GetStatelessResetToken. -func (mr *MockConnRunnerMockRecorder) GetStatelessResetToken(arg0 any) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) GetStatelessResetToken(arg0 any) *ConnRunnerGetStatelessResetTokenCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessResetToken", reflect.TypeOf((*MockConnRunner)(nil).GetStatelessResetToken), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessResetToken", reflect.TypeOf((*MockConnRunner)(nil).GetStatelessResetToken), arg0) + return &ConnRunnerGetStatelessResetTokenCall{Call: call} +} + +// ConnRunnerGetStatelessResetTokenCall wrap *gomock.Call +type ConnRunnerGetStatelessResetTokenCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnRunnerGetStatelessResetTokenCall) Return(arg0 protocol.StatelessResetToken) *ConnRunnerGetStatelessResetTokenCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnRunnerGetStatelessResetTokenCall) Do(f func(protocol.ConnectionID) protocol.StatelessResetToken) *ConnRunnerGetStatelessResetTokenCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnRunnerGetStatelessResetTokenCall) DoAndReturn(f func(protocol.ConnectionID) protocol.StatelessResetToken) *ConnRunnerGetStatelessResetTokenCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Remove mocks base method. @@ -85,9 +157,33 @@ func (m *MockConnRunner) Remove(arg0 protocol.ConnectionID) { } // Remove indicates an expected call of Remove. -func (mr *MockConnRunnerMockRecorder) Remove(arg0 any) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) Remove(arg0 any) *ConnRunnerRemoveCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockConnRunner)(nil).Remove), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockConnRunner)(nil).Remove), arg0) + return &ConnRunnerRemoveCall{Call: call} +} + +// ConnRunnerRemoveCall wrap *gomock.Call +type ConnRunnerRemoveCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnRunnerRemoveCall) Return() *ConnRunnerRemoveCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnRunnerRemoveCall) Do(f func(protocol.ConnectionID)) *ConnRunnerRemoveCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnRunnerRemoveCall) DoAndReturn(f func(protocol.ConnectionID)) *ConnRunnerRemoveCall { + c.Call = c.Call.DoAndReturn(f) + return c } // RemoveResetToken mocks base method. @@ -97,9 +193,33 @@ func (m *MockConnRunner) RemoveResetToken(arg0 protocol.StatelessResetToken) { } // RemoveResetToken indicates an expected call of RemoveResetToken. -func (mr *MockConnRunnerMockRecorder) RemoveResetToken(arg0 any) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) RemoveResetToken(arg0 any) *ConnRunnerRemoveResetTokenCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveResetToken", reflect.TypeOf((*MockConnRunner)(nil).RemoveResetToken), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveResetToken", reflect.TypeOf((*MockConnRunner)(nil).RemoveResetToken), arg0) + return &ConnRunnerRemoveResetTokenCall{Call: call} +} + +// ConnRunnerRemoveResetTokenCall wrap *gomock.Call +type ConnRunnerRemoveResetTokenCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnRunnerRemoveResetTokenCall) Return() *ConnRunnerRemoveResetTokenCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnRunnerRemoveResetTokenCall) Do(f func(protocol.StatelessResetToken)) *ConnRunnerRemoveResetTokenCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnRunnerRemoveResetTokenCall) DoAndReturn(f func(protocol.StatelessResetToken)) *ConnRunnerRemoveResetTokenCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReplaceWithClosed mocks base method. @@ -109,9 +229,33 @@ func (m *MockConnRunner) ReplaceWithClosed(arg0 []protocol.ConnectionID, arg1 pr } // ReplaceWithClosed indicates an expected call of ReplaceWithClosed. -func (mr *MockConnRunnerMockRecorder) ReplaceWithClosed(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) ReplaceWithClosed(arg0, arg1, arg2 any) *ConnRunnerReplaceWithClosedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceWithClosed", reflect.TypeOf((*MockConnRunner)(nil).ReplaceWithClosed), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceWithClosed", reflect.TypeOf((*MockConnRunner)(nil).ReplaceWithClosed), arg0, arg1, arg2) + return &ConnRunnerReplaceWithClosedCall{Call: call} +} + +// ConnRunnerReplaceWithClosedCall wrap *gomock.Call +type ConnRunnerReplaceWithClosedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnRunnerReplaceWithClosedCall) Return() *ConnRunnerReplaceWithClosedCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnRunnerReplaceWithClosedCall) Do(f func([]protocol.ConnectionID, protocol.Perspective, []byte)) *ConnRunnerReplaceWithClosedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnRunnerReplaceWithClosedCall) DoAndReturn(f func([]protocol.ConnectionID, protocol.Perspective, []byte)) *ConnRunnerReplaceWithClosedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Retire mocks base method. @@ -121,7 +265,31 @@ func (m *MockConnRunner) Retire(arg0 protocol.ConnectionID) { } // Retire indicates an expected call of Retire. -func (mr *MockConnRunnerMockRecorder) Retire(arg0 any) *gomock.Call { +func (mr *MockConnRunnerMockRecorder) Retire(arg0 any) *ConnRunnerRetireCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Retire", reflect.TypeOf((*MockConnRunner)(nil).Retire), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Retire", reflect.TypeOf((*MockConnRunner)(nil).Retire), arg0) + return &ConnRunnerRetireCall{Call: call} +} + +// ConnRunnerRetireCall wrap *gomock.Call +type ConnRunnerRetireCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnRunnerRetireCall) Return() *ConnRunnerRetireCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnRunnerRetireCall) Do(f func(protocol.ConnectionID)) *ConnRunnerRetireCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnRunnerRetireCall) DoAndReturn(f func(protocol.ConnectionID)) *ConnRunnerRetireCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_crypto_data_handler_test.go b/mock_crypto_data_handler_test.go index 3240b981e1a..f65526dfe53 100644 --- a/mock_crypto_data_handler_test.go +++ b/mock_crypto_data_handler_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_data_handler_test.go github.com/quic-go/quic-go CryptoDataHandler +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_data_handler_test.go github.com/quic-go/quic-go CryptoDataHandler // // Package quic is a generated GoMock package. package quic @@ -48,9 +48,33 @@ func (m *MockCryptoDataHandler) HandleMessage(arg0 []byte, arg1 protocol.Encrypt } // HandleMessage indicates an expected call of HandleMessage. -func (mr *MockCryptoDataHandlerMockRecorder) HandleMessage(arg0, arg1 any) *gomock.Call { +func (mr *MockCryptoDataHandlerMockRecorder) HandleMessage(arg0, arg1 any) *CryptoDataHandlerHandleMessageCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMessage", reflect.TypeOf((*MockCryptoDataHandler)(nil).HandleMessage), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMessage", reflect.TypeOf((*MockCryptoDataHandler)(nil).HandleMessage), arg0, arg1) + return &CryptoDataHandlerHandleMessageCall{Call: call} +} + +// CryptoDataHandlerHandleMessageCall wrap *gomock.Call +type CryptoDataHandlerHandleMessageCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoDataHandlerHandleMessageCall) Return(arg0 error) *CryptoDataHandlerHandleMessageCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoDataHandlerHandleMessageCall) Do(f func([]byte, protocol.EncryptionLevel) error) *CryptoDataHandlerHandleMessageCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoDataHandlerHandleMessageCall) DoAndReturn(f func([]byte, protocol.EncryptionLevel) error) *CryptoDataHandlerHandleMessageCall { + c.Call = c.Call.DoAndReturn(f) + return c } // NextEvent mocks base method. @@ -62,7 +86,31 @@ func (m *MockCryptoDataHandler) NextEvent() handshake.Event { } // NextEvent indicates an expected call of NextEvent. -func (mr *MockCryptoDataHandlerMockRecorder) NextEvent() *gomock.Call { +func (mr *MockCryptoDataHandlerMockRecorder) NextEvent() *CryptoDataHandlerNextEventCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NextEvent", reflect.TypeOf((*MockCryptoDataHandler)(nil).NextEvent)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NextEvent", reflect.TypeOf((*MockCryptoDataHandler)(nil).NextEvent)) + return &CryptoDataHandlerNextEventCall{Call: call} +} + +// CryptoDataHandlerNextEventCall wrap *gomock.Call +type CryptoDataHandlerNextEventCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoDataHandlerNextEventCall) Return(arg0 handshake.Event) *CryptoDataHandlerNextEventCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoDataHandlerNextEventCall) Do(f func() handshake.Event) *CryptoDataHandlerNextEventCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoDataHandlerNextEventCall) DoAndReturn(f func() handshake.Event) *CryptoDataHandlerNextEventCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_crypto_stream_test.go b/mock_crypto_stream_test.go index 176b51f38e0..0e93650c0bc 100644 --- a/mock_crypto_stream_test.go +++ b/mock_crypto_stream_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_stream_test.go github.com/quic-go/quic-go CryptoStream +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_stream_test.go github.com/quic-go/quic-go CryptoStream // // Package quic is a generated GoMock package. package quic @@ -48,9 +48,33 @@ func (m *MockCryptoStream) Finish() error { } // Finish indicates an expected call of Finish. -func (mr *MockCryptoStreamMockRecorder) Finish() *gomock.Call { +func (mr *MockCryptoStreamMockRecorder) Finish() *CryptoStreamFinishCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Finish", reflect.TypeOf((*MockCryptoStream)(nil).Finish)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Finish", reflect.TypeOf((*MockCryptoStream)(nil).Finish)) + return &CryptoStreamFinishCall{Call: call} +} + +// CryptoStreamFinishCall wrap *gomock.Call +type CryptoStreamFinishCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoStreamFinishCall) Return(arg0 error) *CryptoStreamFinishCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoStreamFinishCall) Do(f func() error) *CryptoStreamFinishCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoStreamFinishCall) DoAndReturn(f func() error) *CryptoStreamFinishCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetCryptoData mocks base method. @@ -62,9 +86,33 @@ func (m *MockCryptoStream) GetCryptoData() []byte { } // GetCryptoData indicates an expected call of GetCryptoData. -func (mr *MockCryptoStreamMockRecorder) GetCryptoData() *gomock.Call { +func (mr *MockCryptoStreamMockRecorder) GetCryptoData() *CryptoStreamGetCryptoDataCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCryptoData", reflect.TypeOf((*MockCryptoStream)(nil).GetCryptoData)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCryptoData", reflect.TypeOf((*MockCryptoStream)(nil).GetCryptoData)) + return &CryptoStreamGetCryptoDataCall{Call: call} +} + +// CryptoStreamGetCryptoDataCall wrap *gomock.Call +type CryptoStreamGetCryptoDataCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoStreamGetCryptoDataCall) Return(arg0 []byte) *CryptoStreamGetCryptoDataCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoStreamGetCryptoDataCall) Do(f func() []byte) *CryptoStreamGetCryptoDataCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoStreamGetCryptoDataCall) DoAndReturn(f func() []byte) *CryptoStreamGetCryptoDataCall { + c.Call = c.Call.DoAndReturn(f) + return c } // HandleCryptoFrame mocks base method. @@ -76,9 +124,33 @@ func (m *MockCryptoStream) HandleCryptoFrame(arg0 *wire.CryptoFrame) error { } // HandleCryptoFrame indicates an expected call of HandleCryptoFrame. -func (mr *MockCryptoStreamMockRecorder) HandleCryptoFrame(arg0 any) *gomock.Call { +func (mr *MockCryptoStreamMockRecorder) HandleCryptoFrame(arg0 any) *CryptoStreamHandleCryptoFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleCryptoFrame", reflect.TypeOf((*MockCryptoStream)(nil).HandleCryptoFrame), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleCryptoFrame", reflect.TypeOf((*MockCryptoStream)(nil).HandleCryptoFrame), arg0) + return &CryptoStreamHandleCryptoFrameCall{Call: call} +} + +// CryptoStreamHandleCryptoFrameCall wrap *gomock.Call +type CryptoStreamHandleCryptoFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoStreamHandleCryptoFrameCall) Return(arg0 error) *CryptoStreamHandleCryptoFrameCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoStreamHandleCryptoFrameCall) Do(f func(*wire.CryptoFrame) error) *CryptoStreamHandleCryptoFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoStreamHandleCryptoFrameCall) DoAndReturn(f func(*wire.CryptoFrame) error) *CryptoStreamHandleCryptoFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } // HasData mocks base method. @@ -90,9 +162,33 @@ func (m *MockCryptoStream) HasData() bool { } // HasData indicates an expected call of HasData. -func (mr *MockCryptoStreamMockRecorder) HasData() *gomock.Call { +func (mr *MockCryptoStreamMockRecorder) HasData() *CryptoStreamHasDataCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasData", reflect.TypeOf((*MockCryptoStream)(nil).HasData)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasData", reflect.TypeOf((*MockCryptoStream)(nil).HasData)) + return &CryptoStreamHasDataCall{Call: call} +} + +// CryptoStreamHasDataCall wrap *gomock.Call +type CryptoStreamHasDataCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoStreamHasDataCall) Return(arg0 bool) *CryptoStreamHasDataCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoStreamHasDataCall) Do(f func() bool) *CryptoStreamHasDataCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoStreamHasDataCall) DoAndReturn(f func() bool) *CryptoStreamHasDataCall { + c.Call = c.Call.DoAndReturn(f) + return c } // PopCryptoFrame mocks base method. @@ -104,9 +200,33 @@ func (m *MockCryptoStream) PopCryptoFrame(arg0 protocol.ByteCount) *wire.CryptoF } // PopCryptoFrame indicates an expected call of PopCryptoFrame. -func (mr *MockCryptoStreamMockRecorder) PopCryptoFrame(arg0 any) *gomock.Call { +func (mr *MockCryptoStreamMockRecorder) PopCryptoFrame(arg0 any) *CryptoStreamPopCryptoFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PopCryptoFrame", reflect.TypeOf((*MockCryptoStream)(nil).PopCryptoFrame), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PopCryptoFrame", reflect.TypeOf((*MockCryptoStream)(nil).PopCryptoFrame), arg0) + return &CryptoStreamPopCryptoFrameCall{Call: call} +} + +// CryptoStreamPopCryptoFrameCall wrap *gomock.Call +type CryptoStreamPopCryptoFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoStreamPopCryptoFrameCall) Return(arg0 *wire.CryptoFrame) *CryptoStreamPopCryptoFrameCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoStreamPopCryptoFrameCall) Do(f func(protocol.ByteCount) *wire.CryptoFrame) *CryptoStreamPopCryptoFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoStreamPopCryptoFrameCall) DoAndReturn(f func(protocol.ByteCount) *wire.CryptoFrame) *CryptoStreamPopCryptoFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Write mocks base method. @@ -119,7 +239,31 @@ func (m *MockCryptoStream) Write(arg0 []byte) (int, error) { } // Write indicates an expected call of Write. -func (mr *MockCryptoStreamMockRecorder) Write(arg0 any) *gomock.Call { +func (mr *MockCryptoStreamMockRecorder) Write(arg0 any) *CryptoStreamWriteCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockCryptoStream)(nil).Write), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockCryptoStream)(nil).Write), arg0) + return &CryptoStreamWriteCall{Call: call} +} + +// CryptoStreamWriteCall wrap *gomock.Call +type CryptoStreamWriteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *CryptoStreamWriteCall) Return(arg0 int, arg1 error) *CryptoStreamWriteCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *CryptoStreamWriteCall) Do(f func([]byte) (int, error)) *CryptoStreamWriteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *CryptoStreamWriteCall) DoAndReturn(f func([]byte) (int, error)) *CryptoStreamWriteCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_frame_source_test.go b/mock_frame_source_test.go index b3b6638b550..df86b7bee86 100644 --- a/mock_frame_source_test.go +++ b/mock_frame_source_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_frame_source_test.go github.com/quic-go/quic-go FrameSource +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_frame_source_test.go github.com/quic-go/quic-go FrameSource // // Package quic is a generated GoMock package. package quic @@ -49,9 +49,33 @@ func (m *MockFrameSource) AppendControlFrames(arg0 []ackhandler.Frame, arg1 prot } // AppendControlFrames indicates an expected call of AppendControlFrames. -func (mr *MockFrameSourceMockRecorder) AppendControlFrames(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockFrameSourceMockRecorder) AppendControlFrames(arg0, arg1, arg2 any) *FrameSourceAppendControlFramesCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendControlFrames", reflect.TypeOf((*MockFrameSource)(nil).AppendControlFrames), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendControlFrames", reflect.TypeOf((*MockFrameSource)(nil).AppendControlFrames), arg0, arg1, arg2) + return &FrameSourceAppendControlFramesCall{Call: call} +} + +// FrameSourceAppendControlFramesCall wrap *gomock.Call +type FrameSourceAppendControlFramesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *FrameSourceAppendControlFramesCall) Return(arg0 []ackhandler.Frame, arg1 protocol.ByteCount) *FrameSourceAppendControlFramesCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *FrameSourceAppendControlFramesCall) Do(f func([]ackhandler.Frame, protocol.ByteCount, protocol.VersionNumber) ([]ackhandler.Frame, protocol.ByteCount)) *FrameSourceAppendControlFramesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *FrameSourceAppendControlFramesCall) DoAndReturn(f func([]ackhandler.Frame, protocol.ByteCount, protocol.VersionNumber) ([]ackhandler.Frame, protocol.ByteCount)) *FrameSourceAppendControlFramesCall { + c.Call = c.Call.DoAndReturn(f) + return c } // AppendStreamFrames mocks base method. @@ -64,9 +88,33 @@ func (m *MockFrameSource) AppendStreamFrames(arg0 []ackhandler.StreamFrame, arg1 } // AppendStreamFrames indicates an expected call of AppendStreamFrames. -func (mr *MockFrameSourceMockRecorder) AppendStreamFrames(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockFrameSourceMockRecorder) AppendStreamFrames(arg0, arg1, arg2 any) *FrameSourceAppendStreamFramesCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendStreamFrames", reflect.TypeOf((*MockFrameSource)(nil).AppendStreamFrames), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendStreamFrames", reflect.TypeOf((*MockFrameSource)(nil).AppendStreamFrames), arg0, arg1, arg2) + return &FrameSourceAppendStreamFramesCall{Call: call} +} + +// FrameSourceAppendStreamFramesCall wrap *gomock.Call +type FrameSourceAppendStreamFramesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *FrameSourceAppendStreamFramesCall) Return(arg0 []ackhandler.StreamFrame, arg1 protocol.ByteCount) *FrameSourceAppendStreamFramesCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *FrameSourceAppendStreamFramesCall) Do(f func([]ackhandler.StreamFrame, protocol.ByteCount, protocol.VersionNumber) ([]ackhandler.StreamFrame, protocol.ByteCount)) *FrameSourceAppendStreamFramesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *FrameSourceAppendStreamFramesCall) DoAndReturn(f func([]ackhandler.StreamFrame, protocol.ByteCount, protocol.VersionNumber) ([]ackhandler.StreamFrame, protocol.ByteCount)) *FrameSourceAppendStreamFramesCall { + c.Call = c.Call.DoAndReturn(f) + return c } // HasData mocks base method. @@ -78,7 +126,31 @@ func (m *MockFrameSource) HasData() bool { } // HasData indicates an expected call of HasData. -func (mr *MockFrameSourceMockRecorder) HasData() *gomock.Call { +func (mr *MockFrameSourceMockRecorder) HasData() *FrameSourceHasDataCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasData", reflect.TypeOf((*MockFrameSource)(nil).HasData)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasData", reflect.TypeOf((*MockFrameSource)(nil).HasData)) + return &FrameSourceHasDataCall{Call: call} +} + +// FrameSourceHasDataCall wrap *gomock.Call +type FrameSourceHasDataCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *FrameSourceHasDataCall) Return(arg0 bool) *FrameSourceHasDataCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *FrameSourceHasDataCall) Do(f func() bool) *FrameSourceHasDataCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *FrameSourceHasDataCall) DoAndReturn(f func() bool) *FrameSourceHasDataCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_mtu_discoverer_test.go b/mock_mtu_discoverer_test.go index a8a9be3e387..3e6035b05e6 100644 --- a/mock_mtu_discoverer_test.go +++ b/mock_mtu_discoverer_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_mtu_discoverer_test.go github.com/quic-go/quic-go MTUDiscoverer +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_mtu_discoverer_test.go github.com/quic-go/quic-go MTUDiscoverer // // Package quic is a generated GoMock package. package quic @@ -49,9 +49,33 @@ func (m *MockMTUDiscoverer) CurrentSize() protocol.ByteCount { } // CurrentSize indicates an expected call of CurrentSize. -func (mr *MockMTUDiscovererMockRecorder) CurrentSize() *gomock.Call { +func (mr *MockMTUDiscovererMockRecorder) CurrentSize() *MTUDiscovererCurrentSizeCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentSize", reflect.TypeOf((*MockMTUDiscoverer)(nil).CurrentSize)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentSize", reflect.TypeOf((*MockMTUDiscoverer)(nil).CurrentSize)) + return &MTUDiscovererCurrentSizeCall{Call: call} +} + +// MTUDiscovererCurrentSizeCall wrap *gomock.Call +type MTUDiscovererCurrentSizeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MTUDiscovererCurrentSizeCall) Return(arg0 protocol.ByteCount) *MTUDiscovererCurrentSizeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MTUDiscovererCurrentSizeCall) Do(f func() protocol.ByteCount) *MTUDiscovererCurrentSizeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MTUDiscovererCurrentSizeCall) DoAndReturn(f func() protocol.ByteCount) *MTUDiscovererCurrentSizeCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetPing mocks base method. @@ -64,9 +88,33 @@ func (m *MockMTUDiscoverer) GetPing() (ackhandler.Frame, protocol.ByteCount) { } // GetPing indicates an expected call of GetPing. -func (mr *MockMTUDiscovererMockRecorder) GetPing() *gomock.Call { +func (mr *MockMTUDiscovererMockRecorder) GetPing() *MTUDiscovererGetPingCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPing", reflect.TypeOf((*MockMTUDiscoverer)(nil).GetPing)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPing", reflect.TypeOf((*MockMTUDiscoverer)(nil).GetPing)) + return &MTUDiscovererGetPingCall{Call: call} +} + +// MTUDiscovererGetPingCall wrap *gomock.Call +type MTUDiscovererGetPingCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MTUDiscovererGetPingCall) Return(arg0 ackhandler.Frame, arg1 protocol.ByteCount) *MTUDiscovererGetPingCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MTUDiscovererGetPingCall) Do(f func() (ackhandler.Frame, protocol.ByteCount)) *MTUDiscovererGetPingCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MTUDiscovererGetPingCall) DoAndReturn(f func() (ackhandler.Frame, protocol.ByteCount)) *MTUDiscovererGetPingCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ShouldSendProbe mocks base method. @@ -78,9 +126,33 @@ func (m *MockMTUDiscoverer) ShouldSendProbe(arg0 time.Time) bool { } // ShouldSendProbe indicates an expected call of ShouldSendProbe. -func (mr *MockMTUDiscovererMockRecorder) ShouldSendProbe(arg0 any) *gomock.Call { +func (mr *MockMTUDiscovererMockRecorder) ShouldSendProbe(arg0 any) *MTUDiscovererShouldSendProbeCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldSendProbe", reflect.TypeOf((*MockMTUDiscoverer)(nil).ShouldSendProbe), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldSendProbe", reflect.TypeOf((*MockMTUDiscoverer)(nil).ShouldSendProbe), arg0) + return &MTUDiscovererShouldSendProbeCall{Call: call} +} + +// MTUDiscovererShouldSendProbeCall wrap *gomock.Call +type MTUDiscovererShouldSendProbeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MTUDiscovererShouldSendProbeCall) Return(arg0 bool) *MTUDiscovererShouldSendProbeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MTUDiscovererShouldSendProbeCall) Do(f func(time.Time) bool) *MTUDiscovererShouldSendProbeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MTUDiscovererShouldSendProbeCall) DoAndReturn(f func(time.Time) bool) *MTUDiscovererShouldSendProbeCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Start mocks base method. @@ -90,7 +162,31 @@ func (m *MockMTUDiscoverer) Start(arg0 protocol.ByteCount) { } // Start indicates an expected call of Start. -func (mr *MockMTUDiscovererMockRecorder) Start(arg0 any) *gomock.Call { +func (mr *MockMTUDiscovererMockRecorder) Start(arg0 any) *MTUDiscovererStartCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockMTUDiscoverer)(nil).Start), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockMTUDiscoverer)(nil).Start), arg0) + return &MTUDiscovererStartCall{Call: call} +} + +// MTUDiscovererStartCall wrap *gomock.Call +type MTUDiscovererStartCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MTUDiscovererStartCall) Return() *MTUDiscovererStartCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MTUDiscovererStartCall) Do(f func(protocol.ByteCount)) *MTUDiscovererStartCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MTUDiscovererStartCall) DoAndReturn(f func(protocol.ByteCount)) *MTUDiscovererStartCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_packer_test.go b/mock_packer_test.go index 26fc63a00dc..8ef1c323a01 100644 --- a/mock_packer_test.go +++ b/mock_packer_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_packer_test.go github.com/quic-go/quic-go Packer +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_packer_test.go github.com/quic-go/quic-go Packer // // Package quic is a generated GoMock package. package quic @@ -50,9 +50,33 @@ func (m *MockPacker) AppendPacket(arg0 *packetBuffer, arg1 protocol.ByteCount, a } // AppendPacket indicates an expected call of AppendPacket. -func (mr *MockPackerMockRecorder) AppendPacket(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockPackerMockRecorder) AppendPacket(arg0, arg1, arg2 any) *PackerAppendPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendPacket", reflect.TypeOf((*MockPacker)(nil).AppendPacket), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendPacket", reflect.TypeOf((*MockPacker)(nil).AppendPacket), arg0, arg1, arg2) + return &PackerAppendPacketCall{Call: call} +} + +// PackerAppendPacketCall wrap *gomock.Call +type PackerAppendPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PackerAppendPacketCall) Return(arg0 shortHeaderPacket, arg1 error) *PackerAppendPacketCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PackerAppendPacketCall) Do(f func(*packetBuffer, protocol.ByteCount, protocol.VersionNumber) (shortHeaderPacket, error)) *PackerAppendPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PackerAppendPacketCall) DoAndReturn(f func(*packetBuffer, protocol.ByteCount, protocol.VersionNumber) (shortHeaderPacket, error)) *PackerAppendPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // MaybePackProbePacket mocks base method. @@ -65,9 +89,33 @@ func (m *MockPacker) MaybePackProbePacket(arg0 protocol.EncryptionLevel, arg1 pr } // MaybePackProbePacket indicates an expected call of MaybePackProbePacket. -func (mr *MockPackerMockRecorder) MaybePackProbePacket(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockPackerMockRecorder) MaybePackProbePacket(arg0, arg1, arg2 any) *PackerMaybePackProbePacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaybePackProbePacket", reflect.TypeOf((*MockPacker)(nil).MaybePackProbePacket), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaybePackProbePacket", reflect.TypeOf((*MockPacker)(nil).MaybePackProbePacket), arg0, arg1, arg2) + return &PackerMaybePackProbePacketCall{Call: call} +} + +// PackerMaybePackProbePacketCall wrap *gomock.Call +type PackerMaybePackProbePacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PackerMaybePackProbePacketCall) Return(arg0 *coalescedPacket, arg1 error) *PackerMaybePackProbePacketCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PackerMaybePackProbePacketCall) Do(f func(protocol.EncryptionLevel, protocol.ByteCount, protocol.VersionNumber) (*coalescedPacket, error)) *PackerMaybePackProbePacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PackerMaybePackProbePacketCall) DoAndReturn(f func(protocol.EncryptionLevel, protocol.ByteCount, protocol.VersionNumber) (*coalescedPacket, error)) *PackerMaybePackProbePacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // PackAckOnlyPacket mocks base method. @@ -81,9 +129,33 @@ func (m *MockPacker) PackAckOnlyPacket(arg0 protocol.ByteCount, arg1 protocol.Ve } // PackAckOnlyPacket indicates an expected call of PackAckOnlyPacket. -func (mr *MockPackerMockRecorder) PackAckOnlyPacket(arg0, arg1 any) *gomock.Call { +func (mr *MockPackerMockRecorder) PackAckOnlyPacket(arg0, arg1 any) *PackerPackAckOnlyPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackAckOnlyPacket", reflect.TypeOf((*MockPacker)(nil).PackAckOnlyPacket), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackAckOnlyPacket", reflect.TypeOf((*MockPacker)(nil).PackAckOnlyPacket), arg0, arg1) + return &PackerPackAckOnlyPacketCall{Call: call} +} + +// PackerPackAckOnlyPacketCall wrap *gomock.Call +type PackerPackAckOnlyPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PackerPackAckOnlyPacketCall) Return(arg0 shortHeaderPacket, arg1 *packetBuffer, arg2 error) *PackerPackAckOnlyPacketCall { + c.Call = c.Call.Return(arg0, arg1, arg2) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PackerPackAckOnlyPacketCall) Do(f func(protocol.ByteCount, protocol.VersionNumber) (shortHeaderPacket, *packetBuffer, error)) *PackerPackAckOnlyPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PackerPackAckOnlyPacketCall) DoAndReturn(f func(protocol.ByteCount, protocol.VersionNumber) (shortHeaderPacket, *packetBuffer, error)) *PackerPackAckOnlyPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // PackApplicationClose mocks base method. @@ -96,9 +168,33 @@ func (m *MockPacker) PackApplicationClose(arg0 *qerr.ApplicationError, arg1 prot } // PackApplicationClose indicates an expected call of PackApplicationClose. -func (mr *MockPackerMockRecorder) PackApplicationClose(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockPackerMockRecorder) PackApplicationClose(arg0, arg1, arg2 any) *PackerPackApplicationCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackApplicationClose", reflect.TypeOf((*MockPacker)(nil).PackApplicationClose), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackApplicationClose", reflect.TypeOf((*MockPacker)(nil).PackApplicationClose), arg0, arg1, arg2) + return &PackerPackApplicationCloseCall{Call: call} +} + +// PackerPackApplicationCloseCall wrap *gomock.Call +type PackerPackApplicationCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PackerPackApplicationCloseCall) Return(arg0 *coalescedPacket, arg1 error) *PackerPackApplicationCloseCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PackerPackApplicationCloseCall) Do(f func(*qerr.ApplicationError, protocol.ByteCount, protocol.VersionNumber) (*coalescedPacket, error)) *PackerPackApplicationCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PackerPackApplicationCloseCall) DoAndReturn(f func(*qerr.ApplicationError, protocol.ByteCount, protocol.VersionNumber) (*coalescedPacket, error)) *PackerPackApplicationCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // PackCoalescedPacket mocks base method. @@ -111,9 +207,33 @@ func (m *MockPacker) PackCoalescedPacket(arg0 bool, arg1 protocol.ByteCount, arg } // PackCoalescedPacket indicates an expected call of PackCoalescedPacket. -func (mr *MockPackerMockRecorder) PackCoalescedPacket(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockPackerMockRecorder) PackCoalescedPacket(arg0, arg1, arg2 any) *PackerPackCoalescedPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackCoalescedPacket", reflect.TypeOf((*MockPacker)(nil).PackCoalescedPacket), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackCoalescedPacket", reflect.TypeOf((*MockPacker)(nil).PackCoalescedPacket), arg0, arg1, arg2) + return &PackerPackCoalescedPacketCall{Call: call} +} + +// PackerPackCoalescedPacketCall wrap *gomock.Call +type PackerPackCoalescedPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PackerPackCoalescedPacketCall) Return(arg0 *coalescedPacket, arg1 error) *PackerPackCoalescedPacketCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PackerPackCoalescedPacketCall) Do(f func(bool, protocol.ByteCount, protocol.VersionNumber) (*coalescedPacket, error)) *PackerPackCoalescedPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PackerPackCoalescedPacketCall) DoAndReturn(f func(bool, protocol.ByteCount, protocol.VersionNumber) (*coalescedPacket, error)) *PackerPackCoalescedPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // PackConnectionClose mocks base method. @@ -126,9 +246,33 @@ func (m *MockPacker) PackConnectionClose(arg0 *qerr.TransportError, arg1 protoco } // PackConnectionClose indicates an expected call of PackConnectionClose. -func (mr *MockPackerMockRecorder) PackConnectionClose(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockPackerMockRecorder) PackConnectionClose(arg0, arg1, arg2 any) *PackerPackConnectionCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackConnectionClose", reflect.TypeOf((*MockPacker)(nil).PackConnectionClose), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackConnectionClose", reflect.TypeOf((*MockPacker)(nil).PackConnectionClose), arg0, arg1, arg2) + return &PackerPackConnectionCloseCall{Call: call} +} + +// PackerPackConnectionCloseCall wrap *gomock.Call +type PackerPackConnectionCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PackerPackConnectionCloseCall) Return(arg0 *coalescedPacket, arg1 error) *PackerPackConnectionCloseCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PackerPackConnectionCloseCall) Do(f func(*qerr.TransportError, protocol.ByteCount, protocol.VersionNumber) (*coalescedPacket, error)) *PackerPackConnectionCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PackerPackConnectionCloseCall) DoAndReturn(f func(*qerr.TransportError, protocol.ByteCount, protocol.VersionNumber) (*coalescedPacket, error)) *PackerPackConnectionCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // PackMTUProbePacket mocks base method. @@ -142,9 +286,33 @@ func (m *MockPacker) PackMTUProbePacket(arg0 ackhandler.Frame, arg1 protocol.Byt } // PackMTUProbePacket indicates an expected call of PackMTUProbePacket. -func (mr *MockPackerMockRecorder) PackMTUProbePacket(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockPackerMockRecorder) PackMTUProbePacket(arg0, arg1, arg2 any) *PackerPackMTUProbePacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackMTUProbePacket", reflect.TypeOf((*MockPacker)(nil).PackMTUProbePacket), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackMTUProbePacket", reflect.TypeOf((*MockPacker)(nil).PackMTUProbePacket), arg0, arg1, arg2) + return &PackerPackMTUProbePacketCall{Call: call} +} + +// PackerPackMTUProbePacketCall wrap *gomock.Call +type PackerPackMTUProbePacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PackerPackMTUProbePacketCall) Return(arg0 shortHeaderPacket, arg1 *packetBuffer, arg2 error) *PackerPackMTUProbePacketCall { + c.Call = c.Call.Return(arg0, arg1, arg2) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PackerPackMTUProbePacketCall) Do(f func(ackhandler.Frame, protocol.ByteCount, protocol.VersionNumber) (shortHeaderPacket, *packetBuffer, error)) *PackerPackMTUProbePacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PackerPackMTUProbePacketCall) DoAndReturn(f func(ackhandler.Frame, protocol.ByteCount, protocol.VersionNumber) (shortHeaderPacket, *packetBuffer, error)) *PackerPackMTUProbePacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetToken mocks base method. @@ -154,7 +322,31 @@ func (m *MockPacker) SetToken(arg0 []byte) { } // SetToken indicates an expected call of SetToken. -func (mr *MockPackerMockRecorder) SetToken(arg0 any) *gomock.Call { +func (mr *MockPackerMockRecorder) SetToken(arg0 any) *PackerSetTokenCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetToken", reflect.TypeOf((*MockPacker)(nil).SetToken), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetToken", reflect.TypeOf((*MockPacker)(nil).SetToken), arg0) + return &PackerSetTokenCall{Call: call} +} + +// PackerSetTokenCall wrap *gomock.Call +type PackerSetTokenCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PackerSetTokenCall) Return() *PackerSetTokenCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PackerSetTokenCall) Do(f func([]byte)) *PackerSetTokenCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PackerSetTokenCall) DoAndReturn(f func([]byte)) *PackerSetTokenCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_packet_handler_manager_test.go b/mock_packet_handler_manager_test.go index e8c57416a7f..fafd43c9870 100644 --- a/mock_packet_handler_manager_test.go +++ b/mock_packet_handler_manager_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager // // Package quic is a generated GoMock package. package quic @@ -47,9 +47,33 @@ func (m *MockPacketHandlerManager) Add(arg0 protocol.ConnectionID, arg1 packetHa } // Add indicates an expected call of Add. -func (mr *MockPacketHandlerManagerMockRecorder) Add(arg0, arg1 any) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) Add(arg0, arg1 any) *PacketHandlerManagerAddCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockPacketHandlerManager)(nil).Add), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockPacketHandlerManager)(nil).Add), arg0, arg1) + return &PacketHandlerManagerAddCall{Call: call} +} + +// PacketHandlerManagerAddCall wrap *gomock.Call +type PacketHandlerManagerAddCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerAddCall) Return(arg0 bool) *PacketHandlerManagerAddCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerAddCall) Do(f func(protocol.ConnectionID, packetHandler) bool) *PacketHandlerManagerAddCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerAddCall) DoAndReturn(f func(protocol.ConnectionID, packetHandler) bool) *PacketHandlerManagerAddCall { + c.Call = c.Call.DoAndReturn(f) + return c } // AddResetToken mocks base method. @@ -59,9 +83,33 @@ func (m *MockPacketHandlerManager) AddResetToken(arg0 protocol.StatelessResetTok } // AddResetToken indicates an expected call of AddResetToken. -func (mr *MockPacketHandlerManagerMockRecorder) AddResetToken(arg0, arg1 any) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) AddResetToken(arg0, arg1 any) *PacketHandlerManagerAddResetTokenCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).AddResetToken), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).AddResetToken), arg0, arg1) + return &PacketHandlerManagerAddResetTokenCall{Call: call} +} + +// PacketHandlerManagerAddResetTokenCall wrap *gomock.Call +type PacketHandlerManagerAddResetTokenCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerAddResetTokenCall) Return() *PacketHandlerManagerAddResetTokenCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerAddResetTokenCall) Do(f func(protocol.StatelessResetToken, packetHandler)) *PacketHandlerManagerAddResetTokenCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerAddResetTokenCall) DoAndReturn(f func(protocol.StatelessResetToken, packetHandler)) *PacketHandlerManagerAddResetTokenCall { + c.Call = c.Call.DoAndReturn(f) + return c } // AddWithConnID mocks base method. @@ -73,9 +121,33 @@ func (m *MockPacketHandlerManager) AddWithConnID(arg0, arg1 protocol.ConnectionI } // AddWithConnID indicates an expected call of AddWithConnID. -func (mr *MockPacketHandlerManagerMockRecorder) AddWithConnID(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) AddWithConnID(arg0, arg1, arg2 any) *PacketHandlerManagerAddWithConnIDCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWithConnID", reflect.TypeOf((*MockPacketHandlerManager)(nil).AddWithConnID), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWithConnID", reflect.TypeOf((*MockPacketHandlerManager)(nil).AddWithConnID), arg0, arg1, arg2) + return &PacketHandlerManagerAddWithConnIDCall{Call: call} +} + +// PacketHandlerManagerAddWithConnIDCall wrap *gomock.Call +type PacketHandlerManagerAddWithConnIDCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerAddWithConnIDCall) Return(arg0 bool) *PacketHandlerManagerAddWithConnIDCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerAddWithConnIDCall) Do(f func(protocol.ConnectionID, protocol.ConnectionID, func() (packetHandler, bool)) bool) *PacketHandlerManagerAddWithConnIDCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerAddWithConnIDCall) DoAndReturn(f func(protocol.ConnectionID, protocol.ConnectionID, func() (packetHandler, bool)) bool) *PacketHandlerManagerAddWithConnIDCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Close mocks base method. @@ -85,9 +157,33 @@ func (m *MockPacketHandlerManager) Close(arg0 error) { } // Close indicates an expected call of Close. -func (mr *MockPacketHandlerManagerMockRecorder) Close(arg0 any) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) Close(arg0 any) *PacketHandlerManagerCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPacketHandlerManager)(nil).Close), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPacketHandlerManager)(nil).Close), arg0) + return &PacketHandlerManagerCloseCall{Call: call} +} + +// PacketHandlerManagerCloseCall wrap *gomock.Call +type PacketHandlerManagerCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerCloseCall) Return() *PacketHandlerManagerCloseCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerCloseCall) Do(f func(error)) *PacketHandlerManagerCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerCloseCall) DoAndReturn(f func(error)) *PacketHandlerManagerCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // CloseServer mocks base method. @@ -97,9 +193,33 @@ func (m *MockPacketHandlerManager) CloseServer() { } // CloseServer indicates an expected call of CloseServer. -func (mr *MockPacketHandlerManagerMockRecorder) CloseServer() *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) CloseServer() *PacketHandlerManagerCloseServerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseServer", reflect.TypeOf((*MockPacketHandlerManager)(nil).CloseServer)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseServer", reflect.TypeOf((*MockPacketHandlerManager)(nil).CloseServer)) + return &PacketHandlerManagerCloseServerCall{Call: call} +} + +// PacketHandlerManagerCloseServerCall wrap *gomock.Call +type PacketHandlerManagerCloseServerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerCloseServerCall) Return() *PacketHandlerManagerCloseServerCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerCloseServerCall) Do(f func()) *PacketHandlerManagerCloseServerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerCloseServerCall) DoAndReturn(f func()) *PacketHandlerManagerCloseServerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Get mocks base method. @@ -112,9 +232,33 @@ func (m *MockPacketHandlerManager) Get(arg0 protocol.ConnectionID) (packetHandle } // Get indicates an expected call of Get. -func (mr *MockPacketHandlerManagerMockRecorder) Get(arg0 any) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) Get(arg0 any) *PacketHandlerManagerGetCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockPacketHandlerManager)(nil).Get), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockPacketHandlerManager)(nil).Get), arg0) + return &PacketHandlerManagerGetCall{Call: call} +} + +// PacketHandlerManagerGetCall wrap *gomock.Call +type PacketHandlerManagerGetCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerGetCall) Return(arg0 packetHandler, arg1 bool) *PacketHandlerManagerGetCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerGetCall) Do(f func(protocol.ConnectionID) (packetHandler, bool)) *PacketHandlerManagerGetCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerGetCall) DoAndReturn(f func(protocol.ConnectionID) (packetHandler, bool)) *PacketHandlerManagerGetCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetByResetToken mocks base method. @@ -127,9 +271,33 @@ func (m *MockPacketHandlerManager) GetByResetToken(arg0 protocol.StatelessResetT } // GetByResetToken indicates an expected call of GetByResetToken. -func (mr *MockPacketHandlerManagerMockRecorder) GetByResetToken(arg0 any) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) GetByResetToken(arg0 any) *PacketHandlerManagerGetByResetTokenCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).GetByResetToken), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).GetByResetToken), arg0) + return &PacketHandlerManagerGetByResetTokenCall{Call: call} +} + +// PacketHandlerManagerGetByResetTokenCall wrap *gomock.Call +type PacketHandlerManagerGetByResetTokenCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerGetByResetTokenCall) Return(arg0 packetHandler, arg1 bool) *PacketHandlerManagerGetByResetTokenCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerGetByResetTokenCall) Do(f func(protocol.StatelessResetToken) (packetHandler, bool)) *PacketHandlerManagerGetByResetTokenCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerGetByResetTokenCall) DoAndReturn(f func(protocol.StatelessResetToken) (packetHandler, bool)) *PacketHandlerManagerGetByResetTokenCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetStatelessResetToken mocks base method. @@ -141,9 +309,33 @@ func (m *MockPacketHandlerManager) GetStatelessResetToken(arg0 protocol.Connecti } // GetStatelessResetToken indicates an expected call of GetStatelessResetToken. -func (mr *MockPacketHandlerManagerMockRecorder) GetStatelessResetToken(arg0 any) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) GetStatelessResetToken(arg0 any) *PacketHandlerManagerGetStatelessResetTokenCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).GetStatelessResetToken), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).GetStatelessResetToken), arg0) + return &PacketHandlerManagerGetStatelessResetTokenCall{Call: call} +} + +// PacketHandlerManagerGetStatelessResetTokenCall wrap *gomock.Call +type PacketHandlerManagerGetStatelessResetTokenCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerGetStatelessResetTokenCall) Return(arg0 protocol.StatelessResetToken) *PacketHandlerManagerGetStatelessResetTokenCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerGetStatelessResetTokenCall) Do(f func(protocol.ConnectionID) protocol.StatelessResetToken) *PacketHandlerManagerGetStatelessResetTokenCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerGetStatelessResetTokenCall) DoAndReturn(f func(protocol.ConnectionID) protocol.StatelessResetToken) *PacketHandlerManagerGetStatelessResetTokenCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Remove mocks base method. @@ -153,9 +345,33 @@ func (m *MockPacketHandlerManager) Remove(arg0 protocol.ConnectionID) { } // Remove indicates an expected call of Remove. -func (mr *MockPacketHandlerManagerMockRecorder) Remove(arg0 any) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) Remove(arg0 any) *PacketHandlerManagerRemoveCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockPacketHandlerManager)(nil).Remove), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockPacketHandlerManager)(nil).Remove), arg0) + return &PacketHandlerManagerRemoveCall{Call: call} +} + +// PacketHandlerManagerRemoveCall wrap *gomock.Call +type PacketHandlerManagerRemoveCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerRemoveCall) Return() *PacketHandlerManagerRemoveCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerRemoveCall) Do(f func(protocol.ConnectionID)) *PacketHandlerManagerRemoveCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerRemoveCall) DoAndReturn(f func(protocol.ConnectionID)) *PacketHandlerManagerRemoveCall { + c.Call = c.Call.DoAndReturn(f) + return c } // RemoveResetToken mocks base method. @@ -165,9 +381,33 @@ func (m *MockPacketHandlerManager) RemoveResetToken(arg0 protocol.StatelessReset } // RemoveResetToken indicates an expected call of RemoveResetToken. -func (mr *MockPacketHandlerManagerMockRecorder) RemoveResetToken(arg0 any) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) RemoveResetToken(arg0 any) *PacketHandlerManagerRemoveResetTokenCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).RemoveResetToken), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveResetToken", reflect.TypeOf((*MockPacketHandlerManager)(nil).RemoveResetToken), arg0) + return &PacketHandlerManagerRemoveResetTokenCall{Call: call} +} + +// PacketHandlerManagerRemoveResetTokenCall wrap *gomock.Call +type PacketHandlerManagerRemoveResetTokenCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerRemoveResetTokenCall) Return() *PacketHandlerManagerRemoveResetTokenCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerRemoveResetTokenCall) Do(f func(protocol.StatelessResetToken)) *PacketHandlerManagerRemoveResetTokenCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerRemoveResetTokenCall) DoAndReturn(f func(protocol.StatelessResetToken)) *PacketHandlerManagerRemoveResetTokenCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReplaceWithClosed mocks base method. @@ -177,9 +417,33 @@ func (m *MockPacketHandlerManager) ReplaceWithClosed(arg0 []protocol.ConnectionI } // ReplaceWithClosed indicates an expected call of ReplaceWithClosed. -func (mr *MockPacketHandlerManagerMockRecorder) ReplaceWithClosed(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) ReplaceWithClosed(arg0, arg1, arg2 any) *PacketHandlerManagerReplaceWithClosedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceWithClosed", reflect.TypeOf((*MockPacketHandlerManager)(nil).ReplaceWithClosed), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceWithClosed", reflect.TypeOf((*MockPacketHandlerManager)(nil).ReplaceWithClosed), arg0, arg1, arg2) + return &PacketHandlerManagerReplaceWithClosedCall{Call: call} +} + +// PacketHandlerManagerReplaceWithClosedCall wrap *gomock.Call +type PacketHandlerManagerReplaceWithClosedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerReplaceWithClosedCall) Return() *PacketHandlerManagerReplaceWithClosedCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerReplaceWithClosedCall) Do(f func([]protocol.ConnectionID, protocol.Perspective, []byte)) *PacketHandlerManagerReplaceWithClosedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerReplaceWithClosedCall) DoAndReturn(f func([]protocol.ConnectionID, protocol.Perspective, []byte)) *PacketHandlerManagerReplaceWithClosedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Retire mocks base method. @@ -189,7 +453,31 @@ func (m *MockPacketHandlerManager) Retire(arg0 protocol.ConnectionID) { } // Retire indicates an expected call of Retire. -func (mr *MockPacketHandlerManagerMockRecorder) Retire(arg0 any) *gomock.Call { +func (mr *MockPacketHandlerManagerMockRecorder) Retire(arg0 any) *PacketHandlerManagerRetireCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Retire", reflect.TypeOf((*MockPacketHandlerManager)(nil).Retire), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Retire", reflect.TypeOf((*MockPacketHandlerManager)(nil).Retire), arg0) + return &PacketHandlerManagerRetireCall{Call: call} +} + +// PacketHandlerManagerRetireCall wrap *gomock.Call +type PacketHandlerManagerRetireCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerManagerRetireCall) Return() *PacketHandlerManagerRetireCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerManagerRetireCall) Do(f func(protocol.ConnectionID)) *PacketHandlerManagerRetireCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerManagerRetireCall) DoAndReturn(f func(protocol.ConnectionID)) *PacketHandlerManagerRetireCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_packet_handler_test.go b/mock_packet_handler_test.go index f30e8f0716d..ec539f15f2f 100644 --- a/mock_packet_handler_test.go +++ b/mock_packet_handler_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_test.go github.com/quic-go/quic-go PacketHandler +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_test.go github.com/quic-go/quic-go PacketHandler // // Package quic is a generated GoMock package. package quic @@ -45,9 +45,33 @@ func (m *MockPacketHandler) destroy(arg0 error) { } // destroy indicates an expected call of destroy. -func (mr *MockPacketHandlerMockRecorder) destroy(arg0 any) *gomock.Call { +func (mr *MockPacketHandlerMockRecorder) destroy(arg0 any) *PacketHandlerdestroyCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "destroy", reflect.TypeOf((*MockPacketHandler)(nil).destroy), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "destroy", reflect.TypeOf((*MockPacketHandler)(nil).destroy), arg0) + return &PacketHandlerdestroyCall{Call: call} +} + +// PacketHandlerdestroyCall wrap *gomock.Call +type PacketHandlerdestroyCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerdestroyCall) Return() *PacketHandlerdestroyCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerdestroyCall) Do(f func(error)) *PacketHandlerdestroyCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerdestroyCall) DoAndReturn(f func(error)) *PacketHandlerdestroyCall { + c.Call = c.Call.DoAndReturn(f) + return c } // getPerspective mocks base method. @@ -59,9 +83,33 @@ func (m *MockPacketHandler) getPerspective() protocol.Perspective { } // getPerspective indicates an expected call of getPerspective. -func (mr *MockPacketHandlerMockRecorder) getPerspective() *gomock.Call { +func (mr *MockPacketHandlerMockRecorder) getPerspective() *PacketHandlergetPerspectiveCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getPerspective", reflect.TypeOf((*MockPacketHandler)(nil).getPerspective)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getPerspective", reflect.TypeOf((*MockPacketHandler)(nil).getPerspective)) + return &PacketHandlergetPerspectiveCall{Call: call} +} + +// PacketHandlergetPerspectiveCall wrap *gomock.Call +type PacketHandlergetPerspectiveCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlergetPerspectiveCall) Return(arg0 protocol.Perspective) *PacketHandlergetPerspectiveCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlergetPerspectiveCall) Do(f func() protocol.Perspective) *PacketHandlergetPerspectiveCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlergetPerspectiveCall) DoAndReturn(f func() protocol.Perspective) *PacketHandlergetPerspectiveCall { + c.Call = c.Call.DoAndReturn(f) + return c } // handlePacket mocks base method. @@ -71,9 +119,33 @@ func (m *MockPacketHandler) handlePacket(arg0 receivedPacket) { } // handlePacket indicates an expected call of handlePacket. -func (mr *MockPacketHandlerMockRecorder) handlePacket(arg0 any) *gomock.Call { +func (mr *MockPacketHandlerMockRecorder) handlePacket(arg0 any) *PacketHandlerhandlePacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handlePacket", reflect.TypeOf((*MockPacketHandler)(nil).handlePacket), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handlePacket", reflect.TypeOf((*MockPacketHandler)(nil).handlePacket), arg0) + return &PacketHandlerhandlePacketCall{Call: call} +} + +// PacketHandlerhandlePacketCall wrap *gomock.Call +type PacketHandlerhandlePacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlerhandlePacketCall) Return() *PacketHandlerhandlePacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlerhandlePacketCall) Do(f func(receivedPacket)) *PacketHandlerhandlePacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlerhandlePacketCall) DoAndReturn(f func(receivedPacket)) *PacketHandlerhandlePacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // shutdown mocks base method. @@ -83,7 +155,31 @@ func (m *MockPacketHandler) shutdown() { } // shutdown indicates an expected call of shutdown. -func (mr *MockPacketHandlerMockRecorder) shutdown() *gomock.Call { +func (mr *MockPacketHandlerMockRecorder) shutdown() *PacketHandlershutdownCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "shutdown", reflect.TypeOf((*MockPacketHandler)(nil).shutdown)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "shutdown", reflect.TypeOf((*MockPacketHandler)(nil).shutdown)) + return &PacketHandlershutdownCall{Call: call} +} + +// PacketHandlershutdownCall wrap *gomock.Call +type PacketHandlershutdownCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketHandlershutdownCall) Return() *PacketHandlershutdownCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketHandlershutdownCall) Do(f func()) *PacketHandlershutdownCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketHandlershutdownCall) DoAndReturn(f func()) *PacketHandlershutdownCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_packetconn_test.go b/mock_packetconn_test.go index f148bb32cba..0af424877e0 100644 --- a/mock_packetconn_test.go +++ b/mock_packetconn_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_packetconn_test.go net PacketConn +// mockgen -typed -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_packetconn_test.go net PacketConn // // Package quic is a generated GoMock package. package quic @@ -48,9 +48,33 @@ func (m *MockPacketConn) Close() error { } // Close indicates an expected call of Close. -func (mr *MockPacketConnMockRecorder) Close() *gomock.Call { +func (mr *MockPacketConnMockRecorder) Close() *PacketConnCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPacketConn)(nil).Close)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPacketConn)(nil).Close)) + return &PacketConnCloseCall{Call: call} +} + +// PacketConnCloseCall wrap *gomock.Call +type PacketConnCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketConnCloseCall) Return(arg0 error) *PacketConnCloseCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketConnCloseCall) Do(f func() error) *PacketConnCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketConnCloseCall) DoAndReturn(f func() error) *PacketConnCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // LocalAddr mocks base method. @@ -62,9 +86,33 @@ func (m *MockPacketConn) LocalAddr() net.Addr { } // LocalAddr indicates an expected call of LocalAddr. -func (mr *MockPacketConnMockRecorder) LocalAddr() *gomock.Call { +func (mr *MockPacketConnMockRecorder) LocalAddr() *PacketConnLocalAddrCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockPacketConn)(nil).LocalAddr)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockPacketConn)(nil).LocalAddr)) + return &PacketConnLocalAddrCall{Call: call} +} + +// PacketConnLocalAddrCall wrap *gomock.Call +type PacketConnLocalAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketConnLocalAddrCall) Return(arg0 net.Addr) *PacketConnLocalAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketConnLocalAddrCall) Do(f func() net.Addr) *PacketConnLocalAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketConnLocalAddrCall) DoAndReturn(f func() net.Addr) *PacketConnLocalAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReadFrom mocks base method. @@ -78,9 +126,33 @@ func (m *MockPacketConn) ReadFrom(arg0 []byte) (int, net.Addr, error) { } // ReadFrom indicates an expected call of ReadFrom. -func (mr *MockPacketConnMockRecorder) ReadFrom(arg0 any) *gomock.Call { +func (mr *MockPacketConnMockRecorder) ReadFrom(arg0 any) *PacketConnReadFromCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadFrom", reflect.TypeOf((*MockPacketConn)(nil).ReadFrom), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadFrom", reflect.TypeOf((*MockPacketConn)(nil).ReadFrom), arg0) + return &PacketConnReadFromCall{Call: call} +} + +// PacketConnReadFromCall wrap *gomock.Call +type PacketConnReadFromCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketConnReadFromCall) Return(arg0 int, arg1 net.Addr, arg2 error) *PacketConnReadFromCall { + c.Call = c.Call.Return(arg0, arg1, arg2) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketConnReadFromCall) Do(f func([]byte) (int, net.Addr, error)) *PacketConnReadFromCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketConnReadFromCall) DoAndReturn(f func([]byte) (int, net.Addr, error)) *PacketConnReadFromCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetDeadline mocks base method. @@ -92,9 +164,33 @@ func (m *MockPacketConn) SetDeadline(arg0 time.Time) error { } // SetDeadline indicates an expected call of SetDeadline. -func (mr *MockPacketConnMockRecorder) SetDeadline(arg0 any) *gomock.Call { +func (mr *MockPacketConnMockRecorder) SetDeadline(arg0 any) *PacketConnSetDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetDeadline), arg0) + return &PacketConnSetDeadlineCall{Call: call} +} + +// PacketConnSetDeadlineCall wrap *gomock.Call +type PacketConnSetDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketConnSetDeadlineCall) Return(arg0 error) *PacketConnSetDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketConnSetDeadlineCall) Do(f func(time.Time) error) *PacketConnSetDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketConnSetDeadlineCall) DoAndReturn(f func(time.Time) error) *PacketConnSetDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetReadDeadline mocks base method. @@ -106,9 +202,33 @@ func (m *MockPacketConn) SetReadDeadline(arg0 time.Time) error { } // SetReadDeadline indicates an expected call of SetReadDeadline. -func (mr *MockPacketConnMockRecorder) SetReadDeadline(arg0 any) *gomock.Call { +func (mr *MockPacketConnMockRecorder) SetReadDeadline(arg0 any) *PacketConnSetReadDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetReadDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetReadDeadline), arg0) + return &PacketConnSetReadDeadlineCall{Call: call} +} + +// PacketConnSetReadDeadlineCall wrap *gomock.Call +type PacketConnSetReadDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketConnSetReadDeadlineCall) Return(arg0 error) *PacketConnSetReadDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketConnSetReadDeadlineCall) Do(f func(time.Time) error) *PacketConnSetReadDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketConnSetReadDeadlineCall) DoAndReturn(f func(time.Time) error) *PacketConnSetReadDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetWriteDeadline mocks base method. @@ -120,9 +240,33 @@ func (m *MockPacketConn) SetWriteDeadline(arg0 time.Time) error { } // SetWriteDeadline indicates an expected call of SetWriteDeadline. -func (mr *MockPacketConnMockRecorder) SetWriteDeadline(arg0 any) *gomock.Call { +func (mr *MockPacketConnMockRecorder) SetWriteDeadline(arg0 any) *PacketConnSetWriteDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetWriteDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetWriteDeadline), arg0) + return &PacketConnSetWriteDeadlineCall{Call: call} +} + +// PacketConnSetWriteDeadlineCall wrap *gomock.Call +type PacketConnSetWriteDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketConnSetWriteDeadlineCall) Return(arg0 error) *PacketConnSetWriteDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketConnSetWriteDeadlineCall) Do(f func(time.Time) error) *PacketConnSetWriteDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketConnSetWriteDeadlineCall) DoAndReturn(f func(time.Time) error) *PacketConnSetWriteDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // WriteTo mocks base method. @@ -135,7 +279,31 @@ func (m *MockPacketConn) WriteTo(arg0 []byte, arg1 net.Addr) (int, error) { } // WriteTo indicates an expected call of WriteTo. -func (mr *MockPacketConnMockRecorder) WriteTo(arg0, arg1 any) *gomock.Call { +func (mr *MockPacketConnMockRecorder) WriteTo(arg0, arg1 any) *PacketConnWriteToCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteTo", reflect.TypeOf((*MockPacketConn)(nil).WriteTo), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteTo", reflect.TypeOf((*MockPacketConn)(nil).WriteTo), arg0, arg1) + return &PacketConnWriteToCall{Call: call} +} + +// PacketConnWriteToCall wrap *gomock.Call +type PacketConnWriteToCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *PacketConnWriteToCall) Return(arg0 int, arg1 error) *PacketConnWriteToCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *PacketConnWriteToCall) Do(f func([]byte, net.Addr) (int, error)) *PacketConnWriteToCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *PacketConnWriteToCall) DoAndReturn(f func([]byte, net.Addr) (int, error)) *PacketConnWriteToCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_quic_conn_test.go b/mock_quic_conn_test.go index d30a939dabc..c7d84850e05 100644 --- a/mock_quic_conn_test.go +++ b/mock_quic_conn_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_quic_conn_test.go github.com/quic-go/quic-go QUICConn +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_quic_conn_test.go github.com/quic-go/quic-go QUICConn // // Package quic is a generated GoMock package. package quic @@ -51,9 +51,33 @@ func (m *MockQUICConn) AcceptStream(arg0 context.Context) (Stream, error) { } // AcceptStream indicates an expected call of AcceptStream. -func (mr *MockQUICConnMockRecorder) AcceptStream(arg0 any) *gomock.Call { +func (mr *MockQUICConnMockRecorder) AcceptStream(arg0 any) *QUICConnAcceptStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptStream", reflect.TypeOf((*MockQUICConn)(nil).AcceptStream), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptStream", reflect.TypeOf((*MockQUICConn)(nil).AcceptStream), arg0) + return &QUICConnAcceptStreamCall{Call: call} +} + +// QUICConnAcceptStreamCall wrap *gomock.Call +type QUICConnAcceptStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnAcceptStreamCall) Return(arg0 Stream, arg1 error) *QUICConnAcceptStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnAcceptStreamCall) Do(f func(context.Context) (Stream, error)) *QUICConnAcceptStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnAcceptStreamCall) DoAndReturn(f func(context.Context) (Stream, error)) *QUICConnAcceptStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // AcceptUniStream mocks base method. @@ -66,9 +90,33 @@ func (m *MockQUICConn) AcceptUniStream(arg0 context.Context) (ReceiveStream, err } // AcceptUniStream indicates an expected call of AcceptUniStream. -func (mr *MockQUICConnMockRecorder) AcceptUniStream(arg0 any) *gomock.Call { +func (mr *MockQUICConnMockRecorder) AcceptUniStream(arg0 any) *QUICConnAcceptUniStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptUniStream", reflect.TypeOf((*MockQUICConn)(nil).AcceptUniStream), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptUniStream", reflect.TypeOf((*MockQUICConn)(nil).AcceptUniStream), arg0) + return &QUICConnAcceptUniStreamCall{Call: call} +} + +// QUICConnAcceptUniStreamCall wrap *gomock.Call +type QUICConnAcceptUniStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnAcceptUniStreamCall) Return(arg0 ReceiveStream, arg1 error) *QUICConnAcceptUniStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnAcceptUniStreamCall) Do(f func(context.Context) (ReceiveStream, error)) *QUICConnAcceptUniStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnAcceptUniStreamCall) DoAndReturn(f func(context.Context) (ReceiveStream, error)) *QUICConnAcceptUniStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // CloseWithError mocks base method. @@ -80,9 +128,33 @@ func (m *MockQUICConn) CloseWithError(arg0 qerr.ApplicationErrorCode, arg1 strin } // CloseWithError indicates an expected call of CloseWithError. -func (mr *MockQUICConnMockRecorder) CloseWithError(arg0, arg1 any) *gomock.Call { +func (mr *MockQUICConnMockRecorder) CloseWithError(arg0, arg1 any) *QUICConnCloseWithErrorCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseWithError", reflect.TypeOf((*MockQUICConn)(nil).CloseWithError), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseWithError", reflect.TypeOf((*MockQUICConn)(nil).CloseWithError), arg0, arg1) + return &QUICConnCloseWithErrorCall{Call: call} +} + +// QUICConnCloseWithErrorCall wrap *gomock.Call +type QUICConnCloseWithErrorCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnCloseWithErrorCall) Return(arg0 error) *QUICConnCloseWithErrorCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnCloseWithErrorCall) Do(f func(qerr.ApplicationErrorCode, string) error) *QUICConnCloseWithErrorCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnCloseWithErrorCall) DoAndReturn(f func(qerr.ApplicationErrorCode, string) error) *QUICConnCloseWithErrorCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ConnectionState mocks base method. @@ -94,9 +166,33 @@ func (m *MockQUICConn) ConnectionState() ConnectionState { } // ConnectionState indicates an expected call of ConnectionState. -func (mr *MockQUICConnMockRecorder) ConnectionState() *gomock.Call { +func (mr *MockQUICConnMockRecorder) ConnectionState() *QUICConnConnectionStateCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectionState", reflect.TypeOf((*MockQUICConn)(nil).ConnectionState)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectionState", reflect.TypeOf((*MockQUICConn)(nil).ConnectionState)) + return &QUICConnConnectionStateCall{Call: call} +} + +// QUICConnConnectionStateCall wrap *gomock.Call +type QUICConnConnectionStateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnConnectionStateCall) Return(arg0 ConnectionState) *QUICConnConnectionStateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnConnectionStateCall) Do(f func() ConnectionState) *QUICConnConnectionStateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnConnectionStateCall) DoAndReturn(f func() ConnectionState) *QUICConnConnectionStateCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Context mocks base method. @@ -108,9 +204,33 @@ func (m *MockQUICConn) Context() context.Context { } // Context indicates an expected call of Context. -func (mr *MockQUICConnMockRecorder) Context() *gomock.Call { +func (mr *MockQUICConnMockRecorder) Context() *QUICConnContextCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockQUICConn)(nil).Context)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockQUICConn)(nil).Context)) + return &QUICConnContextCall{Call: call} +} + +// QUICConnContextCall wrap *gomock.Call +type QUICConnContextCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnContextCall) Return(arg0 context.Context) *QUICConnContextCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnContextCall) Do(f func() context.Context) *QUICConnContextCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnContextCall) DoAndReturn(f func() context.Context) *QUICConnContextCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetVersion mocks base method. @@ -122,9 +242,33 @@ func (m *MockQUICConn) GetVersion() protocol.VersionNumber { } // GetVersion indicates an expected call of GetVersion. -func (mr *MockQUICConnMockRecorder) GetVersion() *gomock.Call { +func (mr *MockQUICConnMockRecorder) GetVersion() *QUICConnGetVersionCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVersion", reflect.TypeOf((*MockQUICConn)(nil).GetVersion)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVersion", reflect.TypeOf((*MockQUICConn)(nil).GetVersion)) + return &QUICConnGetVersionCall{Call: call} +} + +// QUICConnGetVersionCall wrap *gomock.Call +type QUICConnGetVersionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnGetVersionCall) Return(arg0 protocol.VersionNumber) *QUICConnGetVersionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnGetVersionCall) Do(f func() protocol.VersionNumber) *QUICConnGetVersionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnGetVersionCall) DoAndReturn(f func() protocol.VersionNumber) *QUICConnGetVersionCall { + c.Call = c.Call.DoAndReturn(f) + return c } // HandshakeComplete mocks base method. @@ -136,9 +280,33 @@ func (m *MockQUICConn) HandshakeComplete() <-chan struct{} { } // HandshakeComplete indicates an expected call of HandshakeComplete. -func (mr *MockQUICConnMockRecorder) HandshakeComplete() *gomock.Call { +func (mr *MockQUICConnMockRecorder) HandshakeComplete() *QUICConnHandshakeCompleteCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandshakeComplete", reflect.TypeOf((*MockQUICConn)(nil).HandshakeComplete)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandshakeComplete", reflect.TypeOf((*MockQUICConn)(nil).HandshakeComplete)) + return &QUICConnHandshakeCompleteCall{Call: call} +} + +// QUICConnHandshakeCompleteCall wrap *gomock.Call +type QUICConnHandshakeCompleteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnHandshakeCompleteCall) Return(arg0 <-chan struct{}) *QUICConnHandshakeCompleteCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnHandshakeCompleteCall) Do(f func() <-chan struct{}) *QUICConnHandshakeCompleteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnHandshakeCompleteCall) DoAndReturn(f func() <-chan struct{}) *QUICConnHandshakeCompleteCall { + c.Call = c.Call.DoAndReturn(f) + return c } // LocalAddr mocks base method. @@ -150,9 +318,33 @@ func (m *MockQUICConn) LocalAddr() net.Addr { } // LocalAddr indicates an expected call of LocalAddr. -func (mr *MockQUICConnMockRecorder) LocalAddr() *gomock.Call { +func (mr *MockQUICConnMockRecorder) LocalAddr() *QUICConnLocalAddrCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockQUICConn)(nil).LocalAddr)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockQUICConn)(nil).LocalAddr)) + return &QUICConnLocalAddrCall{Call: call} +} + +// QUICConnLocalAddrCall wrap *gomock.Call +type QUICConnLocalAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnLocalAddrCall) Return(arg0 net.Addr) *QUICConnLocalAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnLocalAddrCall) Do(f func() net.Addr) *QUICConnLocalAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnLocalAddrCall) DoAndReturn(f func() net.Addr) *QUICConnLocalAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c } // NextConnection mocks base method. @@ -164,9 +356,33 @@ func (m *MockQUICConn) NextConnection() Connection { } // NextConnection indicates an expected call of NextConnection. -func (mr *MockQUICConnMockRecorder) NextConnection() *gomock.Call { +func (mr *MockQUICConnMockRecorder) NextConnection() *QUICConnNextConnectionCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NextConnection", reflect.TypeOf((*MockQUICConn)(nil).NextConnection)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NextConnection", reflect.TypeOf((*MockQUICConn)(nil).NextConnection)) + return &QUICConnNextConnectionCall{Call: call} +} + +// QUICConnNextConnectionCall wrap *gomock.Call +type QUICConnNextConnectionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnNextConnectionCall) Return(arg0 Connection) *QUICConnNextConnectionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnNextConnectionCall) Do(f func() Connection) *QUICConnNextConnectionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnNextConnectionCall) DoAndReturn(f func() Connection) *QUICConnNextConnectionCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenStream mocks base method. @@ -179,9 +395,33 @@ func (m *MockQUICConn) OpenStream() (Stream, error) { } // OpenStream indicates an expected call of OpenStream. -func (mr *MockQUICConnMockRecorder) OpenStream() *gomock.Call { +func (mr *MockQUICConnMockRecorder) OpenStream() *QUICConnOpenStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStream", reflect.TypeOf((*MockQUICConn)(nil).OpenStream)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStream", reflect.TypeOf((*MockQUICConn)(nil).OpenStream)) + return &QUICConnOpenStreamCall{Call: call} +} + +// QUICConnOpenStreamCall wrap *gomock.Call +type QUICConnOpenStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnOpenStreamCall) Return(arg0 Stream, arg1 error) *QUICConnOpenStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnOpenStreamCall) Do(f func() (Stream, error)) *QUICConnOpenStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnOpenStreamCall) DoAndReturn(f func() (Stream, error)) *QUICConnOpenStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenStreamSync mocks base method. @@ -194,9 +434,33 @@ func (m *MockQUICConn) OpenStreamSync(arg0 context.Context) (Stream, error) { } // OpenStreamSync indicates an expected call of OpenStreamSync. -func (mr *MockQUICConnMockRecorder) OpenStreamSync(arg0 any) *gomock.Call { +func (mr *MockQUICConnMockRecorder) OpenStreamSync(arg0 any) *QUICConnOpenStreamSyncCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStreamSync", reflect.TypeOf((*MockQUICConn)(nil).OpenStreamSync), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStreamSync", reflect.TypeOf((*MockQUICConn)(nil).OpenStreamSync), arg0) + return &QUICConnOpenStreamSyncCall{Call: call} +} + +// QUICConnOpenStreamSyncCall wrap *gomock.Call +type QUICConnOpenStreamSyncCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnOpenStreamSyncCall) Return(arg0 Stream, arg1 error) *QUICConnOpenStreamSyncCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnOpenStreamSyncCall) Do(f func(context.Context) (Stream, error)) *QUICConnOpenStreamSyncCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnOpenStreamSyncCall) DoAndReturn(f func(context.Context) (Stream, error)) *QUICConnOpenStreamSyncCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenUniStream mocks base method. @@ -209,9 +473,33 @@ func (m *MockQUICConn) OpenUniStream() (SendStream, error) { } // OpenUniStream indicates an expected call of OpenUniStream. -func (mr *MockQUICConnMockRecorder) OpenUniStream() *gomock.Call { +func (mr *MockQUICConnMockRecorder) OpenUniStream() *QUICConnOpenUniStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStream", reflect.TypeOf((*MockQUICConn)(nil).OpenUniStream)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStream", reflect.TypeOf((*MockQUICConn)(nil).OpenUniStream)) + return &QUICConnOpenUniStreamCall{Call: call} +} + +// QUICConnOpenUniStreamCall wrap *gomock.Call +type QUICConnOpenUniStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnOpenUniStreamCall) Return(arg0 SendStream, arg1 error) *QUICConnOpenUniStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnOpenUniStreamCall) Do(f func() (SendStream, error)) *QUICConnOpenUniStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnOpenUniStreamCall) DoAndReturn(f func() (SendStream, error)) *QUICConnOpenUniStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenUniStreamSync mocks base method. @@ -224,9 +512,33 @@ func (m *MockQUICConn) OpenUniStreamSync(arg0 context.Context) (SendStream, erro } // OpenUniStreamSync indicates an expected call of OpenUniStreamSync. -func (mr *MockQUICConnMockRecorder) OpenUniStreamSync(arg0 any) *gomock.Call { +func (mr *MockQUICConnMockRecorder) OpenUniStreamSync(arg0 any) *QUICConnOpenUniStreamSyncCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStreamSync", reflect.TypeOf((*MockQUICConn)(nil).OpenUniStreamSync), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStreamSync", reflect.TypeOf((*MockQUICConn)(nil).OpenUniStreamSync), arg0) + return &QUICConnOpenUniStreamSyncCall{Call: call} +} + +// QUICConnOpenUniStreamSyncCall wrap *gomock.Call +type QUICConnOpenUniStreamSyncCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnOpenUniStreamSyncCall) Return(arg0 SendStream, arg1 error) *QUICConnOpenUniStreamSyncCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnOpenUniStreamSyncCall) Do(f func(context.Context) (SendStream, error)) *QUICConnOpenUniStreamSyncCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnOpenUniStreamSyncCall) DoAndReturn(f func(context.Context) (SendStream, error)) *QUICConnOpenUniStreamSyncCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReceiveMessage mocks base method. @@ -239,9 +551,33 @@ func (m *MockQUICConn) ReceiveMessage(arg0 context.Context) ([]byte, error) { } // ReceiveMessage indicates an expected call of ReceiveMessage. -func (mr *MockQUICConnMockRecorder) ReceiveMessage(arg0 any) *gomock.Call { +func (mr *MockQUICConnMockRecorder) ReceiveMessage(arg0 any) *QUICConnReceiveMessageCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveMessage", reflect.TypeOf((*MockQUICConn)(nil).ReceiveMessage), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveMessage", reflect.TypeOf((*MockQUICConn)(nil).ReceiveMessage), arg0) + return &QUICConnReceiveMessageCall{Call: call} +} + +// QUICConnReceiveMessageCall wrap *gomock.Call +type QUICConnReceiveMessageCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnReceiveMessageCall) Return(arg0 []byte, arg1 error) *QUICConnReceiveMessageCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnReceiveMessageCall) Do(f func(context.Context) ([]byte, error)) *QUICConnReceiveMessageCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnReceiveMessageCall) DoAndReturn(f func(context.Context) ([]byte, error)) *QUICConnReceiveMessageCall { + c.Call = c.Call.DoAndReturn(f) + return c } // RemoteAddr mocks base method. @@ -253,9 +589,33 @@ func (m *MockQUICConn) RemoteAddr() net.Addr { } // RemoteAddr indicates an expected call of RemoteAddr. -func (mr *MockQUICConnMockRecorder) RemoteAddr() *gomock.Call { +func (mr *MockQUICConnMockRecorder) RemoteAddr() *QUICConnRemoteAddrCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockQUICConn)(nil).RemoteAddr)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockQUICConn)(nil).RemoteAddr)) + return &QUICConnRemoteAddrCall{Call: call} +} + +// QUICConnRemoteAddrCall wrap *gomock.Call +type QUICConnRemoteAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnRemoteAddrCall) Return(arg0 net.Addr) *QUICConnRemoteAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnRemoteAddrCall) Do(f func() net.Addr) *QUICConnRemoteAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnRemoteAddrCall) DoAndReturn(f func() net.Addr) *QUICConnRemoteAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SendMessage mocks base method. @@ -267,9 +627,33 @@ func (m *MockQUICConn) SendMessage(arg0 []byte) error { } // SendMessage indicates an expected call of SendMessage. -func (mr *MockQUICConnMockRecorder) SendMessage(arg0 any) *gomock.Call { +func (mr *MockQUICConnMockRecorder) SendMessage(arg0 any) *QUICConnSendMessageCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockQUICConn)(nil).SendMessage), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockQUICConn)(nil).SendMessage), arg0) + return &QUICConnSendMessageCall{Call: call} +} + +// QUICConnSendMessageCall wrap *gomock.Call +type QUICConnSendMessageCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnSendMessageCall) Return(arg0 error) *QUICConnSendMessageCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnSendMessageCall) Do(f func([]byte) error) *QUICConnSendMessageCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnSendMessageCall) DoAndReturn(f func([]byte) error) *QUICConnSendMessageCall { + c.Call = c.Call.DoAndReturn(f) + return c } // destroy mocks base method. @@ -279,9 +663,33 @@ func (m *MockQUICConn) destroy(arg0 error) { } // destroy indicates an expected call of destroy. -func (mr *MockQUICConnMockRecorder) destroy(arg0 any) *gomock.Call { +func (mr *MockQUICConnMockRecorder) destroy(arg0 any) *QUICConndestroyCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "destroy", reflect.TypeOf((*MockQUICConn)(nil).destroy), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "destroy", reflect.TypeOf((*MockQUICConn)(nil).destroy), arg0) + return &QUICConndestroyCall{Call: call} +} + +// QUICConndestroyCall wrap *gomock.Call +type QUICConndestroyCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConndestroyCall) Return() *QUICConndestroyCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConndestroyCall) Do(f func(error)) *QUICConndestroyCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConndestroyCall) DoAndReturn(f func(error)) *QUICConndestroyCall { + c.Call = c.Call.DoAndReturn(f) + return c } // earlyConnReady mocks base method. @@ -293,9 +701,33 @@ func (m *MockQUICConn) earlyConnReady() <-chan struct{} { } // earlyConnReady indicates an expected call of earlyConnReady. -func (mr *MockQUICConnMockRecorder) earlyConnReady() *gomock.Call { +func (mr *MockQUICConnMockRecorder) earlyConnReady() *QUICConnearlyConnReadyCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "earlyConnReady", reflect.TypeOf((*MockQUICConn)(nil).earlyConnReady)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "earlyConnReady", reflect.TypeOf((*MockQUICConn)(nil).earlyConnReady)) + return &QUICConnearlyConnReadyCall{Call: call} +} + +// QUICConnearlyConnReadyCall wrap *gomock.Call +type QUICConnearlyConnReadyCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnearlyConnReadyCall) Return(arg0 <-chan struct{}) *QUICConnearlyConnReadyCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnearlyConnReadyCall) Do(f func() <-chan struct{}) *QUICConnearlyConnReadyCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnearlyConnReadyCall) DoAndReturn(f func() <-chan struct{}) *QUICConnearlyConnReadyCall { + c.Call = c.Call.DoAndReturn(f) + return c } // getPerspective mocks base method. @@ -307,9 +739,33 @@ func (m *MockQUICConn) getPerspective() protocol.Perspective { } // getPerspective indicates an expected call of getPerspective. -func (mr *MockQUICConnMockRecorder) getPerspective() *gomock.Call { +func (mr *MockQUICConnMockRecorder) getPerspective() *QUICConngetPerspectiveCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getPerspective", reflect.TypeOf((*MockQUICConn)(nil).getPerspective)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getPerspective", reflect.TypeOf((*MockQUICConn)(nil).getPerspective)) + return &QUICConngetPerspectiveCall{Call: call} +} + +// QUICConngetPerspectiveCall wrap *gomock.Call +type QUICConngetPerspectiveCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConngetPerspectiveCall) Return(arg0 protocol.Perspective) *QUICConngetPerspectiveCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConngetPerspectiveCall) Do(f func() protocol.Perspective) *QUICConngetPerspectiveCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConngetPerspectiveCall) DoAndReturn(f func() protocol.Perspective) *QUICConngetPerspectiveCall { + c.Call = c.Call.DoAndReturn(f) + return c } // handlePacket mocks base method. @@ -319,9 +775,33 @@ func (m *MockQUICConn) handlePacket(arg0 receivedPacket) { } // handlePacket indicates an expected call of handlePacket. -func (mr *MockQUICConnMockRecorder) handlePacket(arg0 any) *gomock.Call { +func (mr *MockQUICConnMockRecorder) handlePacket(arg0 any) *QUICConnhandlePacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handlePacket", reflect.TypeOf((*MockQUICConn)(nil).handlePacket), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handlePacket", reflect.TypeOf((*MockQUICConn)(nil).handlePacket), arg0) + return &QUICConnhandlePacketCall{Call: call} +} + +// QUICConnhandlePacketCall wrap *gomock.Call +type QUICConnhandlePacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnhandlePacketCall) Return() *QUICConnhandlePacketCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnhandlePacketCall) Do(f func(receivedPacket)) *QUICConnhandlePacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnhandlePacketCall) DoAndReturn(f func(receivedPacket)) *QUICConnhandlePacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // run mocks base method. @@ -333,9 +813,33 @@ func (m *MockQUICConn) run() error { } // run indicates an expected call of run. -func (mr *MockQUICConnMockRecorder) run() *gomock.Call { +func (mr *MockQUICConnMockRecorder) run() *QUICConnrunCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "run", reflect.TypeOf((*MockQUICConn)(nil).run)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "run", reflect.TypeOf((*MockQUICConn)(nil).run)) + return &QUICConnrunCall{Call: call} +} + +// QUICConnrunCall wrap *gomock.Call +type QUICConnrunCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnrunCall) Return(arg0 error) *QUICConnrunCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnrunCall) Do(f func() error) *QUICConnrunCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnrunCall) DoAndReturn(f func() error) *QUICConnrunCall { + c.Call = c.Call.DoAndReturn(f) + return c } // shutdown mocks base method. @@ -345,7 +849,31 @@ func (m *MockQUICConn) shutdown() { } // shutdown indicates an expected call of shutdown. -func (mr *MockQUICConnMockRecorder) shutdown() *gomock.Call { +func (mr *MockQUICConnMockRecorder) shutdown() *QUICConnshutdownCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "shutdown", reflect.TypeOf((*MockQUICConn)(nil).shutdown)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "shutdown", reflect.TypeOf((*MockQUICConn)(nil).shutdown)) + return &QUICConnshutdownCall{Call: call} +} + +// QUICConnshutdownCall wrap *gomock.Call +type QUICConnshutdownCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *QUICConnshutdownCall) Return() *QUICConnshutdownCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *QUICConnshutdownCall) Do(f func()) *QUICConnshutdownCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *QUICConnshutdownCall) DoAndReturn(f func()) *QUICConnshutdownCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_raw_conn_test.go b/mock_raw_conn_test.go index bf4751d9dac..4d76dd16e7f 100644 --- a/mock_raw_conn_test.go +++ b/mock_raw_conn_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn // // Package quic is a generated GoMock package. package quic @@ -49,9 +49,33 @@ func (m *MockRawConn) Close() error { } // Close indicates an expected call of Close. -func (mr *MockRawConnMockRecorder) Close() *gomock.Call { +func (mr *MockRawConnMockRecorder) Close() *RawConnCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockRawConn)(nil).Close)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockRawConn)(nil).Close)) + return &RawConnCloseCall{Call: call} +} + +// RawConnCloseCall wrap *gomock.Call +type RawConnCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RawConnCloseCall) Return(arg0 error) *RawConnCloseCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RawConnCloseCall) Do(f func() error) *RawConnCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RawConnCloseCall) DoAndReturn(f func() error) *RawConnCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // LocalAddr mocks base method. @@ -63,9 +87,33 @@ func (m *MockRawConn) LocalAddr() net.Addr { } // LocalAddr indicates an expected call of LocalAddr. -func (mr *MockRawConnMockRecorder) LocalAddr() *gomock.Call { +func (mr *MockRawConnMockRecorder) LocalAddr() *RawConnLocalAddrCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockRawConn)(nil).LocalAddr)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockRawConn)(nil).LocalAddr)) + return &RawConnLocalAddrCall{Call: call} +} + +// RawConnLocalAddrCall wrap *gomock.Call +type RawConnLocalAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RawConnLocalAddrCall) Return(arg0 net.Addr) *RawConnLocalAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RawConnLocalAddrCall) Do(f func() net.Addr) *RawConnLocalAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RawConnLocalAddrCall) DoAndReturn(f func() net.Addr) *RawConnLocalAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ReadPacket mocks base method. @@ -78,9 +126,33 @@ func (m *MockRawConn) ReadPacket() (receivedPacket, error) { } // ReadPacket indicates an expected call of ReadPacket. -func (mr *MockRawConnMockRecorder) ReadPacket() *gomock.Call { +func (mr *MockRawConnMockRecorder) ReadPacket() *RawConnReadPacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadPacket", reflect.TypeOf((*MockRawConn)(nil).ReadPacket)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadPacket", reflect.TypeOf((*MockRawConn)(nil).ReadPacket)) + return &RawConnReadPacketCall{Call: call} +} + +// RawConnReadPacketCall wrap *gomock.Call +type RawConnReadPacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RawConnReadPacketCall) Return(arg0 receivedPacket, arg1 error) *RawConnReadPacketCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RawConnReadPacketCall) Do(f func() (receivedPacket, error)) *RawConnReadPacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RawConnReadPacketCall) DoAndReturn(f func() (receivedPacket, error)) *RawConnReadPacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetReadDeadline mocks base method. @@ -92,9 +164,33 @@ func (m *MockRawConn) SetReadDeadline(arg0 time.Time) error { } // SetReadDeadline indicates an expected call of SetReadDeadline. -func (mr *MockRawConnMockRecorder) SetReadDeadline(arg0 any) *gomock.Call { +func (mr *MockRawConnMockRecorder) SetReadDeadline(arg0 any) *RawConnSetReadDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockRawConn)(nil).SetReadDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockRawConn)(nil).SetReadDeadline), arg0) + return &RawConnSetReadDeadlineCall{Call: call} +} + +// RawConnSetReadDeadlineCall wrap *gomock.Call +type RawConnSetReadDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RawConnSetReadDeadlineCall) Return(arg0 error) *RawConnSetReadDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RawConnSetReadDeadlineCall) Do(f func(time.Time) error) *RawConnSetReadDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RawConnSetReadDeadlineCall) DoAndReturn(f func(time.Time) error) *RawConnSetReadDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // WritePacket mocks base method. @@ -107,9 +203,33 @@ func (m *MockRawConn) WritePacket(arg0 []byte, arg1 net.Addr, arg2 []byte, arg3 } // WritePacket indicates an expected call of WritePacket. -func (mr *MockRawConnMockRecorder) WritePacket(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { +func (mr *MockRawConnMockRecorder) WritePacket(arg0, arg1, arg2, arg3, arg4 any) *RawConnWritePacketCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePacket", reflect.TypeOf((*MockRawConn)(nil).WritePacket), arg0, arg1, arg2, arg3, arg4) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePacket", reflect.TypeOf((*MockRawConn)(nil).WritePacket), arg0, arg1, arg2, arg3, arg4) + return &RawConnWritePacketCall{Call: call} +} + +// RawConnWritePacketCall wrap *gomock.Call +type RawConnWritePacketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RawConnWritePacketCall) Return(arg0 int, arg1 error) *RawConnWritePacketCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RawConnWritePacketCall) Do(f func([]byte, net.Addr, []byte, uint16, protocol.ECN) (int, error)) *RawConnWritePacketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RawConnWritePacketCall) DoAndReturn(f func([]byte, net.Addr, []byte, uint16, protocol.ECN) (int, error)) *RawConnWritePacketCall { + c.Call = c.Call.DoAndReturn(f) + return c } // capabilities mocks base method. @@ -121,7 +241,31 @@ func (m *MockRawConn) capabilities() connCapabilities { } // capabilities indicates an expected call of capabilities. -func (mr *MockRawConnMockRecorder) capabilities() *gomock.Call { +func (mr *MockRawConnMockRecorder) capabilities() *RawConncapabilitiesCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "capabilities", reflect.TypeOf((*MockRawConn)(nil).capabilities)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "capabilities", reflect.TypeOf((*MockRawConn)(nil).capabilities)) + return &RawConncapabilitiesCall{Call: call} +} + +// RawConncapabilitiesCall wrap *gomock.Call +type RawConncapabilitiesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RawConncapabilitiesCall) Return(arg0 connCapabilities) *RawConncapabilitiesCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RawConncapabilitiesCall) Do(f func() connCapabilities) *RawConncapabilitiesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RawConncapabilitiesCall) DoAndReturn(f func() connCapabilities) *RawConncapabilitiesCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_receive_stream_internal_test.go b/mock_receive_stream_internal_test.go index 74ef3fed8dc..4d7d8b98a38 100644 --- a/mock_receive_stream_internal_test.go +++ b/mock_receive_stream_internal_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_receive_stream_internal_test.go github.com/quic-go/quic-go ReceiveStreamI +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_receive_stream_internal_test.go github.com/quic-go/quic-go ReceiveStreamI // // Package quic is a generated GoMock package. package quic @@ -48,9 +48,33 @@ func (m *MockReceiveStreamI) CancelRead(arg0 qerr.StreamErrorCode) { } // CancelRead indicates an expected call of CancelRead. -func (mr *MockReceiveStreamIMockRecorder) CancelRead(arg0 any) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) CancelRead(arg0 any) *ReceiveStreamICancelReadCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRead", reflect.TypeOf((*MockReceiveStreamI)(nil).CancelRead), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRead", reflect.TypeOf((*MockReceiveStreamI)(nil).CancelRead), arg0) + return &ReceiveStreamICancelReadCall{Call: call} +} + +// ReceiveStreamICancelReadCall wrap *gomock.Call +type ReceiveStreamICancelReadCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceiveStreamICancelReadCall) Return() *ReceiveStreamICancelReadCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceiveStreamICancelReadCall) Do(f func(qerr.StreamErrorCode)) *ReceiveStreamICancelReadCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceiveStreamICancelReadCall) DoAndReturn(f func(qerr.StreamErrorCode)) *ReceiveStreamICancelReadCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Read mocks base method. @@ -63,9 +87,33 @@ func (m *MockReceiveStreamI) Read(arg0 []byte) (int, error) { } // Read indicates an expected call of Read. -func (mr *MockReceiveStreamIMockRecorder) Read(arg0 any) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) Read(arg0 any) *ReceiveStreamIReadCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockReceiveStreamI)(nil).Read), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockReceiveStreamI)(nil).Read), arg0) + return &ReceiveStreamIReadCall{Call: call} +} + +// ReceiveStreamIReadCall wrap *gomock.Call +type ReceiveStreamIReadCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceiveStreamIReadCall) Return(arg0 int, arg1 error) *ReceiveStreamIReadCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceiveStreamIReadCall) Do(f func([]byte) (int, error)) *ReceiveStreamIReadCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceiveStreamIReadCall) DoAndReturn(f func([]byte) (int, error)) *ReceiveStreamIReadCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetReadDeadline mocks base method. @@ -77,9 +125,33 @@ func (m *MockReceiveStreamI) SetReadDeadline(arg0 time.Time) error { } // SetReadDeadline indicates an expected call of SetReadDeadline. -func (mr *MockReceiveStreamIMockRecorder) SetReadDeadline(arg0 any) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) SetReadDeadline(arg0 any) *ReceiveStreamISetReadDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockReceiveStreamI)(nil).SetReadDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockReceiveStreamI)(nil).SetReadDeadline), arg0) + return &ReceiveStreamISetReadDeadlineCall{Call: call} +} + +// ReceiveStreamISetReadDeadlineCall wrap *gomock.Call +type ReceiveStreamISetReadDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceiveStreamISetReadDeadlineCall) Return(arg0 error) *ReceiveStreamISetReadDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceiveStreamISetReadDeadlineCall) Do(f func(time.Time) error) *ReceiveStreamISetReadDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceiveStreamISetReadDeadlineCall) DoAndReturn(f func(time.Time) error) *ReceiveStreamISetReadDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // StreamID mocks base method. @@ -91,9 +163,33 @@ func (m *MockReceiveStreamI) StreamID() protocol.StreamID { } // StreamID indicates an expected call of StreamID. -func (mr *MockReceiveStreamIMockRecorder) StreamID() *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) StreamID() *ReceiveStreamIStreamIDCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamID", reflect.TypeOf((*MockReceiveStreamI)(nil).StreamID)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamID", reflect.TypeOf((*MockReceiveStreamI)(nil).StreamID)) + return &ReceiveStreamIStreamIDCall{Call: call} +} + +// ReceiveStreamIStreamIDCall wrap *gomock.Call +type ReceiveStreamIStreamIDCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceiveStreamIStreamIDCall) Return(arg0 protocol.StreamID) *ReceiveStreamIStreamIDCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceiveStreamIStreamIDCall) Do(f func() protocol.StreamID) *ReceiveStreamIStreamIDCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceiveStreamIStreamIDCall) DoAndReturn(f func() protocol.StreamID) *ReceiveStreamIStreamIDCall { + c.Call = c.Call.DoAndReturn(f) + return c } // closeForShutdown mocks base method. @@ -103,9 +199,33 @@ func (m *MockReceiveStreamI) closeForShutdown(arg0 error) { } // closeForShutdown indicates an expected call of closeForShutdown. -func (mr *MockReceiveStreamIMockRecorder) closeForShutdown(arg0 any) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) closeForShutdown(arg0 any) *ReceiveStreamIcloseForShutdownCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "closeForShutdown", reflect.TypeOf((*MockReceiveStreamI)(nil).closeForShutdown), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "closeForShutdown", reflect.TypeOf((*MockReceiveStreamI)(nil).closeForShutdown), arg0) + return &ReceiveStreamIcloseForShutdownCall{Call: call} +} + +// ReceiveStreamIcloseForShutdownCall wrap *gomock.Call +type ReceiveStreamIcloseForShutdownCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceiveStreamIcloseForShutdownCall) Return() *ReceiveStreamIcloseForShutdownCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceiveStreamIcloseForShutdownCall) Do(f func(error)) *ReceiveStreamIcloseForShutdownCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceiveStreamIcloseForShutdownCall) DoAndReturn(f func(error)) *ReceiveStreamIcloseForShutdownCall { + c.Call = c.Call.DoAndReturn(f) + return c } // getWindowUpdate mocks base method. @@ -117,9 +237,33 @@ func (m *MockReceiveStreamI) getWindowUpdate() protocol.ByteCount { } // getWindowUpdate indicates an expected call of getWindowUpdate. -func (mr *MockReceiveStreamIMockRecorder) getWindowUpdate() *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) getWindowUpdate() *ReceiveStreamIgetWindowUpdateCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getWindowUpdate", reflect.TypeOf((*MockReceiveStreamI)(nil).getWindowUpdate)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getWindowUpdate", reflect.TypeOf((*MockReceiveStreamI)(nil).getWindowUpdate)) + return &ReceiveStreamIgetWindowUpdateCall{Call: call} +} + +// ReceiveStreamIgetWindowUpdateCall wrap *gomock.Call +type ReceiveStreamIgetWindowUpdateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceiveStreamIgetWindowUpdateCall) Return(arg0 protocol.ByteCount) *ReceiveStreamIgetWindowUpdateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceiveStreamIgetWindowUpdateCall) Do(f func() protocol.ByteCount) *ReceiveStreamIgetWindowUpdateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceiveStreamIgetWindowUpdateCall) DoAndReturn(f func() protocol.ByteCount) *ReceiveStreamIgetWindowUpdateCall { + c.Call = c.Call.DoAndReturn(f) + return c } // handleResetStreamFrame mocks base method. @@ -131,9 +275,33 @@ func (m *MockReceiveStreamI) handleResetStreamFrame(arg0 *wire.ResetStreamFrame) } // handleResetStreamFrame indicates an expected call of handleResetStreamFrame. -func (mr *MockReceiveStreamIMockRecorder) handleResetStreamFrame(arg0 any) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) handleResetStreamFrame(arg0 any) *ReceiveStreamIhandleResetStreamFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleResetStreamFrame", reflect.TypeOf((*MockReceiveStreamI)(nil).handleResetStreamFrame), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleResetStreamFrame", reflect.TypeOf((*MockReceiveStreamI)(nil).handleResetStreamFrame), arg0) + return &ReceiveStreamIhandleResetStreamFrameCall{Call: call} +} + +// ReceiveStreamIhandleResetStreamFrameCall wrap *gomock.Call +type ReceiveStreamIhandleResetStreamFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceiveStreamIhandleResetStreamFrameCall) Return(arg0 error) *ReceiveStreamIhandleResetStreamFrameCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceiveStreamIhandleResetStreamFrameCall) Do(f func(*wire.ResetStreamFrame) error) *ReceiveStreamIhandleResetStreamFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceiveStreamIhandleResetStreamFrameCall) DoAndReturn(f func(*wire.ResetStreamFrame) error) *ReceiveStreamIhandleResetStreamFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } // handleStreamFrame mocks base method. @@ -145,7 +313,31 @@ func (m *MockReceiveStreamI) handleStreamFrame(arg0 *wire.StreamFrame) error { } // handleStreamFrame indicates an expected call of handleStreamFrame. -func (mr *MockReceiveStreamIMockRecorder) handleStreamFrame(arg0 any) *gomock.Call { +func (mr *MockReceiveStreamIMockRecorder) handleStreamFrame(arg0 any) *ReceiveStreamIhandleStreamFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStreamFrame", reflect.TypeOf((*MockReceiveStreamI)(nil).handleStreamFrame), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStreamFrame", reflect.TypeOf((*MockReceiveStreamI)(nil).handleStreamFrame), arg0) + return &ReceiveStreamIhandleStreamFrameCall{Call: call} +} + +// ReceiveStreamIhandleStreamFrameCall wrap *gomock.Call +type ReceiveStreamIhandleStreamFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ReceiveStreamIhandleStreamFrameCall) Return(arg0 error) *ReceiveStreamIhandleStreamFrameCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ReceiveStreamIhandleStreamFrameCall) Do(f func(*wire.StreamFrame) error) *ReceiveStreamIhandleStreamFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ReceiveStreamIhandleStreamFrameCall) DoAndReturn(f func(*wire.StreamFrame) error) *ReceiveStreamIhandleStreamFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_sealing_manager_test.go b/mock_sealing_manager_test.go index c8ecaad238e..aea943bc7b0 100644 --- a/mock_sealing_manager_test.go +++ b/mock_sealing_manager_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_sealing_manager_test.go github.com/quic-go/quic-go SealingManager +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_sealing_manager_test.go github.com/quic-go/quic-go SealingManager // // Package quic is a generated GoMock package. package quic @@ -48,9 +48,33 @@ func (m *MockSealingManager) Get0RTTSealer() (handshake.LongHeaderSealer, error) } // Get0RTTSealer indicates an expected call of Get0RTTSealer. -func (mr *MockSealingManagerMockRecorder) Get0RTTSealer() *gomock.Call { +func (mr *MockSealingManagerMockRecorder) Get0RTTSealer() *SealingManagerGet0RTTSealerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get0RTTSealer", reflect.TypeOf((*MockSealingManager)(nil).Get0RTTSealer)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get0RTTSealer", reflect.TypeOf((*MockSealingManager)(nil).Get0RTTSealer)) + return &SealingManagerGet0RTTSealerCall{Call: call} +} + +// SealingManagerGet0RTTSealerCall wrap *gomock.Call +type SealingManagerGet0RTTSealerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SealingManagerGet0RTTSealerCall) Return(arg0 handshake.LongHeaderSealer, arg1 error) *SealingManagerGet0RTTSealerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SealingManagerGet0RTTSealerCall) Do(f func() (handshake.LongHeaderSealer, error)) *SealingManagerGet0RTTSealerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SealingManagerGet0RTTSealerCall) DoAndReturn(f func() (handshake.LongHeaderSealer, error)) *SealingManagerGet0RTTSealerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Get1RTTSealer mocks base method. @@ -63,9 +87,33 @@ func (m *MockSealingManager) Get1RTTSealer() (handshake.ShortHeaderSealer, error } // Get1RTTSealer indicates an expected call of Get1RTTSealer. -func (mr *MockSealingManagerMockRecorder) Get1RTTSealer() *gomock.Call { +func (mr *MockSealingManagerMockRecorder) Get1RTTSealer() *SealingManagerGet1RTTSealerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get1RTTSealer", reflect.TypeOf((*MockSealingManager)(nil).Get1RTTSealer)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get1RTTSealer", reflect.TypeOf((*MockSealingManager)(nil).Get1RTTSealer)) + return &SealingManagerGet1RTTSealerCall{Call: call} +} + +// SealingManagerGet1RTTSealerCall wrap *gomock.Call +type SealingManagerGet1RTTSealerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SealingManagerGet1RTTSealerCall) Return(arg0 handshake.ShortHeaderSealer, arg1 error) *SealingManagerGet1RTTSealerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SealingManagerGet1RTTSealerCall) Do(f func() (handshake.ShortHeaderSealer, error)) *SealingManagerGet1RTTSealerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SealingManagerGet1RTTSealerCall) DoAndReturn(f func() (handshake.ShortHeaderSealer, error)) *SealingManagerGet1RTTSealerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetHandshakeSealer mocks base method. @@ -78,9 +126,33 @@ func (m *MockSealingManager) GetHandshakeSealer() (handshake.LongHeaderSealer, e } // GetHandshakeSealer indicates an expected call of GetHandshakeSealer. -func (mr *MockSealingManagerMockRecorder) GetHandshakeSealer() *gomock.Call { +func (mr *MockSealingManagerMockRecorder) GetHandshakeSealer() *SealingManagerGetHandshakeSealerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHandshakeSealer", reflect.TypeOf((*MockSealingManager)(nil).GetHandshakeSealer)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHandshakeSealer", reflect.TypeOf((*MockSealingManager)(nil).GetHandshakeSealer)) + return &SealingManagerGetHandshakeSealerCall{Call: call} +} + +// SealingManagerGetHandshakeSealerCall wrap *gomock.Call +type SealingManagerGetHandshakeSealerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SealingManagerGetHandshakeSealerCall) Return(arg0 handshake.LongHeaderSealer, arg1 error) *SealingManagerGetHandshakeSealerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SealingManagerGetHandshakeSealerCall) Do(f func() (handshake.LongHeaderSealer, error)) *SealingManagerGetHandshakeSealerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SealingManagerGetHandshakeSealerCall) DoAndReturn(f func() (handshake.LongHeaderSealer, error)) *SealingManagerGetHandshakeSealerCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetInitialSealer mocks base method. @@ -93,7 +165,31 @@ func (m *MockSealingManager) GetInitialSealer() (handshake.LongHeaderSealer, err } // GetInitialSealer indicates an expected call of GetInitialSealer. -func (mr *MockSealingManagerMockRecorder) GetInitialSealer() *gomock.Call { +func (mr *MockSealingManagerMockRecorder) GetInitialSealer() *SealingManagerGetInitialSealerCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInitialSealer", reflect.TypeOf((*MockSealingManager)(nil).GetInitialSealer)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInitialSealer", reflect.TypeOf((*MockSealingManager)(nil).GetInitialSealer)) + return &SealingManagerGetInitialSealerCall{Call: call} +} + +// SealingManagerGetInitialSealerCall wrap *gomock.Call +type SealingManagerGetInitialSealerCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SealingManagerGetInitialSealerCall) Return(arg0 handshake.LongHeaderSealer, arg1 error) *SealingManagerGetInitialSealerCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SealingManagerGetInitialSealerCall) Do(f func() (handshake.LongHeaderSealer, error)) *SealingManagerGetInitialSealerCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SealingManagerGetInitialSealerCall) DoAndReturn(f func() (handshake.LongHeaderSealer, error)) *SealingManagerGetInitialSealerCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_send_conn_test.go b/mock_send_conn_test.go index 407c798b89c..d949584151a 100644 --- a/mock_send_conn_test.go +++ b/mock_send_conn_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn // // Package quic is a generated GoMock package. package quic @@ -48,9 +48,33 @@ func (m *MockSendConn) Close() error { } // Close indicates an expected call of Close. -func (mr *MockSendConnMockRecorder) Close() *gomock.Call { +func (mr *MockSendConnMockRecorder) Close() *SendConnCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSendConn)(nil).Close)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSendConn)(nil).Close)) + return &SendConnCloseCall{Call: call} +} + +// SendConnCloseCall wrap *gomock.Call +type SendConnCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendConnCloseCall) Return(arg0 error) *SendConnCloseCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendConnCloseCall) Do(f func() error) *SendConnCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendConnCloseCall) DoAndReturn(f func() error) *SendConnCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // LocalAddr mocks base method. @@ -62,9 +86,33 @@ func (m *MockSendConn) LocalAddr() net.Addr { } // LocalAddr indicates an expected call of LocalAddr. -func (mr *MockSendConnMockRecorder) LocalAddr() *gomock.Call { +func (mr *MockSendConnMockRecorder) LocalAddr() *SendConnLocalAddrCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockSendConn)(nil).LocalAddr)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockSendConn)(nil).LocalAddr)) + return &SendConnLocalAddrCall{Call: call} +} + +// SendConnLocalAddrCall wrap *gomock.Call +type SendConnLocalAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendConnLocalAddrCall) Return(arg0 net.Addr) *SendConnLocalAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendConnLocalAddrCall) Do(f func() net.Addr) *SendConnLocalAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendConnLocalAddrCall) DoAndReturn(f func() net.Addr) *SendConnLocalAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c } // RemoteAddr mocks base method. @@ -76,9 +124,33 @@ func (m *MockSendConn) RemoteAddr() net.Addr { } // RemoteAddr indicates an expected call of RemoteAddr. -func (mr *MockSendConnMockRecorder) RemoteAddr() *gomock.Call { +func (mr *MockSendConnMockRecorder) RemoteAddr() *SendConnRemoteAddrCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockSendConn)(nil).RemoteAddr)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockSendConn)(nil).RemoteAddr)) + return &SendConnRemoteAddrCall{Call: call} +} + +// SendConnRemoteAddrCall wrap *gomock.Call +type SendConnRemoteAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendConnRemoteAddrCall) Return(arg0 net.Addr) *SendConnRemoteAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendConnRemoteAddrCall) Do(f func() net.Addr) *SendConnRemoteAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendConnRemoteAddrCall) DoAndReturn(f func() net.Addr) *SendConnRemoteAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Write mocks base method. @@ -90,9 +162,33 @@ func (m *MockSendConn) Write(arg0 []byte, arg1 uint16, arg2 protocol.ECN) error } // Write indicates an expected call of Write. -func (mr *MockSendConnMockRecorder) Write(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockSendConnMockRecorder) Write(arg0, arg1, arg2 any) *SendConnWriteCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendConn)(nil).Write), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendConn)(nil).Write), arg0, arg1, arg2) + return &SendConnWriteCall{Call: call} +} + +// SendConnWriteCall wrap *gomock.Call +type SendConnWriteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendConnWriteCall) Return(arg0 error) *SendConnWriteCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendConnWriteCall) Do(f func([]byte, uint16, protocol.ECN) error) *SendConnWriteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendConnWriteCall) DoAndReturn(f func([]byte, uint16, protocol.ECN) error) *SendConnWriteCall { + c.Call = c.Call.DoAndReturn(f) + return c } // capabilities mocks base method. @@ -104,7 +200,31 @@ func (m *MockSendConn) capabilities() connCapabilities { } // capabilities indicates an expected call of capabilities. -func (mr *MockSendConnMockRecorder) capabilities() *gomock.Call { +func (mr *MockSendConnMockRecorder) capabilities() *SendConncapabilitiesCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "capabilities", reflect.TypeOf((*MockSendConn)(nil).capabilities)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "capabilities", reflect.TypeOf((*MockSendConn)(nil).capabilities)) + return &SendConncapabilitiesCall{Call: call} +} + +// SendConncapabilitiesCall wrap *gomock.Call +type SendConncapabilitiesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendConncapabilitiesCall) Return(arg0 connCapabilities) *SendConncapabilitiesCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendConncapabilitiesCall) Do(f func() connCapabilities) *SendConncapabilitiesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendConncapabilitiesCall) DoAndReturn(f func() connCapabilities) *SendConncapabilitiesCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_send_stream_internal_test.go b/mock_send_stream_internal_test.go index ded44a85a1e..53093155ccd 100644 --- a/mock_send_stream_internal_test.go +++ b/mock_send_stream_internal_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_send_stream_internal_test.go github.com/quic-go/quic-go SendStreamI +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_send_stream_internal_test.go github.com/quic-go/quic-go SendStreamI // // Package quic is a generated GoMock package. package quic @@ -50,9 +50,33 @@ func (m *MockSendStreamI) CancelWrite(arg0 qerr.StreamErrorCode) { } // CancelWrite indicates an expected call of CancelWrite. -func (mr *MockSendStreamIMockRecorder) CancelWrite(arg0 any) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) CancelWrite(arg0 any) *SendStreamICancelWriteCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelWrite", reflect.TypeOf((*MockSendStreamI)(nil).CancelWrite), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelWrite", reflect.TypeOf((*MockSendStreamI)(nil).CancelWrite), arg0) + return &SendStreamICancelWriteCall{Call: call} +} + +// SendStreamICancelWriteCall wrap *gomock.Call +type SendStreamICancelWriteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendStreamICancelWriteCall) Return() *SendStreamICancelWriteCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendStreamICancelWriteCall) Do(f func(qerr.StreamErrorCode)) *SendStreamICancelWriteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendStreamICancelWriteCall) DoAndReturn(f func(qerr.StreamErrorCode)) *SendStreamICancelWriteCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Close mocks base method. @@ -64,9 +88,33 @@ func (m *MockSendStreamI) Close() error { } // Close indicates an expected call of Close. -func (mr *MockSendStreamIMockRecorder) Close() *gomock.Call { +func (mr *MockSendStreamIMockRecorder) Close() *SendStreamICloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSendStreamI)(nil).Close)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSendStreamI)(nil).Close)) + return &SendStreamICloseCall{Call: call} +} + +// SendStreamICloseCall wrap *gomock.Call +type SendStreamICloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendStreamICloseCall) Return(arg0 error) *SendStreamICloseCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendStreamICloseCall) Do(f func() error) *SendStreamICloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendStreamICloseCall) DoAndReturn(f func() error) *SendStreamICloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Context mocks base method. @@ -78,9 +126,33 @@ func (m *MockSendStreamI) Context() context.Context { } // Context indicates an expected call of Context. -func (mr *MockSendStreamIMockRecorder) Context() *gomock.Call { +func (mr *MockSendStreamIMockRecorder) Context() *SendStreamIContextCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockSendStreamI)(nil).Context)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockSendStreamI)(nil).Context)) + return &SendStreamIContextCall{Call: call} +} + +// SendStreamIContextCall wrap *gomock.Call +type SendStreamIContextCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendStreamIContextCall) Return(arg0 context.Context) *SendStreamIContextCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendStreamIContextCall) Do(f func() context.Context) *SendStreamIContextCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendStreamIContextCall) DoAndReturn(f func() context.Context) *SendStreamIContextCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetWriteDeadline mocks base method. @@ -92,9 +164,33 @@ func (m *MockSendStreamI) SetWriteDeadline(arg0 time.Time) error { } // SetWriteDeadline indicates an expected call of SetWriteDeadline. -func (mr *MockSendStreamIMockRecorder) SetWriteDeadline(arg0 any) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) SetWriteDeadline(arg0 any) *SendStreamISetWriteDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockSendStreamI)(nil).SetWriteDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockSendStreamI)(nil).SetWriteDeadline), arg0) + return &SendStreamISetWriteDeadlineCall{Call: call} +} + +// SendStreamISetWriteDeadlineCall wrap *gomock.Call +type SendStreamISetWriteDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendStreamISetWriteDeadlineCall) Return(arg0 error) *SendStreamISetWriteDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendStreamISetWriteDeadlineCall) Do(f func(time.Time) error) *SendStreamISetWriteDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendStreamISetWriteDeadlineCall) DoAndReturn(f func(time.Time) error) *SendStreamISetWriteDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // StreamID mocks base method. @@ -106,9 +202,33 @@ func (m *MockSendStreamI) StreamID() protocol.StreamID { } // StreamID indicates an expected call of StreamID. -func (mr *MockSendStreamIMockRecorder) StreamID() *gomock.Call { +func (mr *MockSendStreamIMockRecorder) StreamID() *SendStreamIStreamIDCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamID", reflect.TypeOf((*MockSendStreamI)(nil).StreamID)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamID", reflect.TypeOf((*MockSendStreamI)(nil).StreamID)) + return &SendStreamIStreamIDCall{Call: call} +} + +// SendStreamIStreamIDCall wrap *gomock.Call +type SendStreamIStreamIDCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendStreamIStreamIDCall) Return(arg0 protocol.StreamID) *SendStreamIStreamIDCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendStreamIStreamIDCall) Do(f func() protocol.StreamID) *SendStreamIStreamIDCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendStreamIStreamIDCall) DoAndReturn(f func() protocol.StreamID) *SendStreamIStreamIDCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Write mocks base method. @@ -121,9 +241,33 @@ func (m *MockSendStreamI) Write(arg0 []byte) (int, error) { } // Write indicates an expected call of Write. -func (mr *MockSendStreamIMockRecorder) Write(arg0 any) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) Write(arg0 any) *SendStreamIWriteCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendStreamI)(nil).Write), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendStreamI)(nil).Write), arg0) + return &SendStreamIWriteCall{Call: call} +} + +// SendStreamIWriteCall wrap *gomock.Call +type SendStreamIWriteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendStreamIWriteCall) Return(arg0 int, arg1 error) *SendStreamIWriteCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendStreamIWriteCall) Do(f func([]byte) (int, error)) *SendStreamIWriteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendStreamIWriteCall) DoAndReturn(f func([]byte) (int, error)) *SendStreamIWriteCall { + c.Call = c.Call.DoAndReturn(f) + return c } // closeForShutdown mocks base method. @@ -133,9 +277,33 @@ func (m *MockSendStreamI) closeForShutdown(arg0 error) { } // closeForShutdown indicates an expected call of closeForShutdown. -func (mr *MockSendStreamIMockRecorder) closeForShutdown(arg0 any) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) closeForShutdown(arg0 any) *SendStreamIcloseForShutdownCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "closeForShutdown", reflect.TypeOf((*MockSendStreamI)(nil).closeForShutdown), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "closeForShutdown", reflect.TypeOf((*MockSendStreamI)(nil).closeForShutdown), arg0) + return &SendStreamIcloseForShutdownCall{Call: call} +} + +// SendStreamIcloseForShutdownCall wrap *gomock.Call +type SendStreamIcloseForShutdownCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendStreamIcloseForShutdownCall) Return() *SendStreamIcloseForShutdownCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendStreamIcloseForShutdownCall) Do(f func(error)) *SendStreamIcloseForShutdownCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendStreamIcloseForShutdownCall) DoAndReturn(f func(error)) *SendStreamIcloseForShutdownCall { + c.Call = c.Call.DoAndReturn(f) + return c } // handleStopSendingFrame mocks base method. @@ -145,9 +313,33 @@ func (m *MockSendStreamI) handleStopSendingFrame(arg0 *wire.StopSendingFrame) { } // handleStopSendingFrame indicates an expected call of handleStopSendingFrame. -func (mr *MockSendStreamIMockRecorder) handleStopSendingFrame(arg0 any) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) handleStopSendingFrame(arg0 any) *SendStreamIhandleStopSendingFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStopSendingFrame", reflect.TypeOf((*MockSendStreamI)(nil).handleStopSendingFrame), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStopSendingFrame", reflect.TypeOf((*MockSendStreamI)(nil).handleStopSendingFrame), arg0) + return &SendStreamIhandleStopSendingFrameCall{Call: call} +} + +// SendStreamIhandleStopSendingFrameCall wrap *gomock.Call +type SendStreamIhandleStopSendingFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendStreamIhandleStopSendingFrameCall) Return() *SendStreamIhandleStopSendingFrameCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendStreamIhandleStopSendingFrameCall) Do(f func(*wire.StopSendingFrame)) *SendStreamIhandleStopSendingFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendStreamIhandleStopSendingFrameCall) DoAndReturn(f func(*wire.StopSendingFrame)) *SendStreamIhandleStopSendingFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } // hasData mocks base method. @@ -159,9 +351,33 @@ func (m *MockSendStreamI) hasData() bool { } // hasData indicates an expected call of hasData. -func (mr *MockSendStreamIMockRecorder) hasData() *gomock.Call { +func (mr *MockSendStreamIMockRecorder) hasData() *SendStreamIhasDataCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "hasData", reflect.TypeOf((*MockSendStreamI)(nil).hasData)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "hasData", reflect.TypeOf((*MockSendStreamI)(nil).hasData)) + return &SendStreamIhasDataCall{Call: call} +} + +// SendStreamIhasDataCall wrap *gomock.Call +type SendStreamIhasDataCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendStreamIhasDataCall) Return(arg0 bool) *SendStreamIhasDataCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendStreamIhasDataCall) Do(f func() bool) *SendStreamIhasDataCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendStreamIhasDataCall) DoAndReturn(f func() bool) *SendStreamIhasDataCall { + c.Call = c.Call.DoAndReturn(f) + return c } // popStreamFrame mocks base method. @@ -175,9 +391,33 @@ func (m *MockSendStreamI) popStreamFrame(arg0 protocol.ByteCount, arg1 protocol. } // popStreamFrame indicates an expected call of popStreamFrame. -func (mr *MockSendStreamIMockRecorder) popStreamFrame(arg0, arg1 any) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) popStreamFrame(arg0, arg1 any) *SendStreamIpopStreamFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "popStreamFrame", reflect.TypeOf((*MockSendStreamI)(nil).popStreamFrame), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "popStreamFrame", reflect.TypeOf((*MockSendStreamI)(nil).popStreamFrame), arg0, arg1) + return &SendStreamIpopStreamFrameCall{Call: call} +} + +// SendStreamIpopStreamFrameCall wrap *gomock.Call +type SendStreamIpopStreamFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendStreamIpopStreamFrameCall) Return(arg0 ackhandler.StreamFrame, arg1, arg2 bool) *SendStreamIpopStreamFrameCall { + c.Call = c.Call.Return(arg0, arg1, arg2) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendStreamIpopStreamFrameCall) Do(f func(protocol.ByteCount, protocol.VersionNumber) (ackhandler.StreamFrame, bool, bool)) *SendStreamIpopStreamFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendStreamIpopStreamFrameCall) DoAndReturn(f func(protocol.ByteCount, protocol.VersionNumber) (ackhandler.StreamFrame, bool, bool)) *SendStreamIpopStreamFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } // updateSendWindow mocks base method. @@ -187,7 +427,31 @@ func (m *MockSendStreamI) updateSendWindow(arg0 protocol.ByteCount) { } // updateSendWindow indicates an expected call of updateSendWindow. -func (mr *MockSendStreamIMockRecorder) updateSendWindow(arg0 any) *gomock.Call { +func (mr *MockSendStreamIMockRecorder) updateSendWindow(arg0 any) *SendStreamIupdateSendWindowCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "updateSendWindow", reflect.TypeOf((*MockSendStreamI)(nil).updateSendWindow), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "updateSendWindow", reflect.TypeOf((*MockSendStreamI)(nil).updateSendWindow), arg0) + return &SendStreamIupdateSendWindowCall{Call: call} +} + +// SendStreamIupdateSendWindowCall wrap *gomock.Call +type SendStreamIupdateSendWindowCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SendStreamIupdateSendWindowCall) Return() *SendStreamIupdateSendWindowCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SendStreamIupdateSendWindowCall) Do(f func(protocol.ByteCount)) *SendStreamIupdateSendWindowCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SendStreamIupdateSendWindowCall) DoAndReturn(f func(protocol.ByteCount)) *SendStreamIupdateSendWindowCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_sender_test.go b/mock_sender_test.go index 2565a8fa7d6..aa3c8780637 100644 --- a/mock_sender_test.go +++ b/mock_sender_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender // // Package quic is a generated GoMock package. package quic @@ -47,9 +47,33 @@ func (m *MockSender) Available() <-chan struct{} { } // Available indicates an expected call of Available. -func (mr *MockSenderMockRecorder) Available() *gomock.Call { +func (mr *MockSenderMockRecorder) Available() *SenderAvailableCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Available", reflect.TypeOf((*MockSender)(nil).Available)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Available", reflect.TypeOf((*MockSender)(nil).Available)) + return &SenderAvailableCall{Call: call} +} + +// SenderAvailableCall wrap *gomock.Call +type SenderAvailableCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SenderAvailableCall) Return(arg0 <-chan struct{}) *SenderAvailableCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SenderAvailableCall) Do(f func() <-chan struct{}) *SenderAvailableCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SenderAvailableCall) DoAndReturn(f func() <-chan struct{}) *SenderAvailableCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Close mocks base method. @@ -59,9 +83,33 @@ func (m *MockSender) Close() { } // Close indicates an expected call of Close. -func (mr *MockSenderMockRecorder) Close() *gomock.Call { +func (mr *MockSenderMockRecorder) Close() *SenderCloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSender)(nil).Close)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSender)(nil).Close)) + return &SenderCloseCall{Call: call} +} + +// SenderCloseCall wrap *gomock.Call +type SenderCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SenderCloseCall) Return() *SenderCloseCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SenderCloseCall) Do(f func()) *SenderCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SenderCloseCall) DoAndReturn(f func()) *SenderCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Run mocks base method. @@ -73,9 +121,33 @@ func (m *MockSender) Run() error { } // Run indicates an expected call of Run. -func (mr *MockSenderMockRecorder) Run() *gomock.Call { +func (mr *MockSenderMockRecorder) Run() *SenderRunCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockSender)(nil).Run)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockSender)(nil).Run)) + return &SenderRunCall{Call: call} +} + +// SenderRunCall wrap *gomock.Call +type SenderRunCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SenderRunCall) Return(arg0 error) *SenderRunCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SenderRunCall) Do(f func() error) *SenderRunCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SenderRunCall) DoAndReturn(f func() error) *SenderRunCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Send mocks base method. @@ -85,9 +157,33 @@ func (m *MockSender) Send(arg0 *packetBuffer, arg1 uint16, arg2 protocol.ECN) { } // Send indicates an expected call of Send. -func (mr *MockSenderMockRecorder) Send(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockSenderMockRecorder) Send(arg0, arg1, arg2 any) *SenderSendCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockSender)(nil).Send), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockSender)(nil).Send), arg0, arg1, arg2) + return &SenderSendCall{Call: call} +} + +// SenderSendCall wrap *gomock.Call +type SenderSendCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SenderSendCall) Return() *SenderSendCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SenderSendCall) Do(f func(*packetBuffer, uint16, protocol.ECN)) *SenderSendCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SenderSendCall) DoAndReturn(f func(*packetBuffer, uint16, protocol.ECN)) *SenderSendCall { + c.Call = c.Call.DoAndReturn(f) + return c } // WouldBlock mocks base method. @@ -99,7 +195,31 @@ func (m *MockSender) WouldBlock() bool { } // WouldBlock indicates an expected call of WouldBlock. -func (mr *MockSenderMockRecorder) WouldBlock() *gomock.Call { +func (mr *MockSenderMockRecorder) WouldBlock() *SenderWouldBlockCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WouldBlock", reflect.TypeOf((*MockSender)(nil).WouldBlock)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WouldBlock", reflect.TypeOf((*MockSender)(nil).WouldBlock)) + return &SenderWouldBlockCall{Call: call} +} + +// SenderWouldBlockCall wrap *gomock.Call +type SenderWouldBlockCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SenderWouldBlockCall) Return(arg0 bool) *SenderWouldBlockCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SenderWouldBlockCall) Do(f func() bool) *SenderWouldBlockCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SenderWouldBlockCall) DoAndReturn(f func() bool) *SenderWouldBlockCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_stream_getter_test.go b/mock_stream_getter_test.go index d0acde1d6f6..dc3270f6ead 100644 --- a/mock_stream_getter_test.go +++ b/mock_stream_getter_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_getter_test.go github.com/quic-go/quic-go StreamGetter +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_getter_test.go github.com/quic-go/quic-go StreamGetter // // Package quic is a generated GoMock package. package quic @@ -48,9 +48,33 @@ func (m *MockStreamGetter) GetOrOpenReceiveStream(arg0 protocol.StreamID) (recei } // GetOrOpenReceiveStream indicates an expected call of GetOrOpenReceiveStream. -func (mr *MockStreamGetterMockRecorder) GetOrOpenReceiveStream(arg0 any) *gomock.Call { +func (mr *MockStreamGetterMockRecorder) GetOrOpenReceiveStream(arg0 any) *StreamGetterGetOrOpenReceiveStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenReceiveStream", reflect.TypeOf((*MockStreamGetter)(nil).GetOrOpenReceiveStream), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenReceiveStream", reflect.TypeOf((*MockStreamGetter)(nil).GetOrOpenReceiveStream), arg0) + return &StreamGetterGetOrOpenReceiveStreamCall{Call: call} +} + +// StreamGetterGetOrOpenReceiveStreamCall wrap *gomock.Call +type StreamGetterGetOrOpenReceiveStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamGetterGetOrOpenReceiveStreamCall) Return(arg0 receiveStreamI, arg1 error) *StreamGetterGetOrOpenReceiveStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamGetterGetOrOpenReceiveStreamCall) Do(f func(protocol.StreamID) (receiveStreamI, error)) *StreamGetterGetOrOpenReceiveStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamGetterGetOrOpenReceiveStreamCall) DoAndReturn(f func(protocol.StreamID) (receiveStreamI, error)) *StreamGetterGetOrOpenReceiveStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetOrOpenSendStream mocks base method. @@ -63,7 +87,31 @@ func (m *MockStreamGetter) GetOrOpenSendStream(arg0 protocol.StreamID) (sendStre } // GetOrOpenSendStream indicates an expected call of GetOrOpenSendStream. -func (mr *MockStreamGetterMockRecorder) GetOrOpenSendStream(arg0 any) *gomock.Call { +func (mr *MockStreamGetterMockRecorder) GetOrOpenSendStream(arg0 any) *StreamGetterGetOrOpenSendStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenSendStream", reflect.TypeOf((*MockStreamGetter)(nil).GetOrOpenSendStream), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenSendStream", reflect.TypeOf((*MockStreamGetter)(nil).GetOrOpenSendStream), arg0) + return &StreamGetterGetOrOpenSendStreamCall{Call: call} +} + +// StreamGetterGetOrOpenSendStreamCall wrap *gomock.Call +type StreamGetterGetOrOpenSendStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamGetterGetOrOpenSendStreamCall) Return(arg0 sendStreamI, arg1 error) *StreamGetterGetOrOpenSendStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamGetterGetOrOpenSendStreamCall) Do(f func(protocol.StreamID) (sendStreamI, error)) *StreamGetterGetOrOpenSendStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamGetterGetOrOpenSendStreamCall) DoAndReturn(f func(protocol.StreamID) (sendStreamI, error)) *StreamGetterGetOrOpenSendStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_stream_internal_test.go b/mock_stream_internal_test.go index 9121a46178c..21ba4f06187 100644 --- a/mock_stream_internal_test.go +++ b/mock_stream_internal_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_internal_test.go github.com/quic-go/quic-go StreamI +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_internal_test.go github.com/quic-go/quic-go StreamI // // Package quic is a generated GoMock package. package quic @@ -50,9 +50,33 @@ func (m *MockStreamI) CancelRead(arg0 qerr.StreamErrorCode) { } // CancelRead indicates an expected call of CancelRead. -func (mr *MockStreamIMockRecorder) CancelRead(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) CancelRead(arg0 any) *StreamICancelReadCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRead", reflect.TypeOf((*MockStreamI)(nil).CancelRead), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRead", reflect.TypeOf((*MockStreamI)(nil).CancelRead), arg0) + return &StreamICancelReadCall{Call: call} +} + +// StreamICancelReadCall wrap *gomock.Call +type StreamICancelReadCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamICancelReadCall) Return() *StreamICancelReadCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamICancelReadCall) Do(f func(qerr.StreamErrorCode)) *StreamICancelReadCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamICancelReadCall) DoAndReturn(f func(qerr.StreamErrorCode)) *StreamICancelReadCall { + c.Call = c.Call.DoAndReturn(f) + return c } // CancelWrite mocks base method. @@ -62,9 +86,33 @@ func (m *MockStreamI) CancelWrite(arg0 qerr.StreamErrorCode) { } // CancelWrite indicates an expected call of CancelWrite. -func (mr *MockStreamIMockRecorder) CancelWrite(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) CancelWrite(arg0 any) *StreamICancelWriteCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelWrite", reflect.TypeOf((*MockStreamI)(nil).CancelWrite), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelWrite", reflect.TypeOf((*MockStreamI)(nil).CancelWrite), arg0) + return &StreamICancelWriteCall{Call: call} +} + +// StreamICancelWriteCall wrap *gomock.Call +type StreamICancelWriteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamICancelWriteCall) Return() *StreamICancelWriteCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamICancelWriteCall) Do(f func(qerr.StreamErrorCode)) *StreamICancelWriteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamICancelWriteCall) DoAndReturn(f func(qerr.StreamErrorCode)) *StreamICancelWriteCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Close mocks base method. @@ -76,9 +124,33 @@ func (m *MockStreamI) Close() error { } // Close indicates an expected call of Close. -func (mr *MockStreamIMockRecorder) Close() *gomock.Call { +func (mr *MockStreamIMockRecorder) Close() *StreamICloseCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockStreamI)(nil).Close)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockStreamI)(nil).Close)) + return &StreamICloseCall{Call: call} +} + +// StreamICloseCall wrap *gomock.Call +type StreamICloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamICloseCall) Return(arg0 error) *StreamICloseCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamICloseCall) Do(f func() error) *StreamICloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamICloseCall) DoAndReturn(f func() error) *StreamICloseCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Context mocks base method. @@ -90,9 +162,33 @@ func (m *MockStreamI) Context() context.Context { } // Context indicates an expected call of Context. -func (mr *MockStreamIMockRecorder) Context() *gomock.Call { +func (mr *MockStreamIMockRecorder) Context() *StreamIContextCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockStreamI)(nil).Context)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockStreamI)(nil).Context)) + return &StreamIContextCall{Call: call} +} + +// StreamIContextCall wrap *gomock.Call +type StreamIContextCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIContextCall) Return(arg0 context.Context) *StreamIContextCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIContextCall) Do(f func() context.Context) *StreamIContextCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIContextCall) DoAndReturn(f func() context.Context) *StreamIContextCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Read mocks base method. @@ -105,9 +201,33 @@ func (m *MockStreamI) Read(arg0 []byte) (int, error) { } // Read indicates an expected call of Read. -func (mr *MockStreamIMockRecorder) Read(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) Read(arg0 any) *StreamIReadCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStreamI)(nil).Read), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStreamI)(nil).Read), arg0) + return &StreamIReadCall{Call: call} +} + +// StreamIReadCall wrap *gomock.Call +type StreamIReadCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIReadCall) Return(arg0 int, arg1 error) *StreamIReadCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIReadCall) Do(f func([]byte) (int, error)) *StreamIReadCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIReadCall) DoAndReturn(f func([]byte) (int, error)) *StreamIReadCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetDeadline mocks base method. @@ -119,9 +239,33 @@ func (m *MockStreamI) SetDeadline(arg0 time.Time) error { } // SetDeadline indicates an expected call of SetDeadline. -func (mr *MockStreamIMockRecorder) SetDeadline(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) SetDeadline(arg0 any) *StreamISetDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStreamI)(nil).SetDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStreamI)(nil).SetDeadline), arg0) + return &StreamISetDeadlineCall{Call: call} +} + +// StreamISetDeadlineCall wrap *gomock.Call +type StreamISetDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamISetDeadlineCall) Return(arg0 error) *StreamISetDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamISetDeadlineCall) Do(f func(time.Time) error) *StreamISetDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamISetDeadlineCall) DoAndReturn(f func(time.Time) error) *StreamISetDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetReadDeadline mocks base method. @@ -133,9 +277,33 @@ func (m *MockStreamI) SetReadDeadline(arg0 time.Time) error { } // SetReadDeadline indicates an expected call of SetReadDeadline. -func (mr *MockStreamIMockRecorder) SetReadDeadline(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) SetReadDeadline(arg0 any) *StreamISetReadDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStreamI)(nil).SetReadDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStreamI)(nil).SetReadDeadline), arg0) + return &StreamISetReadDeadlineCall{Call: call} +} + +// StreamISetReadDeadlineCall wrap *gomock.Call +type StreamISetReadDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamISetReadDeadlineCall) Return(arg0 error) *StreamISetReadDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamISetReadDeadlineCall) Do(f func(time.Time) error) *StreamISetReadDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamISetReadDeadlineCall) DoAndReturn(f func(time.Time) error) *StreamISetReadDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // SetWriteDeadline mocks base method. @@ -147,9 +315,33 @@ func (m *MockStreamI) SetWriteDeadline(arg0 time.Time) error { } // SetWriteDeadline indicates an expected call of SetWriteDeadline. -func (mr *MockStreamIMockRecorder) SetWriteDeadline(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) SetWriteDeadline(arg0 any) *StreamISetWriteDeadlineCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStreamI)(nil).SetWriteDeadline), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStreamI)(nil).SetWriteDeadline), arg0) + return &StreamISetWriteDeadlineCall{Call: call} +} + +// StreamISetWriteDeadlineCall wrap *gomock.Call +type StreamISetWriteDeadlineCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamISetWriteDeadlineCall) Return(arg0 error) *StreamISetWriteDeadlineCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamISetWriteDeadlineCall) Do(f func(time.Time) error) *StreamISetWriteDeadlineCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamISetWriteDeadlineCall) DoAndReturn(f func(time.Time) error) *StreamISetWriteDeadlineCall { + c.Call = c.Call.DoAndReturn(f) + return c } // StreamID mocks base method. @@ -161,9 +353,33 @@ func (m *MockStreamI) StreamID() protocol.StreamID { } // StreamID indicates an expected call of StreamID. -func (mr *MockStreamIMockRecorder) StreamID() *gomock.Call { +func (mr *MockStreamIMockRecorder) StreamID() *StreamIStreamIDCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamID", reflect.TypeOf((*MockStreamI)(nil).StreamID)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamID", reflect.TypeOf((*MockStreamI)(nil).StreamID)) + return &StreamIStreamIDCall{Call: call} +} + +// StreamIStreamIDCall wrap *gomock.Call +type StreamIStreamIDCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIStreamIDCall) Return(arg0 protocol.StreamID) *StreamIStreamIDCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIStreamIDCall) Do(f func() protocol.StreamID) *StreamIStreamIDCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIStreamIDCall) DoAndReturn(f func() protocol.StreamID) *StreamIStreamIDCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Write mocks base method. @@ -176,9 +392,33 @@ func (m *MockStreamI) Write(arg0 []byte) (int, error) { } // Write indicates an expected call of Write. -func (mr *MockStreamIMockRecorder) Write(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) Write(arg0 any) *StreamIWriteCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStreamI)(nil).Write), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStreamI)(nil).Write), arg0) + return &StreamIWriteCall{Call: call} +} + +// StreamIWriteCall wrap *gomock.Call +type StreamIWriteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIWriteCall) Return(arg0 int, arg1 error) *StreamIWriteCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIWriteCall) Do(f func([]byte) (int, error)) *StreamIWriteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIWriteCall) DoAndReturn(f func([]byte) (int, error)) *StreamIWriteCall { + c.Call = c.Call.DoAndReturn(f) + return c } // closeForShutdown mocks base method. @@ -188,9 +428,33 @@ func (m *MockStreamI) closeForShutdown(arg0 error) { } // closeForShutdown indicates an expected call of closeForShutdown. -func (mr *MockStreamIMockRecorder) closeForShutdown(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) closeForShutdown(arg0 any) *StreamIcloseForShutdownCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "closeForShutdown", reflect.TypeOf((*MockStreamI)(nil).closeForShutdown), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "closeForShutdown", reflect.TypeOf((*MockStreamI)(nil).closeForShutdown), arg0) + return &StreamIcloseForShutdownCall{Call: call} +} + +// StreamIcloseForShutdownCall wrap *gomock.Call +type StreamIcloseForShutdownCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIcloseForShutdownCall) Return() *StreamIcloseForShutdownCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIcloseForShutdownCall) Do(f func(error)) *StreamIcloseForShutdownCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIcloseForShutdownCall) DoAndReturn(f func(error)) *StreamIcloseForShutdownCall { + c.Call = c.Call.DoAndReturn(f) + return c } // getWindowUpdate mocks base method. @@ -202,9 +466,33 @@ func (m *MockStreamI) getWindowUpdate() protocol.ByteCount { } // getWindowUpdate indicates an expected call of getWindowUpdate. -func (mr *MockStreamIMockRecorder) getWindowUpdate() *gomock.Call { +func (mr *MockStreamIMockRecorder) getWindowUpdate() *StreamIgetWindowUpdateCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getWindowUpdate", reflect.TypeOf((*MockStreamI)(nil).getWindowUpdate)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getWindowUpdate", reflect.TypeOf((*MockStreamI)(nil).getWindowUpdate)) + return &StreamIgetWindowUpdateCall{Call: call} +} + +// StreamIgetWindowUpdateCall wrap *gomock.Call +type StreamIgetWindowUpdateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIgetWindowUpdateCall) Return(arg0 protocol.ByteCount) *StreamIgetWindowUpdateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIgetWindowUpdateCall) Do(f func() protocol.ByteCount) *StreamIgetWindowUpdateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIgetWindowUpdateCall) DoAndReturn(f func() protocol.ByteCount) *StreamIgetWindowUpdateCall { + c.Call = c.Call.DoAndReturn(f) + return c } // handleResetStreamFrame mocks base method. @@ -216,9 +504,33 @@ func (m *MockStreamI) handleResetStreamFrame(arg0 *wire.ResetStreamFrame) error } // handleResetStreamFrame indicates an expected call of handleResetStreamFrame. -func (mr *MockStreamIMockRecorder) handleResetStreamFrame(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) handleResetStreamFrame(arg0 any) *StreamIhandleResetStreamFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleResetStreamFrame", reflect.TypeOf((*MockStreamI)(nil).handleResetStreamFrame), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleResetStreamFrame", reflect.TypeOf((*MockStreamI)(nil).handleResetStreamFrame), arg0) + return &StreamIhandleResetStreamFrameCall{Call: call} +} + +// StreamIhandleResetStreamFrameCall wrap *gomock.Call +type StreamIhandleResetStreamFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIhandleResetStreamFrameCall) Return(arg0 error) *StreamIhandleResetStreamFrameCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIhandleResetStreamFrameCall) Do(f func(*wire.ResetStreamFrame) error) *StreamIhandleResetStreamFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIhandleResetStreamFrameCall) DoAndReturn(f func(*wire.ResetStreamFrame) error) *StreamIhandleResetStreamFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } // handleStopSendingFrame mocks base method. @@ -228,9 +540,33 @@ func (m *MockStreamI) handleStopSendingFrame(arg0 *wire.StopSendingFrame) { } // handleStopSendingFrame indicates an expected call of handleStopSendingFrame. -func (mr *MockStreamIMockRecorder) handleStopSendingFrame(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) handleStopSendingFrame(arg0 any) *StreamIhandleStopSendingFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStopSendingFrame", reflect.TypeOf((*MockStreamI)(nil).handleStopSendingFrame), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStopSendingFrame", reflect.TypeOf((*MockStreamI)(nil).handleStopSendingFrame), arg0) + return &StreamIhandleStopSendingFrameCall{Call: call} +} + +// StreamIhandleStopSendingFrameCall wrap *gomock.Call +type StreamIhandleStopSendingFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIhandleStopSendingFrameCall) Return() *StreamIhandleStopSendingFrameCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIhandleStopSendingFrameCall) Do(f func(*wire.StopSendingFrame)) *StreamIhandleStopSendingFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIhandleStopSendingFrameCall) DoAndReturn(f func(*wire.StopSendingFrame)) *StreamIhandleStopSendingFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } // handleStreamFrame mocks base method. @@ -242,9 +578,33 @@ func (m *MockStreamI) handleStreamFrame(arg0 *wire.StreamFrame) error { } // handleStreamFrame indicates an expected call of handleStreamFrame. -func (mr *MockStreamIMockRecorder) handleStreamFrame(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) handleStreamFrame(arg0 any) *StreamIhandleStreamFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStreamFrame", reflect.TypeOf((*MockStreamI)(nil).handleStreamFrame), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "handleStreamFrame", reflect.TypeOf((*MockStreamI)(nil).handleStreamFrame), arg0) + return &StreamIhandleStreamFrameCall{Call: call} +} + +// StreamIhandleStreamFrameCall wrap *gomock.Call +type StreamIhandleStreamFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIhandleStreamFrameCall) Return(arg0 error) *StreamIhandleStreamFrameCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIhandleStreamFrameCall) Do(f func(*wire.StreamFrame) error) *StreamIhandleStreamFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIhandleStreamFrameCall) DoAndReturn(f func(*wire.StreamFrame) error) *StreamIhandleStreamFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } // hasData mocks base method. @@ -256,9 +616,33 @@ func (m *MockStreamI) hasData() bool { } // hasData indicates an expected call of hasData. -func (mr *MockStreamIMockRecorder) hasData() *gomock.Call { +func (mr *MockStreamIMockRecorder) hasData() *StreamIhasDataCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "hasData", reflect.TypeOf((*MockStreamI)(nil).hasData)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "hasData", reflect.TypeOf((*MockStreamI)(nil).hasData)) + return &StreamIhasDataCall{Call: call} +} + +// StreamIhasDataCall wrap *gomock.Call +type StreamIhasDataCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIhasDataCall) Return(arg0 bool) *StreamIhasDataCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIhasDataCall) Do(f func() bool) *StreamIhasDataCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIhasDataCall) DoAndReturn(f func() bool) *StreamIhasDataCall { + c.Call = c.Call.DoAndReturn(f) + return c } // popStreamFrame mocks base method. @@ -272,9 +656,33 @@ func (m *MockStreamI) popStreamFrame(arg0 protocol.ByteCount, arg1 protocol.Vers } // popStreamFrame indicates an expected call of popStreamFrame. -func (mr *MockStreamIMockRecorder) popStreamFrame(arg0, arg1 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) popStreamFrame(arg0, arg1 any) *StreamIpopStreamFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "popStreamFrame", reflect.TypeOf((*MockStreamI)(nil).popStreamFrame), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "popStreamFrame", reflect.TypeOf((*MockStreamI)(nil).popStreamFrame), arg0, arg1) + return &StreamIpopStreamFrameCall{Call: call} +} + +// StreamIpopStreamFrameCall wrap *gomock.Call +type StreamIpopStreamFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIpopStreamFrameCall) Return(arg0 ackhandler.StreamFrame, arg1, arg2 bool) *StreamIpopStreamFrameCall { + c.Call = c.Call.Return(arg0, arg1, arg2) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIpopStreamFrameCall) Do(f func(protocol.ByteCount, protocol.VersionNumber) (ackhandler.StreamFrame, bool, bool)) *StreamIpopStreamFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIpopStreamFrameCall) DoAndReturn(f func(protocol.ByteCount, protocol.VersionNumber) (ackhandler.StreamFrame, bool, bool)) *StreamIpopStreamFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } // updateSendWindow mocks base method. @@ -284,7 +692,31 @@ func (m *MockStreamI) updateSendWindow(arg0 protocol.ByteCount) { } // updateSendWindow indicates an expected call of updateSendWindow. -func (mr *MockStreamIMockRecorder) updateSendWindow(arg0 any) *gomock.Call { +func (mr *MockStreamIMockRecorder) updateSendWindow(arg0 any) *StreamIupdateSendWindowCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "updateSendWindow", reflect.TypeOf((*MockStreamI)(nil).updateSendWindow), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "updateSendWindow", reflect.TypeOf((*MockStreamI)(nil).updateSendWindow), arg0) + return &StreamIupdateSendWindowCall{Call: call} +} + +// StreamIupdateSendWindowCall wrap *gomock.Call +type StreamIupdateSendWindowCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamIupdateSendWindowCall) Return() *StreamIupdateSendWindowCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamIupdateSendWindowCall) Do(f func(protocol.ByteCount)) *StreamIupdateSendWindowCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamIupdateSendWindowCall) DoAndReturn(f func(protocol.ByteCount)) *StreamIupdateSendWindowCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_stream_manager_test.go b/mock_stream_manager_test.go index 3dacd419b94..62ecf6329da 100644 --- a/mock_stream_manager_test.go +++ b/mock_stream_manager_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_manager_test.go github.com/quic-go/quic-go StreamManager +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_manager_test.go github.com/quic-go/quic-go StreamManager // // Package quic is a generated GoMock package. package quic @@ -50,9 +50,33 @@ func (m *MockStreamManager) AcceptStream(arg0 context.Context) (Stream, error) { } // AcceptStream indicates an expected call of AcceptStream. -func (mr *MockStreamManagerMockRecorder) AcceptStream(arg0 any) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) AcceptStream(arg0 any) *StreamManagerAcceptStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptStream", reflect.TypeOf((*MockStreamManager)(nil).AcceptStream), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptStream", reflect.TypeOf((*MockStreamManager)(nil).AcceptStream), arg0) + return &StreamManagerAcceptStreamCall{Call: call} +} + +// StreamManagerAcceptStreamCall wrap *gomock.Call +type StreamManagerAcceptStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerAcceptStreamCall) Return(arg0 Stream, arg1 error) *StreamManagerAcceptStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerAcceptStreamCall) Do(f func(context.Context) (Stream, error)) *StreamManagerAcceptStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerAcceptStreamCall) DoAndReturn(f func(context.Context) (Stream, error)) *StreamManagerAcceptStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // AcceptUniStream mocks base method. @@ -65,9 +89,33 @@ func (m *MockStreamManager) AcceptUniStream(arg0 context.Context) (ReceiveStream } // AcceptUniStream indicates an expected call of AcceptUniStream. -func (mr *MockStreamManagerMockRecorder) AcceptUniStream(arg0 any) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) AcceptUniStream(arg0 any) *StreamManagerAcceptUniStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptUniStream", reflect.TypeOf((*MockStreamManager)(nil).AcceptUniStream), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptUniStream", reflect.TypeOf((*MockStreamManager)(nil).AcceptUniStream), arg0) + return &StreamManagerAcceptUniStreamCall{Call: call} +} + +// StreamManagerAcceptUniStreamCall wrap *gomock.Call +type StreamManagerAcceptUniStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerAcceptUniStreamCall) Return(arg0 ReceiveStream, arg1 error) *StreamManagerAcceptUniStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerAcceptUniStreamCall) Do(f func(context.Context) (ReceiveStream, error)) *StreamManagerAcceptUniStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerAcceptUniStreamCall) DoAndReturn(f func(context.Context) (ReceiveStream, error)) *StreamManagerAcceptUniStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // CloseWithError mocks base method. @@ -77,9 +125,33 @@ func (m *MockStreamManager) CloseWithError(arg0 error) { } // CloseWithError indicates an expected call of CloseWithError. -func (mr *MockStreamManagerMockRecorder) CloseWithError(arg0 any) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) CloseWithError(arg0 any) *StreamManagerCloseWithErrorCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseWithError", reflect.TypeOf((*MockStreamManager)(nil).CloseWithError), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseWithError", reflect.TypeOf((*MockStreamManager)(nil).CloseWithError), arg0) + return &StreamManagerCloseWithErrorCall{Call: call} +} + +// StreamManagerCloseWithErrorCall wrap *gomock.Call +type StreamManagerCloseWithErrorCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerCloseWithErrorCall) Return() *StreamManagerCloseWithErrorCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerCloseWithErrorCall) Do(f func(error)) *StreamManagerCloseWithErrorCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerCloseWithErrorCall) DoAndReturn(f func(error)) *StreamManagerCloseWithErrorCall { + c.Call = c.Call.DoAndReturn(f) + return c } // DeleteStream mocks base method. @@ -91,9 +163,33 @@ func (m *MockStreamManager) DeleteStream(arg0 protocol.StreamID) error { } // DeleteStream indicates an expected call of DeleteStream. -func (mr *MockStreamManagerMockRecorder) DeleteStream(arg0 any) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) DeleteStream(arg0 any) *StreamManagerDeleteStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStream", reflect.TypeOf((*MockStreamManager)(nil).DeleteStream), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStream", reflect.TypeOf((*MockStreamManager)(nil).DeleteStream), arg0) + return &StreamManagerDeleteStreamCall{Call: call} +} + +// StreamManagerDeleteStreamCall wrap *gomock.Call +type StreamManagerDeleteStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerDeleteStreamCall) Return(arg0 error) *StreamManagerDeleteStreamCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerDeleteStreamCall) Do(f func(protocol.StreamID) error) *StreamManagerDeleteStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerDeleteStreamCall) DoAndReturn(f func(protocol.StreamID) error) *StreamManagerDeleteStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetOrOpenReceiveStream mocks base method. @@ -106,9 +202,33 @@ func (m *MockStreamManager) GetOrOpenReceiveStream(arg0 protocol.StreamID) (rece } // GetOrOpenReceiveStream indicates an expected call of GetOrOpenReceiveStream. -func (mr *MockStreamManagerMockRecorder) GetOrOpenReceiveStream(arg0 any) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) GetOrOpenReceiveStream(arg0 any) *StreamManagerGetOrOpenReceiveStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenReceiveStream", reflect.TypeOf((*MockStreamManager)(nil).GetOrOpenReceiveStream), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenReceiveStream", reflect.TypeOf((*MockStreamManager)(nil).GetOrOpenReceiveStream), arg0) + return &StreamManagerGetOrOpenReceiveStreamCall{Call: call} +} + +// StreamManagerGetOrOpenReceiveStreamCall wrap *gomock.Call +type StreamManagerGetOrOpenReceiveStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerGetOrOpenReceiveStreamCall) Return(arg0 receiveStreamI, arg1 error) *StreamManagerGetOrOpenReceiveStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerGetOrOpenReceiveStreamCall) Do(f func(protocol.StreamID) (receiveStreamI, error)) *StreamManagerGetOrOpenReceiveStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerGetOrOpenReceiveStreamCall) DoAndReturn(f func(protocol.StreamID) (receiveStreamI, error)) *StreamManagerGetOrOpenReceiveStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // GetOrOpenSendStream mocks base method. @@ -121,9 +241,33 @@ func (m *MockStreamManager) GetOrOpenSendStream(arg0 protocol.StreamID) (sendStr } // GetOrOpenSendStream indicates an expected call of GetOrOpenSendStream. -func (mr *MockStreamManagerMockRecorder) GetOrOpenSendStream(arg0 any) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) GetOrOpenSendStream(arg0 any) *StreamManagerGetOrOpenSendStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenSendStream", reflect.TypeOf((*MockStreamManager)(nil).GetOrOpenSendStream), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrOpenSendStream", reflect.TypeOf((*MockStreamManager)(nil).GetOrOpenSendStream), arg0) + return &StreamManagerGetOrOpenSendStreamCall{Call: call} +} + +// StreamManagerGetOrOpenSendStreamCall wrap *gomock.Call +type StreamManagerGetOrOpenSendStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerGetOrOpenSendStreamCall) Return(arg0 sendStreamI, arg1 error) *StreamManagerGetOrOpenSendStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerGetOrOpenSendStreamCall) Do(f func(protocol.StreamID) (sendStreamI, error)) *StreamManagerGetOrOpenSendStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerGetOrOpenSendStreamCall) DoAndReturn(f func(protocol.StreamID) (sendStreamI, error)) *StreamManagerGetOrOpenSendStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // HandleMaxStreamsFrame mocks base method. @@ -133,9 +277,33 @@ func (m *MockStreamManager) HandleMaxStreamsFrame(arg0 *wire.MaxStreamsFrame) { } // HandleMaxStreamsFrame indicates an expected call of HandleMaxStreamsFrame. -func (mr *MockStreamManagerMockRecorder) HandleMaxStreamsFrame(arg0 any) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) HandleMaxStreamsFrame(arg0 any) *StreamManagerHandleMaxStreamsFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMaxStreamsFrame", reflect.TypeOf((*MockStreamManager)(nil).HandleMaxStreamsFrame), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMaxStreamsFrame", reflect.TypeOf((*MockStreamManager)(nil).HandleMaxStreamsFrame), arg0) + return &StreamManagerHandleMaxStreamsFrameCall{Call: call} +} + +// StreamManagerHandleMaxStreamsFrameCall wrap *gomock.Call +type StreamManagerHandleMaxStreamsFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerHandleMaxStreamsFrameCall) Return() *StreamManagerHandleMaxStreamsFrameCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerHandleMaxStreamsFrameCall) Do(f func(*wire.MaxStreamsFrame)) *StreamManagerHandleMaxStreamsFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerHandleMaxStreamsFrameCall) DoAndReturn(f func(*wire.MaxStreamsFrame)) *StreamManagerHandleMaxStreamsFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenStream mocks base method. @@ -148,9 +316,33 @@ func (m *MockStreamManager) OpenStream() (Stream, error) { } // OpenStream indicates an expected call of OpenStream. -func (mr *MockStreamManagerMockRecorder) OpenStream() *gomock.Call { +func (mr *MockStreamManagerMockRecorder) OpenStream() *StreamManagerOpenStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStream", reflect.TypeOf((*MockStreamManager)(nil).OpenStream)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStream", reflect.TypeOf((*MockStreamManager)(nil).OpenStream)) + return &StreamManagerOpenStreamCall{Call: call} +} + +// StreamManagerOpenStreamCall wrap *gomock.Call +type StreamManagerOpenStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerOpenStreamCall) Return(arg0 Stream, arg1 error) *StreamManagerOpenStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerOpenStreamCall) Do(f func() (Stream, error)) *StreamManagerOpenStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerOpenStreamCall) DoAndReturn(f func() (Stream, error)) *StreamManagerOpenStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenStreamSync mocks base method. @@ -163,9 +355,33 @@ func (m *MockStreamManager) OpenStreamSync(arg0 context.Context) (Stream, error) } // OpenStreamSync indicates an expected call of OpenStreamSync. -func (mr *MockStreamManagerMockRecorder) OpenStreamSync(arg0 any) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) OpenStreamSync(arg0 any) *StreamManagerOpenStreamSyncCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStreamSync", reflect.TypeOf((*MockStreamManager)(nil).OpenStreamSync), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStreamSync", reflect.TypeOf((*MockStreamManager)(nil).OpenStreamSync), arg0) + return &StreamManagerOpenStreamSyncCall{Call: call} +} + +// StreamManagerOpenStreamSyncCall wrap *gomock.Call +type StreamManagerOpenStreamSyncCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerOpenStreamSyncCall) Return(arg0 Stream, arg1 error) *StreamManagerOpenStreamSyncCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerOpenStreamSyncCall) Do(f func(context.Context) (Stream, error)) *StreamManagerOpenStreamSyncCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerOpenStreamSyncCall) DoAndReturn(f func(context.Context) (Stream, error)) *StreamManagerOpenStreamSyncCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenUniStream mocks base method. @@ -178,9 +394,33 @@ func (m *MockStreamManager) OpenUniStream() (SendStream, error) { } // OpenUniStream indicates an expected call of OpenUniStream. -func (mr *MockStreamManagerMockRecorder) OpenUniStream() *gomock.Call { +func (mr *MockStreamManagerMockRecorder) OpenUniStream() *StreamManagerOpenUniStreamCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStream", reflect.TypeOf((*MockStreamManager)(nil).OpenUniStream)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStream", reflect.TypeOf((*MockStreamManager)(nil).OpenUniStream)) + return &StreamManagerOpenUniStreamCall{Call: call} +} + +// StreamManagerOpenUniStreamCall wrap *gomock.Call +type StreamManagerOpenUniStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerOpenUniStreamCall) Return(arg0 SendStream, arg1 error) *StreamManagerOpenUniStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerOpenUniStreamCall) Do(f func() (SendStream, error)) *StreamManagerOpenUniStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerOpenUniStreamCall) DoAndReturn(f func() (SendStream, error)) *StreamManagerOpenUniStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c } // OpenUniStreamSync mocks base method. @@ -193,9 +433,33 @@ func (m *MockStreamManager) OpenUniStreamSync(arg0 context.Context) (SendStream, } // OpenUniStreamSync indicates an expected call of OpenUniStreamSync. -func (mr *MockStreamManagerMockRecorder) OpenUniStreamSync(arg0 any) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) OpenUniStreamSync(arg0 any) *StreamManagerOpenUniStreamSyncCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStreamSync", reflect.TypeOf((*MockStreamManager)(nil).OpenUniStreamSync), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenUniStreamSync", reflect.TypeOf((*MockStreamManager)(nil).OpenUniStreamSync), arg0) + return &StreamManagerOpenUniStreamSyncCall{Call: call} +} + +// StreamManagerOpenUniStreamSyncCall wrap *gomock.Call +type StreamManagerOpenUniStreamSyncCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerOpenUniStreamSyncCall) Return(arg0 SendStream, arg1 error) *StreamManagerOpenUniStreamSyncCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerOpenUniStreamSyncCall) Do(f func(context.Context) (SendStream, error)) *StreamManagerOpenUniStreamSyncCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerOpenUniStreamSyncCall) DoAndReturn(f func(context.Context) (SendStream, error)) *StreamManagerOpenUniStreamSyncCall { + c.Call = c.Call.DoAndReturn(f) + return c } // ResetFor0RTT mocks base method. @@ -205,9 +469,33 @@ func (m *MockStreamManager) ResetFor0RTT() { } // ResetFor0RTT indicates an expected call of ResetFor0RTT. -func (mr *MockStreamManagerMockRecorder) ResetFor0RTT() *gomock.Call { +func (mr *MockStreamManagerMockRecorder) ResetFor0RTT() *StreamManagerResetFor0RTTCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetFor0RTT", reflect.TypeOf((*MockStreamManager)(nil).ResetFor0RTT)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetFor0RTT", reflect.TypeOf((*MockStreamManager)(nil).ResetFor0RTT)) + return &StreamManagerResetFor0RTTCall{Call: call} +} + +// StreamManagerResetFor0RTTCall wrap *gomock.Call +type StreamManagerResetFor0RTTCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerResetFor0RTTCall) Return() *StreamManagerResetFor0RTTCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerResetFor0RTTCall) Do(f func()) *StreamManagerResetFor0RTTCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerResetFor0RTTCall) DoAndReturn(f func()) *StreamManagerResetFor0RTTCall { + c.Call = c.Call.DoAndReturn(f) + return c } // UpdateLimits mocks base method. @@ -217,9 +505,33 @@ func (m *MockStreamManager) UpdateLimits(arg0 *wire.TransportParameters) { } // UpdateLimits indicates an expected call of UpdateLimits. -func (mr *MockStreamManagerMockRecorder) UpdateLimits(arg0 any) *gomock.Call { +func (mr *MockStreamManagerMockRecorder) UpdateLimits(arg0 any) *StreamManagerUpdateLimitsCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLimits", reflect.TypeOf((*MockStreamManager)(nil).UpdateLimits), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLimits", reflect.TypeOf((*MockStreamManager)(nil).UpdateLimits), arg0) + return &StreamManagerUpdateLimitsCall{Call: call} +} + +// StreamManagerUpdateLimitsCall wrap *gomock.Call +type StreamManagerUpdateLimitsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerUpdateLimitsCall) Return() *StreamManagerUpdateLimitsCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerUpdateLimitsCall) Do(f func(*wire.TransportParameters)) *StreamManagerUpdateLimitsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerUpdateLimitsCall) DoAndReturn(f func(*wire.TransportParameters)) *StreamManagerUpdateLimitsCall { + c.Call = c.Call.DoAndReturn(f) + return c } // UseResetMaps mocks base method. @@ -229,7 +541,31 @@ func (m *MockStreamManager) UseResetMaps() { } // UseResetMaps indicates an expected call of UseResetMaps. -func (mr *MockStreamManagerMockRecorder) UseResetMaps() *gomock.Call { +func (mr *MockStreamManagerMockRecorder) UseResetMaps() *StreamManagerUseResetMapsCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UseResetMaps", reflect.TypeOf((*MockStreamManager)(nil).UseResetMaps)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UseResetMaps", reflect.TypeOf((*MockStreamManager)(nil).UseResetMaps)) + return &StreamManagerUseResetMapsCall{Call: call} +} + +// StreamManagerUseResetMapsCall wrap *gomock.Call +type StreamManagerUseResetMapsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamManagerUseResetMapsCall) Return() *StreamManagerUseResetMapsCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamManagerUseResetMapsCall) Do(f func()) *StreamManagerUseResetMapsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamManagerUseResetMapsCall) DoAndReturn(f func()) *StreamManagerUseResetMapsCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_stream_sender_test.go b/mock_stream_sender_test.go index 87a05a485e8..eca614fde64 100644 --- a/mock_stream_sender_test.go +++ b/mock_stream_sender_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_sender_test.go github.com/quic-go/quic-go StreamSender +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_sender_test.go github.com/quic-go/quic-go StreamSender // // Package quic is a generated GoMock package. package quic @@ -46,9 +46,33 @@ func (m *MockStreamSender) onHasStreamData(arg0 protocol.StreamID) { } // onHasStreamData indicates an expected call of onHasStreamData. -func (mr *MockStreamSenderMockRecorder) onHasStreamData(arg0 any) *gomock.Call { +func (mr *MockStreamSenderMockRecorder) onHasStreamData(arg0 any) *StreamSenderonHasStreamDataCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "onHasStreamData", reflect.TypeOf((*MockStreamSender)(nil).onHasStreamData), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "onHasStreamData", reflect.TypeOf((*MockStreamSender)(nil).onHasStreamData), arg0) + return &StreamSenderonHasStreamDataCall{Call: call} +} + +// StreamSenderonHasStreamDataCall wrap *gomock.Call +type StreamSenderonHasStreamDataCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamSenderonHasStreamDataCall) Return() *StreamSenderonHasStreamDataCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamSenderonHasStreamDataCall) Do(f func(protocol.StreamID)) *StreamSenderonHasStreamDataCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamSenderonHasStreamDataCall) DoAndReturn(f func(protocol.StreamID)) *StreamSenderonHasStreamDataCall { + c.Call = c.Call.DoAndReturn(f) + return c } // onStreamCompleted mocks base method. @@ -58,9 +82,33 @@ func (m *MockStreamSender) onStreamCompleted(arg0 protocol.StreamID) { } // onStreamCompleted indicates an expected call of onStreamCompleted. -func (mr *MockStreamSenderMockRecorder) onStreamCompleted(arg0 any) *gomock.Call { +func (mr *MockStreamSenderMockRecorder) onStreamCompleted(arg0 any) *StreamSenderonStreamCompletedCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "onStreamCompleted", reflect.TypeOf((*MockStreamSender)(nil).onStreamCompleted), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "onStreamCompleted", reflect.TypeOf((*MockStreamSender)(nil).onStreamCompleted), arg0) + return &StreamSenderonStreamCompletedCall{Call: call} +} + +// StreamSenderonStreamCompletedCall wrap *gomock.Call +type StreamSenderonStreamCompletedCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamSenderonStreamCompletedCall) Return() *StreamSenderonStreamCompletedCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamSenderonStreamCompletedCall) Do(f func(protocol.StreamID)) *StreamSenderonStreamCompletedCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamSenderonStreamCompletedCall) DoAndReturn(f func(protocol.StreamID)) *StreamSenderonStreamCompletedCall { + c.Call = c.Call.DoAndReturn(f) + return c } // queueControlFrame mocks base method. @@ -70,7 +118,31 @@ func (m *MockStreamSender) queueControlFrame(arg0 wire.Frame) { } // queueControlFrame indicates an expected call of queueControlFrame. -func (mr *MockStreamSenderMockRecorder) queueControlFrame(arg0 any) *gomock.Call { +func (mr *MockStreamSenderMockRecorder) queueControlFrame(arg0 any) *StreamSenderqueueControlFrameCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "queueControlFrame", reflect.TypeOf((*MockStreamSender)(nil).queueControlFrame), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "queueControlFrame", reflect.TypeOf((*MockStreamSender)(nil).queueControlFrame), arg0) + return &StreamSenderqueueControlFrameCall{Call: call} +} + +// StreamSenderqueueControlFrameCall wrap *gomock.Call +type StreamSenderqueueControlFrameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *StreamSenderqueueControlFrameCall) Return() *StreamSenderqueueControlFrameCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *StreamSenderqueueControlFrameCall) Do(f func(wire.Frame)) *StreamSenderqueueControlFrameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *StreamSenderqueueControlFrameCall) DoAndReturn(f func(wire.Frame)) *StreamSenderqueueControlFrameCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_token_store_test.go b/mock_token_store_test.go index 3d251052a3f..b5f2dbabfef 100644 --- a/mock_token_store_test.go +++ b/mock_token_store_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_token_store_test.go github.com/quic-go/quic-go TokenStore +// mockgen -typed -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_token_store_test.go github.com/quic-go/quic-go TokenStore // // Package quic is a generated GoMock package. package quic @@ -46,9 +46,33 @@ func (m *MockTokenStore) Pop(arg0 string) *ClientToken { } // Pop indicates an expected call of Pop. -func (mr *MockTokenStoreMockRecorder) Pop(arg0 any) *gomock.Call { +func (mr *MockTokenStoreMockRecorder) Pop(arg0 any) *TokenStorePopCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pop", reflect.TypeOf((*MockTokenStore)(nil).Pop), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pop", reflect.TypeOf((*MockTokenStore)(nil).Pop), arg0) + return &TokenStorePopCall{Call: call} +} + +// TokenStorePopCall wrap *gomock.Call +type TokenStorePopCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TokenStorePopCall) Return(arg0 *ClientToken) *TokenStorePopCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TokenStorePopCall) Do(f func(string) *ClientToken) *TokenStorePopCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TokenStorePopCall) DoAndReturn(f func(string) *ClientToken) *TokenStorePopCall { + c.Call = c.Call.DoAndReturn(f) + return c } // Put mocks base method. @@ -58,7 +82,31 @@ func (m *MockTokenStore) Put(arg0 string, arg1 *ClientToken) { } // Put indicates an expected call of Put. -func (mr *MockTokenStoreMockRecorder) Put(arg0, arg1 any) *gomock.Call { +func (mr *MockTokenStoreMockRecorder) Put(arg0, arg1 any) *TokenStorePutCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockTokenStore)(nil).Put), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockTokenStore)(nil).Put), arg0, arg1) + return &TokenStorePutCall{Call: call} +} + +// TokenStorePutCall wrap *gomock.Call +type TokenStorePutCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TokenStorePutCall) Return() *TokenStorePutCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TokenStorePutCall) Do(f func(string, *ClientToken)) *TokenStorePutCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TokenStorePutCall) DoAndReturn(f func(string, *ClientToken)) *TokenStorePutCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mock_unpacker_test.go b/mock_unpacker_test.go index 372e4ac3947..006d9fec782 100644 --- a/mock_unpacker_test.go +++ b/mock_unpacker_test.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_unpacker_test.go github.com/quic-go/quic-go Unpacker +// mockgen -typed -build_flags=-tags=gomock -package quic -self_package github.com/quic-go/quic-go -destination mock_unpacker_test.go github.com/quic-go/quic-go Unpacker // // Package quic is a generated GoMock package. package quic @@ -50,9 +50,33 @@ func (m *MockUnpacker) UnpackLongHeader(arg0 *wire.Header, arg1 time.Time, arg2 } // UnpackLongHeader indicates an expected call of UnpackLongHeader. -func (mr *MockUnpackerMockRecorder) UnpackLongHeader(arg0, arg1, arg2, arg3 any) *gomock.Call { +func (mr *MockUnpackerMockRecorder) UnpackLongHeader(arg0, arg1, arg2, arg3 any) *UnpackerUnpackLongHeaderCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnpackLongHeader", reflect.TypeOf((*MockUnpacker)(nil).UnpackLongHeader), arg0, arg1, arg2, arg3) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnpackLongHeader", reflect.TypeOf((*MockUnpacker)(nil).UnpackLongHeader), arg0, arg1, arg2, arg3) + return &UnpackerUnpackLongHeaderCall{Call: call} +} + +// UnpackerUnpackLongHeaderCall wrap *gomock.Call +type UnpackerUnpackLongHeaderCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *UnpackerUnpackLongHeaderCall) Return(arg0 *unpackedPacket, arg1 error) *UnpackerUnpackLongHeaderCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *UnpackerUnpackLongHeaderCall) Do(f func(*wire.Header, time.Time, []byte, protocol.VersionNumber) (*unpackedPacket, error)) *UnpackerUnpackLongHeaderCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *UnpackerUnpackLongHeaderCall) DoAndReturn(f func(*wire.Header, time.Time, []byte, protocol.VersionNumber) (*unpackedPacket, error)) *UnpackerUnpackLongHeaderCall { + c.Call = c.Call.DoAndReturn(f) + return c } // UnpackShortHeader mocks base method. @@ -68,7 +92,31 @@ func (m *MockUnpacker) UnpackShortHeader(arg0 time.Time, arg1 []byte) (protocol. } // UnpackShortHeader indicates an expected call of UnpackShortHeader. -func (mr *MockUnpackerMockRecorder) UnpackShortHeader(arg0, arg1 any) *gomock.Call { +func (mr *MockUnpackerMockRecorder) UnpackShortHeader(arg0, arg1 any) *UnpackerUnpackShortHeaderCall { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnpackShortHeader", reflect.TypeOf((*MockUnpacker)(nil).UnpackShortHeader), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnpackShortHeader", reflect.TypeOf((*MockUnpacker)(nil).UnpackShortHeader), arg0, arg1) + return &UnpackerUnpackShortHeaderCall{Call: call} +} + +// UnpackerUnpackShortHeaderCall wrap *gomock.Call +type UnpackerUnpackShortHeaderCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *UnpackerUnpackShortHeaderCall) Return(arg0 protocol.PacketNumber, arg1 protocol.PacketNumberLen, arg2 protocol.KeyPhaseBit, arg3 []byte, arg4 error) *UnpackerUnpackShortHeaderCall { + c.Call = c.Call.Return(arg0, arg1, arg2, arg3, arg4) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *UnpackerUnpackShortHeaderCall) Do(f func(time.Time, []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error)) *UnpackerUnpackShortHeaderCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *UnpackerUnpackShortHeaderCall) DoAndReturn(f func(time.Time, []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error)) *UnpackerUnpackShortHeaderCall { + c.Call = c.Call.DoAndReturn(f) + return c } diff --git a/mockgen.go b/mockgen.go index eb24738631a..81cc4a5ef57 100644 --- a/mockgen.go +++ b/mockgen.go @@ -2,73 +2,75 @@ package quic -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn" type SendConn = sendConn -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn" type RawConn = rawConn -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender" type Sender = sender -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_internal_test.go github.com/quic-go/quic-go StreamI" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_internal_test.go github.com/quic-go/quic-go StreamI" type StreamI = streamI -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_stream_test.go github.com/quic-go/quic-go CryptoStream" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_stream_test.go github.com/quic-go/quic-go CryptoStream" type CryptoStream = cryptoStream -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_receive_stream_internal_test.go github.com/quic-go/quic-go ReceiveStreamI" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_receive_stream_internal_test.go github.com/quic-go/quic-go ReceiveStreamI" type ReceiveStreamI = receiveStreamI -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_stream_internal_test.go github.com/quic-go/quic-go SendStreamI" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_stream_internal_test.go github.com/quic-go/quic-go SendStreamI" type SendStreamI = sendStreamI -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_getter_test.go github.com/quic-go/quic-go StreamGetter" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_getter_test.go github.com/quic-go/quic-go StreamGetter" type StreamGetter = streamGetter -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_sender_test.go github.com/quic-go/quic-go StreamSender" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_sender_test.go github.com/quic-go/quic-go StreamSender" type StreamSender = streamSender -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_data_handler_test.go github.com/quic-go/quic-go CryptoDataHandler" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_crypto_data_handler_test.go github.com/quic-go/quic-go CryptoDataHandler" type CryptoDataHandler = cryptoDataHandler -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_frame_source_test.go github.com/quic-go/quic-go FrameSource" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_frame_source_test.go github.com/quic-go/quic-go FrameSource" type FrameSource = frameSource -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_ack_frame_source_test.go github.com/quic-go/quic-go AckFrameSource" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_ack_frame_source_test.go github.com/quic-go/quic-go AckFrameSource" type AckFrameSource = ackFrameSource -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_manager_test.go github.com/quic-go/quic-go StreamManager" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_manager_test.go github.com/quic-go/quic-go StreamManager" type StreamManager = streamManager -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sealing_manager_test.go github.com/quic-go/quic-go SealingManager" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sealing_manager_test.go github.com/quic-go/quic-go SealingManager" type SealingManager = sealingManager -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_unpacker_test.go github.com/quic-go/quic-go Unpacker" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_unpacker_test.go github.com/quic-go/quic-go Unpacker" type Unpacker = unpacker -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packer_test.go github.com/quic-go/quic-go Packer" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packer_test.go github.com/quic-go/quic-go Packer" type Packer = packer -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_mtu_discoverer_test.go github.com/quic-go/quic-go MTUDiscoverer" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_mtu_discoverer_test.go github.com/quic-go/quic-go MTUDiscoverer" type MTUDiscoverer = mtuDiscoverer -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_conn_runner_test.go github.com/quic-go/quic-go ConnRunner" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_conn_runner_test.go github.com/quic-go/quic-go ConnRunner" type ConnRunner = connRunner -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_quic_conn_test.go github.com/quic-go/quic-go QUICConn" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_quic_conn_test.go github.com/quic-go/quic-go QUICConn" type QUICConn = quicConn -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_test.go github.com/quic-go/quic-go PacketHandler" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_test.go github.com/quic-go/quic-go PacketHandler" type PacketHandler = packetHandler //go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager" + +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager" type PacketHandlerManager = packetHandlerManager // Need to use source mode for the batchConn, since reflect mode follows type aliases. // See https://github.com/golang/mock/issues/244 for details. // -//go:generate sh -c "go run go.uber.org/mock/mockgen -package quic -self_package github.com/quic-go/quic-go -source sys_conn_oob.go -destination mock_batch_conn_test.go -mock_names batchConn=MockBatchConn" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -package quic -self_package github.com/quic-go/quic-go -source sys_conn_oob.go -destination mock_batch_conn_test.go -mock_names batchConn=MockBatchConn" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_token_store_test.go github.com/quic-go/quic-go TokenStore" -//go:generate sh -c "go run go.uber.org/mock/mockgen -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_packetconn_test.go net PacketConn" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_token_store_test.go github.com/quic-go/quic-go TokenStore" +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_packetconn_test.go net PacketConn" diff --git a/send_queue_test.go b/send_queue_test.go index e8cb8bdc048..f5513062a48 100644 --- a/send_queue_test.go +++ b/send_queue_test.go @@ -31,7 +31,7 @@ var _ = Describe("Send Queue", func() { q.Send(p, 10, protocol.ECT1) // make sure the packet size is passed through to the conn written := make(chan struct{}) - c.EXPECT().Write([]byte("foobar"), uint16(10), protocol.ECT1).Do(func([]byte, uint16, protocol.ECN) { close(written) }) + c.EXPECT().Write([]byte("foobar"), uint16(10), protocol.ECT1).Do(func([]byte, uint16, protocol.ECN) error { close(written); return nil }) done := make(chan struct{}) go func() { defer GinkgoRecover() @@ -149,7 +149,7 @@ var _ = Describe("Send Queue", func() { It("blocks Close() until the packet has been sent out", func() { written := make(chan []byte) - c.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(p []byte, _ uint16, _ protocol.ECN) { written <- p }) + c.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(p []byte, _ uint16, _ protocol.ECN) error { written <- p; return nil }) done := make(chan struct{}) go func() { defer GinkgoRecover() diff --git a/server_test.go b/server_test.go index 6944a81e519..6b250c33227 100644 --- a/server_test.go +++ b/server_test.go @@ -91,9 +91,10 @@ var _ = Describe("Server", func() { <-wait return 0, nil, errors.New("done") }).MaxTimes(1) - conn.EXPECT().SetReadDeadline(gomock.Any()).Do(func(time.Time) { + conn.EXPECT().SetReadDeadline(gomock.Any()).Do(func(time.Time) error { close(wait) conn.EXPECT().SetReadDeadline(time.Time{}) + return nil }).MaxTimes(1) tlsConf = testdata.GetTLSConfig() tlsConf.NextProtos = []string{"proto1"} @@ -307,7 +308,7 @@ var _ = Describe("Server", func() { Expect(srcConnID).To(Equal(newConnID)) Expect(tokenP).To(Equal(token)) conn.EXPECT().handlePacket(p) - conn.EXPECT().run().Do(func() { close(run) }) + conn.EXPECT().run().Do(func() error { close(run); return nil }) conn.EXPECT().Context().Return(context.Background()) conn.EXPECT().HandshakeComplete().Return(make(chan struct{})) return conn @@ -370,7 +371,6 @@ var _ = Describe("Server", func() { raddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337} packet.remoteAddr = raddr done := make(chan struct{}) - conn.EXPECT().WriteTo(gomock.Any(), raddr).Do(func() { close(done) }).Times(0) serv.handlePacket(packet) Consistently(done, 50*time.Millisecond).ShouldNot(BeClosed()) }) @@ -509,7 +509,7 @@ var _ = Describe("Server", func() { Expect(srcConnID).To(Equal(newConnID)) Expect(tokenP).To(Equal(token)) conn.EXPECT().handlePacket(p) - conn.EXPECT().run().Do(func() { close(run) }) + conn.EXPECT().run().Do(func() error { close(run); return nil }) conn.EXPECT().Context().Return(context.Background()) conn.EXPECT().HandshakeComplete().Return(make(chan struct{})) return conn @@ -621,7 +621,7 @@ var _ = Describe("Server", func() { phm.EXPECT().AddWithConnID(connID, gomock.Any(), gomock.Any()).Return(false) tracer.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()) done := make(chan struct{}) - conn.EXPECT().WriteTo(gomock.Any(), gomock.Any()).Do(func([]byte, net.Addr) { close(done) }) + conn.EXPECT().WriteTo(gomock.Any(), gomock.Any()).Do(func([]byte, net.Addr) (int, error) { close(done); return 0, nil }) Expect(serv.handlePacketImpl(p)).To(BeTrue()) Expect(createdConn).To(BeFalse()) Eventually(done).Should(BeClosed()) @@ -791,7 +791,10 @@ var _ = Describe("Server", func() { done := make(chan struct{}) phm.EXPECT().Get(gomock.Any()) - phm.EXPECT().AddWithConnID(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_, _ protocol.ConnectionID, _ func() (packetHandler, bool)) { close(done) }) + phm.EXPECT().AddWithConnID(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_, _ protocol.ConnectionID, _ func() (packetHandler, bool)) bool { + close(done) + return false + }) serv.handlePacket(packet) Eventually(done).Should(BeClosed()) }) @@ -1031,7 +1034,7 @@ var _ = Describe("Server", func() { Expect(conf.MaxIncomingStreams).To(BeEquivalentTo(1234)) conn.EXPECT().handlePacket(gomock.Any()) conn.EXPECT().HandshakeComplete().Return(handshakeChan) - conn.EXPECT().run().Do(func() {}) + conn.EXPECT().run() conn.EXPECT().Context().Return(context.Background()) return conn } @@ -1107,7 +1110,7 @@ var _ = Describe("Server", func() { ) quicConn { conn.EXPECT().handlePacket(gomock.Any()) conn.EXPECT().HandshakeComplete().Return(handshakeChan) - conn.EXPECT().run().Do(func() {}) + conn.EXPECT().run() conn.EXPECT().Context().Return(context.Background()) return conn } @@ -1179,7 +1182,7 @@ var _ = Describe("Server", func() { _ protocol.VersionNumber, ) quicConn { conn.EXPECT().handlePacket(gomock.Any()) - conn.EXPECT().run().Do(func() {}) + conn.EXPECT().run() conn.EXPECT().earlyConnReady().Return(ready) conn.EXPECT().Context().Return(context.Background()) return conn diff --git a/transport_test.go b/transport_test.go index 2501971982e..5fa6321361e 100644 --- a/transport_test.go +++ b/transport_test.go @@ -280,9 +280,10 @@ var _ = Describe("Transport", func() { phm.EXPECT().GetByResetToken(gomock.Any()), phm.EXPECT().Get(connID), phm.EXPECT().GetStatelessResetToken(connID).Return(token), - conn.EXPECT().WriteTo(gomock.Any(), gomock.Any()).Do(func(b []byte, _ net.Addr) { + conn.EXPECT().WriteTo(gomock.Any(), gomock.Any()).Do(func(b []byte, _ net.Addr) (int, error) { defer close(written) Expect(bytes.Contains(b, token[:])).To(BeTrue()) + return len(b), nil }), ) packetChan <- packetToRead{data: b} From 36f7fe7d07edb94f9be148494659184546b9dbcd Mon Sep 17 00:00:00 2001 From: Glonee Date: Mon, 23 Oct 2023 10:31:24 +0800 Subject: [PATCH 087/225] http3: discard body from responses to HEAD requests (#4115) * http3: HEAD method should not have a body * add tests * Update http3/server.go Co-authored-by: Marten Seemann * ruduce the size of responseWriter --------- Co-authored-by: Marten Seemann --- http3/response_writer.go | 7 ++++++- http3/server.go | 3 +++ http3/server_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/http3/response_writer.go b/http3/response_writer.go index 0d93147827d..59f0ed9a000 100644 --- a/http3/response_writer.go +++ b/http3/response_writer.go @@ -67,9 +67,10 @@ type responseWriter struct { bufferedStr *bufio.Writer buf []byte - headerWritten bool contentLen int64 // if handler set valid Content-Length header numWritten int64 // bytes written + headerWritten bool + isHead bool } var ( @@ -162,6 +163,10 @@ func (w *responseWriter) Write(p []byte) (int, error) { return 0, http.ErrContentLength } + if w.isHead { + return len(p), nil + } + df := &dataFrame{Length: uint64(len(p))} w.buf = w.buf[:0] w.buf = df.Append(w.buf) diff --git a/http3/server.go b/http3/server.go index 4587a1fca77..ac2e32a6e1c 100644 --- a/http3/server.go +++ b/http3/server.go @@ -599,6 +599,9 @@ func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *q ctx = context.WithValue(ctx, http.LocalAddrContextKey, conn.LocalAddr()) req = req.WithContext(ctx) r := newResponseWriter(str, conn, s.logger) + if req.Method == http.MethodHead { + r.isHead = true + } handler := s.Handler if handler == nil { handler = http.DefaultServeMux diff --git a/http3/server_test.go b/http3/server_test.go index 28e89ab99aa..5ec58668f81 100644 --- a/http3/server_test.go +++ b/http3/server_test.go @@ -221,6 +221,45 @@ var _ = Describe("Server", func() { Expect(hfs).To(HaveLen(3)) }) + It("response to HEAD request should not have body", func() { + s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("foobar")) + }) + + headRequest, err := http.NewRequest("HEAD", "https://www.example.com", nil) + Expect(err).ToNot(HaveOccurred()) + responseBuf := &bytes.Buffer{} + setRequest(encodeRequest(headRequest)) + str.EXPECT().Context().Return(reqContext) + str.EXPECT().Write(gomock.Any()).DoAndReturn(responseBuf.Write).AnyTimes() + str.EXPECT().CancelRead(gomock.Any()) + serr := s.handleRequest(conn, str, qpackDecoder, nil) + Expect(serr.err).ToNot(HaveOccurred()) + hfs := decodeHeader(responseBuf) + Expect(hfs).To(HaveKeyWithValue(":status", []string{"200"})) + Expect(responseBuf.Bytes()).To(HaveLen(0)) + }) + + It("response to HEAD request should also do content sniffing", func() { + s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("")) + }) + + headRequest, err := http.NewRequest("HEAD", "https://www.example.com", nil) + Expect(err).ToNot(HaveOccurred()) + responseBuf := &bytes.Buffer{} + setRequest(encodeRequest(headRequest)) + str.EXPECT().Context().Return(reqContext) + str.EXPECT().Write(gomock.Any()).DoAndReturn(responseBuf.Write).AnyTimes() + str.EXPECT().CancelRead(gomock.Any()) + serr := s.handleRequest(conn, str, qpackDecoder, nil) + Expect(serr.err).ToNot(HaveOccurred()) + hfs := decodeHeader(responseBuf) + Expect(hfs).To(HaveKeyWithValue(":status", []string{"200"})) + Expect(hfs).To(HaveKeyWithValue("content-length", []string{"13"})) + Expect(hfs).To(HaveKeyWithValue("content-type", []string{"text/html; charset=utf-8"})) + }) + It("handles a aborting handler", func() { s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { panic(http.ErrAbortHandler) From 5314d90b9f8df658dffd5e10d304653040d94eab Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 23 Oct 2023 12:46:27 +0700 Subject: [PATCH 088/225] fix logging of connection IDs in tracer test (#4118) --- integrationtests/self/tracer_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integrationtests/self/tracer_test.go b/integrationtests/self/tracer_test.go index 5179646e99a..21691661cb1 100644 --- a/integrationtests/self/tracer_test.go +++ b/integrationtests/self/tracer_test.go @@ -19,7 +19,7 @@ import ( . "github.com/onsi/gomega" ) -var _ = Describe("Handshake tests", func() { +var _ = Describe("Tracer tests", func() { addTracers := func(pers protocol.Perspective, conf *quic.Config) *quic.Config { enableQlog := mrand.Int()%3 != 0 enableCustomTracer := mrand.Int()%3 != 0 @@ -30,10 +30,10 @@ var _ = Describe("Handshake tests", func() { if enableQlog { 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) + fmt.Fprintf(GinkgoWriter, "%s qlog tracer deciding to not trace connection %s\n", p, connID) return nil } - fmt.Fprintf(GinkgoWriter, "%s qlog tracing connection %x\n", p, connID) + fmt.Fprintf(GinkgoWriter, "%s qlog tracing connection %s\n", p, connID) return qlog.NewConnectionTracer(utils.NewBufferedWriteCloser(bufio.NewWriter(&bytes.Buffer{}), io.NopCloser(nil)), p, connID) }) } From 4c357c8f769e027016e18824ff7c51ea50e52311 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 23 Oct 2023 12:53:10 +0700 Subject: [PATCH 089/225] ci: create separate artifact archives per workflow run (#4121) --- .github/workflows/integration.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index c661e09cc7e..ba94f673ed4 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -56,7 +56,8 @@ jobs: go run github.com/onsi/ginkgo/v2/ginkgo -r -v -randomize-all -randomize-suites -trace integrationtests/self -- ${{ env.QLOGFLAG }} - name: save qlogs if: ${{ always() && env.DEBUG == 'true' }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: - name: qlogs + name: qlogs-${{ matrix.os }}-go${{ matrix.go }} path: integrationtests/self/*.qlog + retention-days: 7 From 7884f87f826027b36229c7c99eeda77e2cbac28a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 23 Oct 2023 13:36:45 +0700 Subject: [PATCH 090/225] ci: use bash on all platforms (#4122) --- .github/workflows/integration.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index ba94f673ed4..6f9b27fea54 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -13,6 +13,9 @@ jobs: - os: "macos" go: "1.21.x" runs-on: ${{ fromJSON(vars[format('INTEGRATION_RUNNER_{0}', matrix.os)] || format('"{0}-latest"', matrix.os)) }} + defaults: + run: + shell: bash # by default Windows uses PowerShell, which uses a different syntax for setting environment variables env: DEBUG: false # set this to true to export qlogs and save them as artifacts TIMESCALE_FACTOR: 3 From 1c631cf9cb20ff2f4928fe46e3265be1eba3da2c Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 25 Oct 2023 11:18:09 +0700 Subject: [PATCH 091/225] rename Connection.{Send,Receive}Message to {Send,Receive}Datagram (#4116) This is more consistent with both the RFC and the rest of the API. For example, the option in the Config is already name EnableDatagrams, and the property in the ConnectionState is named SupportsDatagrams. --- README.md | 10 ++-- connection.go | 4 +- integrationtests/self/datagram_test.go | 6 +-- integrationtests/self/zero_rtt_oldgo_test.go | 8 ++-- integrationtests/self/zero_rtt_test.go | 8 ++-- interface.go | 10 ++-- internal/mocks/quic/early_conn.go | 48 ++++++++++---------- mock_quic_conn_test.go | 48 ++++++++++---------- 8 files changed, 71 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index e6beb8aa5b0..30265c3ab3f 100644 --- a/README.md +++ b/README.md @@ -159,18 +159,18 @@ On the receiver side, this is surfaced as a `quic.ApplicationError`. Unreliable datagrams are a QUIC extension ([RFC 9221](https://datatracker.ietf.org/doc/html/rfc9221)) that is negotiated during the handshake. Support can be enabled by setting the `quic.Config.EnableDatagram` flag. Note that this doesn't guarantee that the peer also supports datagrams. Whether or not the feature negotiation succeeded can be learned from the `quic.ConnectionState.SupportsDatagrams` obtained from `quic.Connection.ConnectionState()`. -QUIC DATAGRAMs are a new QUIC frame type sent in QUIC 1-RTT packets (i.e. after completion of the handshake). Therefore, they're end-to-end encrypted and congestion-controlled. However, if a DATAGRAM frame is deemed lost by QUIC's loss detection mechanism, they are not automatically retransmitted. +QUIC DATAGRAMs are a new QUIC frame type sent in QUIC 1-RTT packets (i.e. after completion of the handshake). Therefore, they're end-to-end encrypted and congestion-controlled. However, if a DATAGRAM frame is deemed lost by QUIC's loss detection mechanism, they are not retransmitted. -Datagrams are sent using the `SendMessage` method on the `quic.Connection`: +Datagrams are sent using the `SendDatagram` method on the `quic.Connection`: ```go -conn.SendMessage([]byte("foobar")) +conn.SendDatagram([]byte("foobar")) ``` -And received using `ReceiveMessage`: +And received using `ReceiveDatagram`: ```go -msg, err := conn.ReceiveMessage() +msg, err := conn.ReceiveDatagram() ``` Note that this code path is currently not optimized. It works for datagrams that are sent occasionally, but it doesn't achieve the same throughput as writing data on a stream. Please get in touch on issue #3766 if your use case relies on high datagram throughput, or if you'd like to help fix this issue. There are also some restrictions regarding the maximum message size (see #3599). diff --git a/connection.go b/connection.go index 09b522a9eb7..93c159137bf 100644 --- a/connection.go +++ b/connection.go @@ -2343,7 +2343,7 @@ func (s *connection) onStreamCompleted(id protocol.StreamID) { } } -func (s *connection) SendMessage(p []byte) error { +func (s *connection) SendDatagram(p []byte) error { if !s.supportsDatagrams() { return errors.New("datagram support disabled") } @@ -2357,7 +2357,7 @@ func (s *connection) SendMessage(p []byte) error { return s.datagramQueue.AddAndWait(f) } -func (s *connection) ReceiveMessage(ctx context.Context) ([]byte, error) { +func (s *connection) ReceiveDatagram(ctx context.Context) ([]byte, error) { if !s.config.EnableDatagrams { return nil, errors.New("datagram support disabled") } diff --git a/integrationtests/self/datagram_test.go b/integrationtests/self/datagram_test.go index 35d0718a978..5f7f09f3415 100644 --- a/integrationtests/self/datagram_test.go +++ b/integrationtests/self/datagram_test.go @@ -57,7 +57,7 @@ var _ = Describe("Datagram test", func() { defer wg.Done() b := make([]byte, 8) binary.BigEndian.PutUint64(b, uint64(i)) - Expect(conn.SendMessage(b)).To(Succeed()) + Expect(conn.SendDatagram(b)).To(Succeed()) }(i) } wg.Wait() @@ -120,7 +120,7 @@ var _ = Describe("Datagram test", func() { for { // Close the connection if no message is received for 100 ms. timer := time.AfterFunc(scaleDuration(100*time.Millisecond), func() { conn.CloseWithError(0, "") }) - if _, err := conn.ReceiveMessage(context.Background()); err != nil { + if _, err := conn.ReceiveDatagram(context.Background()); err != nil { break } timer.Stop() @@ -170,7 +170,7 @@ var _ = Describe("Datagram test", func() { Expect(err).ToNot(HaveOccurred()) Expect(conn.ConnectionState().SupportsDatagrams).To(BeFalse()) - Expect(conn.SendMessage([]byte{0})).To(HaveOccurred()) + Expect(conn.SendDatagram([]byte{0})).To(HaveOccurred()) close() conn.CloseWithError(0, "") diff --git a/integrationtests/self/zero_rtt_oldgo_test.go b/integrationtests/self/zero_rtt_oldgo_test.go index eb2302d3d85..f42194bcc39 100644 --- a/integrationtests/self/zero_rtt_oldgo_test.go +++ b/integrationtests/self/zero_rtt_oldgo_test.go @@ -830,7 +830,7 @@ var _ = Describe("0-RTT", func() { defer close(received) conn, err := ln.Accept(context.Background()) Expect(err).ToNot(HaveOccurred()) - receivedMessage, err = conn.ReceiveMessage(context.Background()) + receivedMessage, err = conn.ReceiveDatagram(context.Background()) Expect(err).ToNot(HaveOccurred()) Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) }() @@ -844,7 +844,7 @@ var _ = Describe("0-RTT", func() { ) Expect(err).ToNot(HaveOccurred()) Expect(conn.ConnectionState().SupportsDatagrams).To(BeTrue()) - Expect(conn.SendMessage(sentMessage)).To(Succeed()) + Expect(conn.SendDatagram(sentMessage)).To(Succeed()) <-conn.HandshakeComplete() <-received @@ -884,7 +884,7 @@ var _ = Describe("0-RTT", func() { defer GinkgoRecover() conn, err := ln.Accept(context.Background()) Expect(err).ToNot(HaveOccurred()) - _, err = conn.ReceiveMessage(context.Background()) + _, err = conn.ReceiveDatagram(context.Background()) Expect(err.Error()).To(Equal("datagram support disabled")) <-conn.HandshakeComplete() Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) @@ -900,7 +900,7 @@ var _ = Describe("0-RTT", func() { Expect(err).ToNot(HaveOccurred()) // the client can temporarily send datagrams but the server doesn't process them. Expect(conn.ConnectionState().SupportsDatagrams).To(BeTrue()) - Expect(conn.SendMessage(make([]byte, 100))).To(Succeed()) + Expect(conn.SendDatagram(make([]byte, 100))).To(Succeed()) <-conn.HandshakeComplete() Expect(conn.ConnectionState().SupportsDatagrams).To(BeFalse()) diff --git a/integrationtests/self/zero_rtt_test.go b/integrationtests/self/zero_rtt_test.go index 1f750d3ac25..3e9a0f601b6 100644 --- a/integrationtests/self/zero_rtt_test.go +++ b/integrationtests/self/zero_rtt_test.go @@ -960,7 +960,7 @@ var _ = Describe("0-RTT", func() { defer close(received) conn, err := ln.Accept(context.Background()) Expect(err).ToNot(HaveOccurred()) - receivedMessage, err = conn.ReceiveMessage(context.Background()) + receivedMessage, err = conn.ReceiveDatagram(context.Background()) Expect(err).ToNot(HaveOccurred()) Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) }() @@ -974,7 +974,7 @@ var _ = Describe("0-RTT", func() { ) Expect(err).ToNot(HaveOccurred()) Expect(conn.ConnectionState().SupportsDatagrams).To(BeTrue()) - Expect(conn.SendMessage(sentMessage)).To(Succeed()) + Expect(conn.SendDatagram(sentMessage)).To(Succeed()) <-conn.HandshakeComplete() <-received @@ -1016,7 +1016,7 @@ var _ = Describe("0-RTT", func() { defer GinkgoRecover() conn, err := ln.Accept(context.Background()) Expect(err).ToNot(HaveOccurred()) - _, err = conn.ReceiveMessage(context.Background()) + _, err = conn.ReceiveDatagram(context.Background()) Expect(err.Error()).To(Equal("datagram support disabled")) <-conn.HandshakeComplete() Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) @@ -1032,7 +1032,7 @@ var _ = Describe("0-RTT", func() { Expect(err).ToNot(HaveOccurred()) // the client can temporarily send datagrams but the server doesn't process them. Expect(conn.ConnectionState().SupportsDatagrams).To(BeTrue()) - Expect(conn.SendMessage(make([]byte, 100))).To(Succeed()) + Expect(conn.SendDatagram(make([]byte, 100))).To(Succeed()) <-conn.HandshakeComplete() Expect(conn.ConnectionState().SupportsDatagrams).To(BeFalse()) diff --git a/interface.go b/interface.go index 6eac385dfce..da0e5e2b31b 100644 --- a/interface.go +++ b/interface.go @@ -187,10 +187,10 @@ type Connection interface { // Warning: This API should not be considered stable and might change soon. ConnectionState() ConnectionState - // SendMessage sends a message as a datagram, as specified in RFC 9221. - SendMessage([]byte) error - // ReceiveMessage gets a message received in a datagram, as specified in RFC 9221. - ReceiveMessage(context.Context) ([]byte, error) + // SendDatagram sends a message as a datagram, as specified in RFC 9221. + SendDatagram([]byte) error + // ReceiveDatagram gets a message received in a datagram, as specified in RFC 9221. + ReceiveDatagram(context.Context) ([]byte, error) } // An EarlyConnection is a connection that is handshaking. @@ -338,7 +338,7 @@ type ConnectionState struct { // SupportsDatagrams says if support for QUIC datagrams (RFC 9221) was negotiated. // This requires both nodes to support and enable the datagram extensions (via Config.EnableDatagrams). // If datagram support was negotiated, datagrams can be sent and received using the - // SendMessage and ReceiveMessage methods on the Connection. + // SendDatagram and ReceiveDatagram methods on the Connection. SupportsDatagrams bool // Used0RTT says if 0-RTT resumption was used. Used0RTT bool diff --git a/internal/mocks/quic/early_conn.go b/internal/mocks/quic/early_conn.go index 223def6c5e9..2e726a823d2 100644 --- a/internal/mocks/quic/early_conn.go +++ b/internal/mocks/quic/early_conn.go @@ -503,41 +503,41 @@ func (c *EarlyConnectionOpenUniStreamSyncCall) DoAndReturn(f func(context.Contex return c } -// ReceiveMessage mocks base method. -func (m *MockEarlyConnection) ReceiveMessage(arg0 context.Context) ([]byte, error) { +// ReceiveDatagram mocks base method. +func (m *MockEarlyConnection) ReceiveDatagram(arg0 context.Context) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReceiveMessage", arg0) + ret := m.ctrl.Call(m, "ReceiveDatagram", arg0) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } -// ReceiveMessage indicates an expected call of ReceiveMessage. -func (mr *MockEarlyConnectionMockRecorder) ReceiveMessage(arg0 any) *EarlyConnectionReceiveMessageCall { +// ReceiveDatagram indicates an expected call of ReceiveDatagram. +func (mr *MockEarlyConnectionMockRecorder) ReceiveDatagram(arg0 any) *EarlyConnectionReceiveDatagramCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveMessage", reflect.TypeOf((*MockEarlyConnection)(nil).ReceiveMessage), arg0) - return &EarlyConnectionReceiveMessageCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveDatagram", reflect.TypeOf((*MockEarlyConnection)(nil).ReceiveDatagram), arg0) + return &EarlyConnectionReceiveDatagramCall{Call: call} } -// EarlyConnectionReceiveMessageCall wrap *gomock.Call -type EarlyConnectionReceiveMessageCall struct { +// EarlyConnectionReceiveDatagramCall wrap *gomock.Call +type EarlyConnectionReceiveDatagramCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *EarlyConnectionReceiveMessageCall) Return(arg0 []byte, arg1 error) *EarlyConnectionReceiveMessageCall { +func (c *EarlyConnectionReceiveDatagramCall) Return(arg0 []byte, arg1 error) *EarlyConnectionReceiveDatagramCall { c.Call = c.Call.Return(arg0, arg1) return c } // Do rewrite *gomock.Call.Do -func (c *EarlyConnectionReceiveMessageCall) Do(f func(context.Context) ([]byte, error)) *EarlyConnectionReceiveMessageCall { +func (c *EarlyConnectionReceiveDatagramCall) Do(f func(context.Context) ([]byte, error)) *EarlyConnectionReceiveDatagramCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *EarlyConnectionReceiveMessageCall) DoAndReturn(f func(context.Context) ([]byte, error)) *EarlyConnectionReceiveMessageCall { +func (c *EarlyConnectionReceiveDatagramCall) DoAndReturn(f func(context.Context) ([]byte, error)) *EarlyConnectionReceiveDatagramCall { c.Call = c.Call.DoAndReturn(f) return c } @@ -580,40 +580,40 @@ func (c *EarlyConnectionRemoteAddrCall) DoAndReturn(f func() net.Addr) *EarlyCon return c } -// SendMessage mocks base method. -func (m *MockEarlyConnection) SendMessage(arg0 []byte) error { +// SendDatagram mocks base method. +func (m *MockEarlyConnection) SendDatagram(arg0 []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendMessage", arg0) + ret := m.ctrl.Call(m, "SendDatagram", arg0) ret0, _ := ret[0].(error) return ret0 } -// SendMessage indicates an expected call of SendMessage. -func (mr *MockEarlyConnectionMockRecorder) SendMessage(arg0 any) *EarlyConnectionSendMessageCall { +// SendDatagram indicates an expected call of SendDatagram. +func (mr *MockEarlyConnectionMockRecorder) SendDatagram(arg0 any) *EarlyConnectionSendDatagramCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockEarlyConnection)(nil).SendMessage), arg0) - return &EarlyConnectionSendMessageCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendDatagram", reflect.TypeOf((*MockEarlyConnection)(nil).SendDatagram), arg0) + return &EarlyConnectionSendDatagramCall{Call: call} } -// EarlyConnectionSendMessageCall wrap *gomock.Call -type EarlyConnectionSendMessageCall struct { +// EarlyConnectionSendDatagramCall wrap *gomock.Call +type EarlyConnectionSendDatagramCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *EarlyConnectionSendMessageCall) Return(arg0 error) *EarlyConnectionSendMessageCall { +func (c *EarlyConnectionSendDatagramCall) Return(arg0 error) *EarlyConnectionSendDatagramCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *EarlyConnectionSendMessageCall) Do(f func([]byte) error) *EarlyConnectionSendMessageCall { +func (c *EarlyConnectionSendDatagramCall) Do(f func([]byte) error) *EarlyConnectionSendDatagramCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *EarlyConnectionSendMessageCall) DoAndReturn(f func([]byte) error) *EarlyConnectionSendMessageCall { +func (c *EarlyConnectionSendDatagramCall) DoAndReturn(f func([]byte) error) *EarlyConnectionSendDatagramCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/mock_quic_conn_test.go b/mock_quic_conn_test.go index c7d84850e05..2a677066246 100644 --- a/mock_quic_conn_test.go +++ b/mock_quic_conn_test.go @@ -541,41 +541,41 @@ func (c *QUICConnOpenUniStreamSyncCall) DoAndReturn(f func(context.Context) (Sen return c } -// ReceiveMessage mocks base method. -func (m *MockQUICConn) ReceiveMessage(arg0 context.Context) ([]byte, error) { +// ReceiveDatagram mocks base method. +func (m *MockQUICConn) ReceiveDatagram(arg0 context.Context) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReceiveMessage", arg0) + ret := m.ctrl.Call(m, "ReceiveDatagram", arg0) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } -// ReceiveMessage indicates an expected call of ReceiveMessage. -func (mr *MockQUICConnMockRecorder) ReceiveMessage(arg0 any) *QUICConnReceiveMessageCall { +// ReceiveDatagram indicates an expected call of ReceiveDatagram. +func (mr *MockQUICConnMockRecorder) ReceiveDatagram(arg0 any) *QUICConnReceiveDatagramCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveMessage", reflect.TypeOf((*MockQUICConn)(nil).ReceiveMessage), arg0) - return &QUICConnReceiveMessageCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveDatagram", reflect.TypeOf((*MockQUICConn)(nil).ReceiveDatagram), arg0) + return &QUICConnReceiveDatagramCall{Call: call} } -// QUICConnReceiveMessageCall wrap *gomock.Call -type QUICConnReceiveMessageCall struct { +// QUICConnReceiveDatagramCall wrap *gomock.Call +type QUICConnReceiveDatagramCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *QUICConnReceiveMessageCall) Return(arg0 []byte, arg1 error) *QUICConnReceiveMessageCall { +func (c *QUICConnReceiveDatagramCall) Return(arg0 []byte, arg1 error) *QUICConnReceiveDatagramCall { c.Call = c.Call.Return(arg0, arg1) return c } // Do rewrite *gomock.Call.Do -func (c *QUICConnReceiveMessageCall) Do(f func(context.Context) ([]byte, error)) *QUICConnReceiveMessageCall { +func (c *QUICConnReceiveDatagramCall) Do(f func(context.Context) ([]byte, error)) *QUICConnReceiveDatagramCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *QUICConnReceiveMessageCall) DoAndReturn(f func(context.Context) ([]byte, error)) *QUICConnReceiveMessageCall { +func (c *QUICConnReceiveDatagramCall) DoAndReturn(f func(context.Context) ([]byte, error)) *QUICConnReceiveDatagramCall { c.Call = c.Call.DoAndReturn(f) return c } @@ -618,40 +618,40 @@ func (c *QUICConnRemoteAddrCall) DoAndReturn(f func() net.Addr) *QUICConnRemoteA return c } -// SendMessage mocks base method. -func (m *MockQUICConn) SendMessage(arg0 []byte) error { +// SendDatagram mocks base method. +func (m *MockQUICConn) SendDatagram(arg0 []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendMessage", arg0) + ret := m.ctrl.Call(m, "SendDatagram", arg0) ret0, _ := ret[0].(error) return ret0 } -// SendMessage indicates an expected call of SendMessage. -func (mr *MockQUICConnMockRecorder) SendMessage(arg0 any) *QUICConnSendMessageCall { +// SendDatagram indicates an expected call of SendDatagram. +func (mr *MockQUICConnMockRecorder) SendDatagram(arg0 any) *QUICConnSendDatagramCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockQUICConn)(nil).SendMessage), arg0) - return &QUICConnSendMessageCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendDatagram", reflect.TypeOf((*MockQUICConn)(nil).SendDatagram), arg0) + return &QUICConnSendDatagramCall{Call: call} } -// QUICConnSendMessageCall wrap *gomock.Call -type QUICConnSendMessageCall struct { +// QUICConnSendDatagramCall wrap *gomock.Call +type QUICConnSendDatagramCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *QUICConnSendMessageCall) Return(arg0 error) *QUICConnSendMessageCall { +func (c *QUICConnSendDatagramCall) Return(arg0 error) *QUICConnSendDatagramCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *QUICConnSendMessageCall) Do(f func([]byte) error) *QUICConnSendMessageCall { +func (c *QUICConnSendDatagramCall) Do(f func([]byte) error) *QUICConnSendDatagramCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *QUICConnSendMessageCall) DoAndReturn(f func([]byte) error) *QUICConnSendMessageCall { +func (c *QUICConnSendDatagramCall) DoAndReturn(f func([]byte) error) *QUICConnSendDatagramCall { c.Call = c.Call.DoAndReturn(f) return c } From 6239effc7ae0a02c2fda23be9fbf62db722cc5b3 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 25 Oct 2023 11:18:43 +0700 Subject: [PATCH 092/225] fix IPv4 ECN control message length on Linux (#4127) --- sys_conn_helper_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys_conn_helper_linux.go b/sys_conn_helper_linux.go index 8e326af9817..5fbf34ade52 100644 --- a/sys_conn_helper_linux.go +++ b/sys_conn_helper_linux.go @@ -19,7 +19,7 @@ const ( ipv4PKTINFO = unix.IP_PKTINFO ) -const ecnIPv4DataLen = 4 +const ecnIPv4DataLen = 1 const batchSize = 8 // needs to smaller than MaxUint8 (otherwise the type of oobConn.readPos has to be changed) From 30f9c0139f02d1e013b2a3a4007a2e494e38d9d3 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 25 Oct 2023 11:46:29 +0700 Subject: [PATCH 093/225] use typed atomics in integration tests (#4120) * use typed atomic in integration tests * use an atomic.Bool in hotswap test --- integrationtests/self/cancelation_test.go | 68 ++++++++++---------- integrationtests/self/datagram_test.go | 10 +-- integrationtests/self/drop_test.go | 6 +- integrationtests/self/handshake_drop_test.go | 12 ++-- integrationtests/self/hotswap_test.go | 22 ++++--- integrationtests/self/mitm_test.go | 18 +++--- integrationtests/self/timeout_test.go | 6 +- integrationtests/self/zero_rtt_oldgo_test.go | 33 +++++----- integrationtests/self/zero_rtt_test.go | 33 +++++----- integrationtests/tools/proxy/proxy_test.go | 30 ++++----- 10 files changed, 118 insertions(+), 120 deletions(-) diff --git a/integrationtests/self/cancelation_test.go b/integrationtests/self/cancelation_test.go index 5f95c0b73cf..28f3e009a96 100644 --- a/integrationtests/self/cancelation_test.go +++ b/integrationtests/self/cancelation_test.go @@ -31,7 +31,7 @@ var _ = Describe("Stream Cancellations", func() { server, err = quic.ListenAddr("localhost:0", getTLSConfig(), getQuicConfig(nil)) Expect(err).ToNot(HaveOccurred()) - var canceledCounter int32 + var canceledCounter atomic.Int32 go func() { defer GinkgoRecover() var wg sync.WaitGroup @@ -50,18 +50,18 @@ var _ = Describe("Stream Cancellations", func() { ErrorCode: quic.StreamErrorCode(str.StreamID()), Remote: true, })) - atomic.AddInt32(&canceledCounter, 1) + canceledCounter.Add(1) return } if err := str.Close(); err != nil { Expect(err).To(MatchError(fmt.Sprintf("close called for canceled stream %d", str.StreamID()))) - atomic.AddInt32(&canceledCounter, 1) + canceledCounter.Add(1) return } }() } wg.Wait() - numCanceledStreamsChan <- atomic.LoadInt32(&canceledCounter) + numCanceledStreamsChan <- canceledCounter.Load() }() return numCanceledStreamsChan } @@ -80,7 +80,7 @@ var _ = Describe("Stream Cancellations", func() { ) Expect(err).ToNot(HaveOccurred()) - var canceledCounter int32 + var canceledCounter atomic.Int32 var wg sync.WaitGroup wg.Add(numStreams) for i := 0; i < numStreams; i++ { @@ -91,7 +91,7 @@ var _ = Describe("Stream Cancellations", func() { Expect(err).ToNot(HaveOccurred()) // cancel around 2/3 of the streams if rand.Int31()%3 != 0 { - atomic.AddInt32(&canceledCounter, 1) + canceledCounter.Add(1) resetErr := quic.StreamErrorCode(str.StreamID()) str.CancelRead(resetErr) _, err := str.Read([]byte{0}) @@ -113,7 +113,7 @@ var _ = Describe("Stream Cancellations", func() { Eventually(serverCanceledCounterChan).Should(Receive(&serverCanceledCounter)) Expect(conn.CloseWithError(0, "")).To(Succeed()) - clientCanceledCounter := atomic.LoadInt32(&canceledCounter) + clientCanceledCounter := canceledCounter.Load() // The server will only count a stream as being reset if learns about the cancelation before it finished writing all data. Expect(clientCanceledCounter).To(BeNumerically(">=", serverCanceledCounter)) fmt.Fprintf(GinkgoWriter, "Canceled reading on %d of %d streams.\n", clientCanceledCounter, numStreams) @@ -132,7 +132,7 @@ var _ = Describe("Stream Cancellations", func() { ) Expect(err).ToNot(HaveOccurred()) - var canceledCounter int32 + var canceledCounter atomic.Int32 var wg sync.WaitGroup wg.Add(numStreams) for i := 0; i < numStreams; i++ { @@ -148,7 +148,7 @@ var _ = Describe("Stream Cancellations", func() { Expect(err).ToNot(HaveOccurred()) str.CancelRead(quic.StreamErrorCode(str.StreamID())) Expect(data).To(Equal(PRData[:length])) - atomic.AddInt32(&canceledCounter, 1) + canceledCounter.Add(1) return } data, err := io.ReadAll(str) @@ -162,7 +162,7 @@ var _ = Describe("Stream Cancellations", func() { Eventually(serverCanceledCounterChan).Should(Receive(&serverCanceledCounter)) Expect(conn.CloseWithError(0, "")).To(Succeed()) - clientCanceledCounter := atomic.LoadInt32(&canceledCounter) + clientCanceledCounter := canceledCounter.Load() // The server will only count a stream as being reset if learns about the cancelation before it finished writing all data. Expect(clientCanceledCounter).To(BeNumerically(">=", serverCanceledCounter)) fmt.Fprintf(GinkgoWriter, "Canceled reading on %d of %d streams.\n", clientCanceledCounter, numStreams) @@ -185,7 +185,7 @@ var _ = Describe("Stream Cancellations", func() { var wg sync.WaitGroup wg.Add(numStreams) - var counter int32 + var counter atomic.Int32 for i := 0; i < numStreams; i++ { go func() { defer GinkgoRecover() @@ -199,7 +199,7 @@ var _ = Describe("Stream Cancellations", func() { defer close(done) b := make([]byte, 32) if _, err := str.Read(b); err != nil { - atomic.AddInt32(&counter, 1) + counter.Add(1) Expect(err).To(Equal(&quic.StreamError{ StreamID: str.StreamID(), ErrorCode: 1234, @@ -214,7 +214,7 @@ var _ = Describe("Stream Cancellations", func() { } wg.Wait() Expect(conn.CloseWithError(0, "")).To(Succeed()) - numCanceled := atomic.LoadInt32(&counter) + numCanceled := counter.Load() fmt.Fprintf(GinkgoWriter, "canceled %d out of %d streams", numCanceled, numStreams) Expect(numCanceled).ToNot(BeZero()) Eventually(serverCanceledCounterChan).Should(Receive()) @@ -232,7 +232,7 @@ var _ = Describe("Stream Cancellations", func() { Expect(err).ToNot(HaveOccurred()) var wg sync.WaitGroup - var counter int32 + var counter atomic.Int32 wg.Add(numStreams) for i := 0; i < numStreams; i++ { go func() { @@ -242,7 +242,7 @@ var _ = Describe("Stream Cancellations", func() { Expect(err).ToNot(HaveOccurred()) data, err := io.ReadAll(str) if err != nil { - atomic.AddInt32(&counter, 1) + counter.Add(1) Expect(err).To(MatchError(&quic.StreamError{ StreamID: str.StreamID(), ErrorCode: quic.StreamErrorCode(str.StreamID()), @@ -254,7 +254,7 @@ var _ = Describe("Stream Cancellations", func() { } wg.Wait() - streamCount := atomic.LoadInt32(&counter) + streamCount := counter.Load() fmt.Fprintf(GinkgoWriter, "Canceled writing on %d of %d streams\n", streamCount, numStreams) Expect(streamCount).To(BeNumerically(">", numStreams/10)) Expect(numStreams - streamCount).To(BeNumerically(">", numStreams/10)) @@ -267,7 +267,7 @@ var _ = Describe("Stream Cancellations", func() { server, err := quic.ListenAddr("localhost:0", getTLSConfig(), nil) Expect(err).ToNot(HaveOccurred()) - var canceledCounter int32 + var canceledCounter atomic.Int32 go func() { defer GinkgoRecover() conn, err := server.Accept(context.Background()) @@ -280,7 +280,7 @@ var _ = Describe("Stream Cancellations", func() { // cancel about 2/3 of the streams if rand.Int31()%3 != 0 { str.CancelWrite(quic.StreamErrorCode(str.StreamID())) - atomic.AddInt32(&canceledCounter, 1) + canceledCounter.Add(1) return } _, err = str.Write(PRData) @@ -291,14 +291,14 @@ var _ = Describe("Stream Cancellations", func() { }() clientCanceledStreams := runClient(server) - Expect(clientCanceledStreams).To(Equal(atomic.LoadInt32(&canceledCounter))) + Expect(clientCanceledStreams).To(Equal(canceledCounter.Load())) }) It("downloads when the server cancels some streams after sending some data", func() { server, err := quic.ListenAddr("localhost:0", getTLSConfig(), nil) Expect(err).ToNot(HaveOccurred()) - var canceledCounter int32 + var canceledCounter atomic.Int32 go func() { defer GinkgoRecover() conn, err := server.Accept(context.Background()) @@ -314,7 +314,7 @@ var _ = Describe("Stream Cancellations", func() { _, err = str.Write(PRData[:length]) Expect(err).ToNot(HaveOccurred()) str.CancelWrite(quic.StreamErrorCode(str.StreamID())) - atomic.AddInt32(&canceledCounter, 1) + canceledCounter.Add(1) return } _, err = str.Write(PRData) @@ -325,7 +325,7 @@ var _ = Describe("Stream Cancellations", func() { }() clientCanceledStreams := runClient(server) - Expect(clientCanceledStreams).To(Equal(atomic.LoadInt32(&canceledCounter))) + Expect(clientCanceledStreams).To(Equal(canceledCounter.Load())) }) }) @@ -378,7 +378,7 @@ var _ = Describe("Stream Cancellations", func() { Expect(err).ToNot(HaveOccurred()) var wg sync.WaitGroup - var counter int32 + var counter atomic.Int32 wg.Add(numStreams) for i := 0; i < numStreams; i++ { go func() { @@ -399,13 +399,13 @@ var _ = Describe("Stream Cancellations", func() { })) return } - atomic.AddInt32(&counter, 1) + counter.Add(1) Expect(data).To(Equal(PRData)) }() } wg.Wait() - count := atomic.LoadInt32(&counter) + count := counter.Load() Expect(count).To(BeNumerically(">", numStreams/15)) fmt.Fprintf(GinkgoWriter, "Successfully read from %d of %d streams.\n", count, numStreams) @@ -464,7 +464,7 @@ var _ = Describe("Stream Cancellations", func() { Expect(err).ToNot(HaveOccurred()) var wg sync.WaitGroup - var counter int32 + var counter atomic.Int32 wg.Add(numStreams) for i := 0; i < numStreams; i++ { go func() { @@ -495,14 +495,14 @@ var _ = Describe("Stream Cancellations", func() { return } - atomic.AddInt32(&counter, 1) + counter.Add(1) Expect(data).To(Equal(PRData)) }() } wg.Wait() Eventually(done).Should(BeClosed()) - count := atomic.LoadInt32(&counter) + count := counter.Load() Expect(count).To(BeNumerically(">", numStreams/15)) fmt.Fprintf(GinkgoWriter, "Successfully read from %d of %d streams.\n", count, numStreams) @@ -543,7 +543,7 @@ var _ = Describe("Stream Cancellations", func() { Expect(err).ToNot(HaveOccurred()) var numToAccept int - var counter int32 + var counter atomic.Int32 var wg sync.WaitGroup wg.Add(numStreams) for numToAccept < numStreams { @@ -561,7 +561,7 @@ var _ = Describe("Stream Cancellations", func() { str, err := conn.AcceptUniStream(ctx) if err != nil { if err.Error() == "context canceled" { - atomic.AddInt32(&counter, 1) + counter.Add(1) } return } @@ -573,7 +573,7 @@ var _ = Describe("Stream Cancellations", func() { } wg.Wait() - count := atomic.LoadInt32(&counter) + count := counter.Load() fmt.Fprintf(GinkgoWriter, "Canceled AcceptStream %d times\n", count) Expect(count).To(BeNumerically(">", numStreams/2)) Expect(conn.CloseWithError(0, "")).To(Succeed()) @@ -589,7 +589,7 @@ var _ = Describe("Stream Cancellations", func() { Expect(err).ToNot(HaveOccurred()) msg := make(chan struct{}, 1) - var numCanceled int32 + var numCanceled atomic.Int32 go func() { defer GinkgoRecover() defer close(msg) @@ -603,7 +603,7 @@ var _ = Describe("Stream Cancellations", func() { str, err := conn.OpenUniStreamSync(ctx) if err != nil { Expect(err).To(MatchError(context.DeadlineExceeded)) - atomic.AddInt32(&numCanceled, 1) + numCanceled.Add(1) select { case msg <- struct{}{}: default: @@ -644,7 +644,7 @@ var _ = Describe("Stream Cancellations", func() { } wg.Wait() - count := atomic.LoadInt32(&numCanceled) + count := numCanceled.Load() fmt.Fprintf(GinkgoWriter, "Canceled OpenStreamSync %d times\n", count) Expect(count).To(BeNumerically(">=", numStreams-maxIncomingStreams)) Expect(conn.CloseWithError(0, "")).To(Succeed()) diff --git a/integrationtests/self/datagram_test.go b/integrationtests/self/datagram_test.go index 5f7f09f3415..55e85771620 100644 --- a/integrationtests/self/datagram_test.go +++ b/integrationtests/self/datagram_test.go @@ -23,7 +23,7 @@ var _ = Describe("Datagram test", func() { var ( serverConn, clientConn *net.UDPConn - dropped, total int32 + dropped, total atomic.Int32 ) startServerAndProxy := func(enableDatagram, expectDatagramSupport bool) (port int, closeFn func()) { @@ -81,9 +81,9 @@ var _ = Describe("Datagram test", func() { } drop := mrand.Int()%10 == 0 if drop { - atomic.AddInt32(&dropped, 1) + dropped.Add(1) } - atomic.AddInt32(&total, 1) + total.Add(1) return drop }, }) @@ -127,9 +127,9 @@ var _ = Describe("Datagram test", func() { counter++ } - numDropped := int(atomic.LoadInt32(&dropped)) + numDropped := int(dropped.Load()) expVal := num - numDropped - fmt.Fprintf(GinkgoWriter, "Dropped %d out of %d packets.\n", numDropped, atomic.LoadInt32(&total)) + fmt.Fprintf(GinkgoWriter, "Dropped %d out of %d packets.\n", numDropped, total.Load()) fmt.Fprintf(GinkgoWriter, "Received %d out of %d sent datagrams.\n", counter, num) Expect(counter).To(And( BeNumerically(">", expVal*9/10), diff --git a/integrationtests/self/drop_test.go b/integrationtests/self/drop_test.go index 4eac657aa8a..a3e385bbf35 100644 --- a/integrationtests/self/drop_test.go +++ b/integrationtests/self/drop_test.go @@ -67,14 +67,14 @@ var _ = Describe("Drop Tests", func() { fmt.Fprintf(GinkgoWriter, "Dropping packets for %s, after a delay of %s\n", dropDuration, dropDelay) startTime := time.Now() - var numDroppedPackets int32 + var numDroppedPackets atomic.Int32 startListenerAndProxy(func(d quicproxy.Direction, _ []byte) bool { if !d.Is(direction) { return false } drop := time.Now().After(startTime.Add(dropDelay)) && time.Now().Before(startTime.Add(dropDelay).Add(dropDuration)) if drop { - atomic.AddInt32(&numDroppedPackets, 1) + numDroppedPackets.Add(1) } return drop }) @@ -114,7 +114,7 @@ var _ = Describe("Drop Tests", func() { Expect(b[0]).To(Equal(i)) } close(done) - numDropped := atomic.LoadInt32(&numDroppedPackets) + numDropped := numDroppedPackets.Load() fmt.Fprintf(GinkgoWriter, "Dropped %d packets.\n", numDropped) Expect(numDropped).To(BeNumerically(">", 0)) }) diff --git a/integrationtests/self/handshake_drop_test.go b/integrationtests/self/handshake_drop_test.go index ae4837715e4..a0f2347984a 100644 --- a/integrationtests/self/handshake_drop_test.go +++ b/integrationtests/self/handshake_drop_test.go @@ -194,15 +194,15 @@ var _ = Describe("Handshake drop tests", func() { Context(app.name, func() { It(fmt.Sprintf("establishes a connection when the first packet is lost in %s direction", direction), func() { - var incoming, outgoing int32 + var incoming, outgoing atomic.Int32 startListenerAndProxy(func(d quicproxy.Direction, _ []byte) bool { var p int32 //nolint:exhaustive switch d { case quicproxy.DirectionIncoming: - p = atomic.AddInt32(&incoming, 1) + p = incoming.Add(1) case quicproxy.DirectionOutgoing: - p = atomic.AddInt32(&outgoing, 1) + p = outgoing.Add(1) } return p == 1 && d.Is(direction) }, doRetry, longCertChain) @@ -210,15 +210,15 @@ var _ = Describe("Handshake drop tests", func() { }) It(fmt.Sprintf("establishes a connection when the second packet is lost in %s direction", direction), func() { - var incoming, outgoing int32 + var incoming, outgoing atomic.Int32 startListenerAndProxy(func(d quicproxy.Direction, _ []byte) bool { var p int32 //nolint:exhaustive switch d { case quicproxy.DirectionIncoming: - p = atomic.AddInt32(&incoming, 1) + p = incoming.Add(1) case quicproxy.DirectionOutgoing: - p = atomic.AddInt32(&outgoing, 1) + p = outgoing.Add(1) } return p == 2 && d.Is(direction) }, doRetry, longCertChain) diff --git a/integrationtests/self/hotswap_test.go b/integrationtests/self/hotswap_test.go index ac75a49450e..232a13c329b 100644 --- a/integrationtests/self/hotswap_test.go +++ b/integrationtests/self/hotswap_test.go @@ -20,7 +20,7 @@ import ( type listenerWrapper struct { http3.QUICEarlyListener listenerClosed bool - count int32 + count atomic.Int32 } func (ln *listenerWrapper) Close() error { @@ -29,14 +29,18 @@ func (ln *listenerWrapper) Close() error { } func (ln *listenerWrapper) Faker() *fakeClosingListener { - atomic.AddInt32(&ln.count, 1) + ln.count.Add(1) ctx, cancel := context.WithCancel(context.Background()) - return &fakeClosingListener{ln, 0, ctx, cancel} + return &fakeClosingListener{ + listenerWrapper: ln, + ctx: ctx, + cancel: cancel, + } } type fakeClosingListener struct { *listenerWrapper - closed int32 + closed atomic.Bool ctx context.Context cancel context.CancelFunc } @@ -47,9 +51,9 @@ func (ln *fakeClosingListener) Accept(ctx context.Context) (quic.EarlyConnection } func (ln *fakeClosingListener) Close() error { - if atomic.CompareAndSwapInt32(&ln.closed, 0, 1) { + if ln.closed.CompareAndSwap(false, true) { ln.cancel() - if atomic.AddInt32(&ln.listenerWrapper.count, -1) == 0 { + if ln.listenerWrapper.count.Add(-1) == 0 { ln.listenerWrapper.Close() } } @@ -145,8 +149,8 @@ var _ = Describe("HTTP3 Server hotswap test", func() { // and only the fake listener should be closed Expect(server1.Close()).NotTo(HaveOccurred()) Eventually(stoppedServing1).Should(BeClosed()) - Expect(fake1.closed).To(Equal(int32(1))) - Expect(fake2.closed).To(Equal(int32(0))) + Expect(fake1.closed.Load()).To(BeTrue()) + Expect(fake2.closed.Load()).To(BeFalse()) Expect(ln.listenerClosed).ToNot(BeTrue()) Expect(client.Transport.(*http3.RoundTripper).Close()).NotTo(HaveOccurred()) @@ -161,7 +165,7 @@ var _ = Describe("HTTP3 Server hotswap test", func() { // close the other server - both the fake and the actual listeners must close now Expect(server2.Close()).NotTo(HaveOccurred()) Eventually(stoppedServing2).Should(BeClosed()) - Expect(fake2.closed).To(Equal(int32(1))) + Expect(fake2.closed.Load()).To(BeTrue()) Expect(ln.listenerClosed).To(BeTrue()) }) }) diff --git a/integrationtests/self/mitm_test.go b/integrationtests/self/mitm_test.go index a5f07f77a6d..0eb68d06b72 100644 --- a/integrationtests/self/mitm_test.go +++ b/integrationtests/self/mitm_test.go @@ -244,17 +244,17 @@ var _ = Describe("MITM test", func() { Context("corrupting packets", func() { const idleTimeout = time.Second - var numCorrupted, numPackets int32 + var numCorrupted, numPackets atomic.Int32 BeforeEach(func() { - numCorrupted = 0 - numPackets = 0 + numCorrupted.Store(0) + numPackets.Store(0) serverConfig.MaxIdleTimeout = idleTimeout }) AfterEach(func() { - num := atomic.LoadInt32(&numCorrupted) - fmt.Fprintf(GinkgoWriter, "Corrupted %d of %d packets.", num, atomic.LoadInt32(&numPackets)) + num := numCorrupted.Load() + fmt.Fprintf(GinkgoWriter, "Corrupted %d of %d packets.", num, numPackets.Load()) Expect(num).To(BeNumerically(">=", 1)) // If the packet containing the CONNECTION_CLOSE is corrupted, // we have to wait for the connection to time out. @@ -266,13 +266,13 @@ var _ = Describe("MITM test", func() { dropCb := func(dir quicproxy.Direction, raw []byte) bool { defer GinkgoRecover() if dir == quicproxy.DirectionIncoming { - atomic.AddInt32(&numPackets, 1) + numPackets.Add(1) if rand.Intn(interval) == 0 { pos := rand.Intn(len(raw)) raw[pos] = byte(rand.Intn(256)) _, err := clientTransport.WriteTo(raw, serverTransport.Conn.LocalAddr()) Expect(err).ToNot(HaveOccurred()) - atomic.AddInt32(&numCorrupted, 1) + numCorrupted.Add(1) return true } } @@ -286,13 +286,13 @@ var _ = Describe("MITM test", func() { dropCb := func(dir quicproxy.Direction, raw []byte) bool { defer GinkgoRecover() if dir == quicproxy.DirectionOutgoing { - atomic.AddInt32(&numPackets, 1) + numPackets.Add(1) if rand.Intn(interval) == 0 { pos := rand.Intn(len(raw)) raw[pos] = byte(rand.Intn(256)) _, err := serverTransport.WriteTo(raw, clientTransport.Conn.LocalAddr()) Expect(err).ToNot(HaveOccurred()) - atomic.AddInt32(&numCorrupted, 1) + numCorrupted.Add(1) return true } } diff --git a/integrationtests/self/timeout_test.go b/integrationtests/self/timeout_test.go index ddd0b973846..dd18c4ea3bc 100644 --- a/integrationtests/self/timeout_test.go +++ b/integrationtests/self/timeout_test.go @@ -22,12 +22,12 @@ type faultyConn struct { net.PacketConn MaxPackets int32 - counter int32 + counter atomic.Int32 } func (c *faultyConn) ReadFrom(p []byte) (int, net.Addr, error) { n, addr, err := c.PacketConn.ReadFrom(p) - counter := atomic.AddInt32(&c.counter, 1) + counter := c.counter.Add(1) if counter <= c.MaxPackets { return n, addr, err } @@ -35,7 +35,7 @@ func (c *faultyConn) ReadFrom(p []byte) (int, net.Addr, error) { } func (c *faultyConn) WriteTo(p []byte, addr net.Addr) (int, error) { - counter := atomic.AddInt32(&c.counter, 1) + counter := c.counter.Add(1) if counter <= c.MaxPackets { return c.PacketConn.WriteTo(p, addr) } diff --git a/integrationtests/self/zero_rtt_oldgo_test.go b/integrationtests/self/zero_rtt_oldgo_test.go index f42194bcc39..8d07ea256a3 100644 --- a/integrationtests/self/zero_rtt_oldgo_test.go +++ b/integrationtests/self/zero_rtt_oldgo_test.go @@ -26,8 +26,8 @@ import ( var _ = Describe("0-RTT", func() { rtt := scaleDuration(5 * time.Millisecond) - runCountingProxy := func(serverPort int) (*quicproxy.QuicProxy, *uint32) { - var num0RTTPackets uint32 // to be used as an atomic + runCountingProxy := func(serverPort int) (*quicproxy.QuicProxy, *atomic.Uint32) { + var num0RTTPackets atomic.Uint32 proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{ RemoteAddr: fmt.Sprintf("localhost:%d", serverPort), DelayPacket: func(_ quicproxy.Direction, data []byte) time.Duration { @@ -38,7 +38,7 @@ var _ = Describe("0-RTT", func() { hdr, _, rest, err := wire.ParsePacket(data) Expect(err).ToNot(HaveOccurred()) if hdr.Type == protocol.PacketType0RTT { - atomic.AddUint32(&num0RTTPackets, 1) + num0RTTPackets.Add(1) break } data = rest @@ -257,7 +257,7 @@ var _ = Describe("0-RTT", func() { Expect(numNewConnIDs).ToNot(BeZero()) } - num0RTT := atomic.LoadUint32(num0RTTPackets) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets()) @@ -348,10 +348,7 @@ var _ = Describe("0-RTT", func() { }) It("transfers 0-RTT data, when 0-RTT packets are lost", func() { - var ( - num0RTTPackets uint32 // to be used as an atomic - num0RTTDropped uint32 - ) + var num0RTTPackets, num0RTTDropped atomic.Uint32 tlsConf, clientConf := dialAndReceiveSessionTicket(nil) @@ -374,7 +371,7 @@ var _ = Describe("0-RTT", func() { hdr, _, _, err := wire.ParsePacket(data) Expect(err).ToNot(HaveOccurred()) if hdr.Type == protocol.PacketType0RTT { - atomic.AddUint32(&num0RTTPackets, 1) + num0RTTPackets.Add(1) } } return rtt / 2 @@ -389,7 +386,7 @@ var _ = Describe("0-RTT", func() { // drop 25% of the 0-RTT packets drop := mrand.Intn(4) == 0 if drop { - atomic.AddUint32(&num0RTTDropped, 1) + num0RTTDropped.Add(1) } return drop } @@ -401,8 +398,8 @@ var _ = Describe("0-RTT", func() { transfer0RTTData(ln, proxy.LocalPort(), protocol.DefaultConnectionIDLength, clientConf, nil, PRData) - num0RTT := atomic.LoadUint32(&num0RTTPackets) - numDropped := atomic.LoadUint32(&num0RTTDropped) + num0RTT := num0RTTPackets.Load() + numDropped := num0RTTDropped.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets. Dropped %d of those.", num0RTT, numDropped) Expect(numDropped).ToNot(BeZero()) Expect(num0RTT).ToNot(BeZero()) @@ -551,7 +548,7 @@ var _ = Describe("0-RTT", func() { check0RTTRejected(ln, proxy.LocalPort(), clientConf) // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := atomic.LoadUint32(num0RTTPackets) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) @@ -580,7 +577,7 @@ var _ = Describe("0-RTT", func() { check0RTTRejected(ln, proxy.LocalPort(), clientConf) // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := atomic.LoadUint32(num0RTTPackets) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) @@ -607,7 +604,7 @@ var _ = Describe("0-RTT", func() { check0RTTRejected(ln, proxy.LocalPort(), clientConf) // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := atomic.LoadUint32(num0RTTPackets) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) @@ -759,7 +756,7 @@ var _ = Describe("0-RTT", func() { Expect(conn.CloseWithError(0, "")).To(Succeed()) // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := atomic.LoadUint32(num0RTTPackets) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) @@ -851,7 +848,7 @@ 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) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets()) @@ -906,7 +903,7 @@ 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) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) diff --git a/integrationtests/self/zero_rtt_test.go b/integrationtests/self/zero_rtt_test.go index 3e9a0f601b6..7f8184a262b 100644 --- a/integrationtests/self/zero_rtt_test.go +++ b/integrationtests/self/zero_rtt_test.go @@ -56,8 +56,8 @@ func (m metadataClientSessionCache) Put(key string, session *tls.ClientSessionSt var _ = Describe("0-RTT", func() { rtt := scaleDuration(5 * time.Millisecond) - runCountingProxy := func(serverPort int) (*quicproxy.QuicProxy, *uint32) { - var num0RTTPackets uint32 // to be used as an atomic + runCountingProxy := func(serverPort int) (*quicproxy.QuicProxy, *atomic.Uint32) { + var num0RTTPackets atomic.Uint32 proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{ RemoteAddr: fmt.Sprintf("localhost:%d", serverPort), DelayPacket: func(_ quicproxy.Direction, data []byte) time.Duration { @@ -68,7 +68,7 @@ var _ = Describe("0-RTT", func() { hdr, _, rest, err := wire.ParsePacket(data) Expect(err).ToNot(HaveOccurred()) if hdr.Type == protocol.PacketType0RTT { - atomic.AddUint32(&num0RTTPackets, 1) + num0RTTPackets.Add(1) break } data = rest @@ -289,7 +289,7 @@ var _ = Describe("0-RTT", func() { Expect(numNewConnIDs).ToNot(BeZero()) } - num0RTT := atomic.LoadUint32(num0RTTPackets) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets()) @@ -382,10 +382,7 @@ var _ = Describe("0-RTT", func() { }) It("transfers 0-RTT data, when 0-RTT packets are lost", func() { - var ( - num0RTTPackets uint32 // to be used as an atomic - num0RTTDropped uint32 - ) + var num0RTTPackets, num0RTTDropped atomic.Uint32 tlsConf := getTLSConfig() clientConf := getTLSClientConfig() @@ -410,7 +407,7 @@ var _ = Describe("0-RTT", func() { hdr, _, _, err := wire.ParsePacket(data) Expect(err).ToNot(HaveOccurred()) if hdr.Type == protocol.PacketType0RTT { - atomic.AddUint32(&num0RTTPackets, 1) + num0RTTPackets.Add(1) } } return rtt / 2 @@ -425,7 +422,7 @@ var _ = Describe("0-RTT", func() { // drop 25% of the 0-RTT packets drop := mrand.Intn(4) == 0 if drop { - atomic.AddUint32(&num0RTTDropped, 1) + num0RTTDropped.Add(1) } return drop } @@ -437,8 +434,8 @@ var _ = Describe("0-RTT", func() { transfer0RTTData(ln, proxy.LocalPort(), protocol.DefaultConnectionIDLength, clientConf, nil, PRData) - num0RTT := atomic.LoadUint32(&num0RTTPackets) - numDropped := atomic.LoadUint32(&num0RTTDropped) + num0RTT := num0RTTPackets.Load() + numDropped := num0RTTDropped.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets. Dropped %d of those.", num0RTT, numDropped) Expect(numDropped).ToNot(BeZero()) Expect(num0RTT).ToNot(BeZero()) @@ -594,7 +591,7 @@ var _ = Describe("0-RTT", func() { check0RTTRejected(ln, proxy.LocalPort(), clientConf) // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := atomic.LoadUint32(num0RTTPackets) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) @@ -627,7 +624,7 @@ var _ = Describe("0-RTT", func() { check0RTTRejected(ln, proxy.LocalPort(), clientConf) // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := atomic.LoadUint32(num0RTTPackets) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) @@ -656,7 +653,7 @@ var _ = Describe("0-RTT", func() { check0RTTRejected(ln, proxy.LocalPort(), clientConf) // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := atomic.LoadUint32(num0RTTPackets) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) @@ -812,7 +809,7 @@ var _ = Describe("0-RTT", func() { Expect(conn.CloseWithError(0, "")).To(Succeed()) // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := atomic.LoadUint32(num0RTTPackets) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) @@ -981,7 +978,7 @@ var _ = Describe("0-RTT", func() { Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) Expect(conn.CloseWithError(0, "")).To(Succeed()) Expect(receivedMessage).To(Equal(sentMessage)) - num0RTT := atomic.LoadUint32(num0RTTPackets) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets()) @@ -1038,7 +1035,7 @@ 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) + num0RTT := num0RTTPackets.Load() fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) Expect(num0RTT).ToNot(BeZero()) Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) diff --git a/integrationtests/tools/proxy/proxy_test.go b/integrationtests/tools/proxy/proxy_test.go index c9b80be5cc4..c51a436a5ff 100644 --- a/integrationtests/tools/proxy/proxy_test.go +++ b/integrationtests/tools/proxy/proxy_test.go @@ -141,7 +141,7 @@ var _ = Describe("QUIC Proxy", func() { Context("Proxy tests", func() { var ( serverConn *net.UDPConn - serverNumPacketsSent int32 + serverNumPacketsSent atomic.Int32 serverReceivedPackets chan packetData clientConn *net.UDPConn proxy *QuicProxy @@ -159,9 +159,9 @@ var _ = Describe("QUIC Proxy", func() { BeforeEach(func() { stoppedReading = make(chan struct{}) serverReceivedPackets = make(chan packetData, 100) - atomic.StoreInt32(&serverNumPacketsSent, 0) + serverNumPacketsSent.Store(0) - // setup a dump UDP server + // set up a dump UDP server // in production this would be a QUIC server raddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0") Expect(err).ToNot(HaveOccurred()) @@ -181,7 +181,7 @@ var _ = Describe("QUIC Proxy", func() { data := buf[0:n] serverReceivedPackets <- packetData(data) // echo the packet - atomic.AddInt32(&serverNumPacketsSent, 1) + serverNumPacketsSent.Add(1) serverConn.WriteToUDP(data, addr) } }() @@ -236,7 +236,7 @@ var _ = Describe("QUIC Proxy", func() { }() Eventually(serverReceivedPackets).Should(HaveLen(2)) - Expect(atomic.LoadInt32(&serverNumPacketsSent)).To(BeEquivalentTo(2)) + Expect(serverNumPacketsSent.Load()).To(BeEquivalentTo(2)) Eventually(clientReceivedPackets).Should(HaveLen(2)) Expect(string(<-clientReceivedPackets)).To(ContainSubstring("foobar")) Expect(string(<-clientReceivedPackets)).To(ContainSubstring("decafbad")) @@ -245,14 +245,14 @@ var _ = Describe("QUIC Proxy", func() { Context("Drop Callbacks", func() { It("drops incoming packets", func() { - var counter int32 + var counter atomic.Int32 opts := &Opts{ RemoteAddr: serverConn.LocalAddr().String(), DropPacket: func(d Direction, _ []byte) bool { if d != DirectionIncoming { return false } - return atomic.AddInt32(&counter, 1)%2 == 1 + return counter.Add(1)%2 == 1 }, } startProxy(opts) @@ -267,14 +267,14 @@ var _ = Describe("QUIC Proxy", func() { It("drops outgoing packets", func() { const numPackets = 6 - var counter int32 + var counter atomic.Int32 opts := &Opts{ RemoteAddr: serverConn.LocalAddr().String(), DropPacket: func(d Direction, _ []byte) bool { if d != DirectionOutgoing { return false } - return atomic.AddInt32(&counter, 1)%2 == 1 + return counter.Add(1)%2 == 1 }, } startProxy(opts) @@ -315,7 +315,7 @@ var _ = Describe("QUIC Proxy", func() { } It("delays incoming packets", func() { - var counter int32 + var counter atomic.Int32 opts := &Opts{ RemoteAddr: serverConn.LocalAddr().String(), // delay packet 1 by 200 ms @@ -325,7 +325,7 @@ var _ = Describe("QUIC Proxy", func() { if d == DirectionOutgoing { return 0 } - p := atomic.AddInt32(&counter, 1) + p := counter.Add(1) return time.Duration(p) * delay }, } @@ -349,7 +349,7 @@ var _ = Describe("QUIC Proxy", func() { }) It("handles reordered packets", func() { - var counter int32 + var counter atomic.Int32 opts := &Opts{ RemoteAddr: serverConn.LocalAddr().String(), // delay packet 1 by 600 ms @@ -359,7 +359,7 @@ var _ = Describe("QUIC Proxy", func() { if d == DirectionOutgoing { return 0 } - p := atomic.AddInt32(&counter, 1) + p := counter.Add(1) return 600*time.Millisecond - time.Duration(p-1)*delay }, } @@ -407,7 +407,7 @@ var _ = Describe("QUIC Proxy", func() { It("delays outgoing packets", func() { const numPackets = 3 - var counter int32 + var counter atomic.Int32 opts := &Opts{ RemoteAddr: serverConn.LocalAddr().String(), // delay packet 1 by 200 ms @@ -417,7 +417,7 @@ var _ = Describe("QUIC Proxy", func() { if d == DirectionIncoming { return 0 } - p := atomic.AddInt32(&counter, 1) + p := counter.Add(1) return time.Duration(p) * delay }, } From 1bcec709781fcfb0bd653a9d6e5dcc550f0469c8 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 25 Oct 2023 12:03:41 +0700 Subject: [PATCH 094/225] ci: run linter on all supported Go versions (#4126) --- .github/workflows/lint.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1d56486144e..fd735c9b7ee 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/setup-go@v4 with: skip-pkg-cache: true - go-version: "1.20.x" + go-version: "1.21.x" - name: Check that no non-test files import Ginkgo or Gomega run: .github/workflows/no_ginkgo.sh - name: Check for //go:build ignore in .go files @@ -36,11 +36,16 @@ jobs: go mod vendor golangci-lint: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + go: [ "1.20.x", "1.21.x" ] + name: golangci-lint (Go ${{ matrix.go }}) steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v4 with: - go-version: "1.20.x" + go-version: ${{ matrix.go }} - name: golangci-lint (Linux) uses: golangci/golangci-lint-action@v3 with: From 746290b78ae49dd5e1c1e34cb4314350602a8c88 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 25 Oct 2023 22:20:23 +0700 Subject: [PATCH 095/225] never allow 0-RTT when using Dial, even if the session ticket allows it (#4125) When resuming a TLS session using Dial (and not DialEarly), 0-RTT should be disabled at the TLS layer, even if the session ticket allows for 0-RTT resumption. This bug is not critical, since Dial doesn't return an EarlyConnection, so the client wouldn't be able to actually send 0-RTT data in practice. --- go.mod | 2 +- go.sum | 4 +-- integrationtests/gomodvendor/go.sum | 4 +-- integrationtests/self/zero_rtt_oldgo_test.go | 31 ++++++++++++++++++ integrationtests/self/zero_rtt_test.go | 33 ++++++++++++++++++++ internal/handshake/crypto_setup.go | 16 ++++++++-- internal/handshake/crypto_setup_test.go | 2 +- internal/qtls/client_session_cache.go | 6 ++-- internal/qtls/client_session_cache_test.go | 5 ++- internal/qtls/go120.go | 2 +- internal/qtls/go121.go | 2 +- 11 files changed, 93 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 0a56346309e..238490916cf 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/onsi/ginkgo/v2 v2.9.5 github.com/onsi/gomega v1.27.6 github.com/quic-go/qpack v0.4.0 - github.com/quic-go/qtls-go1-20 v0.3.4 + github.com/quic-go/qtls-go1-20 v0.4.0 go.uber.org/mock v0.3.0 golang.org/x/crypto v0.4.0 golang.org/x/exp v0.0.0-20221205204356-47842c84f3db diff --git a/go.sum b/go.sum index 62b640db008..89f4f3b53c4 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,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.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/quic-go/qtls-go1-20 v0.4.0 h1:irfww1426oQ9Nbro3DsxySpIwVmoxRS1LCA9RL73C8Y= +github.com/quic-go/qtls-go1-20 v0.4.0/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= diff --git a/integrationtests/gomodvendor/go.sum b/integrationtests/gomodvendor/go.sum index 29427a8ce82..06185fcec21 100644 --- a/integrationtests/gomodvendor/go.sum +++ b/integrationtests/gomodvendor/go.sum @@ -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.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/quic-go/qtls-go1-20 v0.4.0 h1:irfww1426oQ9Nbro3DsxySpIwVmoxRS1LCA9RL73C8Y= +github.com/quic-go/qtls-go1-20 v0.4.0/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= diff --git a/integrationtests/self/zero_rtt_oldgo_test.go b/integrationtests/self/zero_rtt_oldgo_test.go index 8d07ea256a3..aea54271c62 100644 --- a/integrationtests/self/zero_rtt_oldgo_test.go +++ b/integrationtests/self/zero_rtt_oldgo_test.go @@ -482,6 +482,37 @@ var _ = Describe("0-RTT", func() { Expect(zeroRTTPackets[0]).To(BeNumerically(">=", protocol.PacketNumber(5))) }) + It("doesn't use 0-RTT when Dial is used for the resumed connection", func() { + tlsConf, clientConf := dialAndReceiveSessionTicket(nil) + + ln, err := quic.ListenAddrEarly( + "localhost:0", + tlsConf, + getQuicConfig(&quic.Config{Allow0RTT: true}), + ) + Expect(err).ToNot(HaveOccurred()) + defer ln.Close() + proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) + defer proxy.Close() + + conn, err := quic.DialAddr( + context.Background(), + fmt.Sprintf("localhost:%d", proxy.LocalPort()), + clientConf, + getQuicConfig(nil), + ) + Expect(err).ToNot(HaveOccurred()) + defer conn.CloseWithError(0, "") + Expect(conn.ConnectionState().TLS.DidResume).To(BeTrue()) + Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) + Expect(num0RTTPackets.Load()).To(BeZero()) + + serverConn, err := ln.Accept(context.Background()) + Expect(err).ToNot(HaveOccurred()) + Expect(serverConn.ConnectionState().TLS.DidResume).To(BeTrue()) + Expect(serverConn.ConnectionState().Used0RTT).To(BeFalse()) + }) + It("doesn't reject 0-RTT when the server's transport stream limit increased", func() { const maxStreams = 1 tlsConf, clientConf := dialAndReceiveSessionTicket(getQuicConfig(&quic.Config{ diff --git a/integrationtests/self/zero_rtt_test.go b/integrationtests/self/zero_rtt_test.go index 7f8184a262b..c0fc5325ff0 100644 --- a/integrationtests/self/zero_rtt_test.go +++ b/integrationtests/self/zero_rtt_test.go @@ -520,6 +520,39 @@ var _ = Describe("0-RTT", func() { Expect(zeroRTTPackets[0]).To(BeNumerically(">=", protocol.PacketNumber(5))) }) + It("doesn't use 0-RTT when Dial is used for the resumed connection", func() { + tlsConf := getTLSConfig() + clientConf := getTLSClientConfig() + dialAndReceiveSessionTicket(tlsConf, getQuicConfig(nil), clientConf) + + ln, err := quic.ListenAddrEarly( + "localhost:0", + tlsConf, + getQuicConfig(&quic.Config{Allow0RTT: true}), + ) + Expect(err).ToNot(HaveOccurred()) + defer ln.Close() + proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) + defer proxy.Close() + + conn, err := quic.DialAddr( + context.Background(), + fmt.Sprintf("localhost:%d", proxy.LocalPort()), + clientConf, + getQuicConfig(nil), + ) + Expect(err).ToNot(HaveOccurred()) + defer conn.CloseWithError(0, "") + Expect(conn.ConnectionState().TLS.DidResume).To(BeTrue()) + Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) + Expect(num0RTTPackets.Load()).To(BeZero()) + + serverConn, err := ln.Accept(context.Background()) + Expect(err).ToNot(HaveOccurred()) + Expect(serverConn.ConnectionState().TLS.DidResume).To(BeTrue()) + Expect(serverConn.ConnectionState().Used0RTT).To(BeFalse()) + }) + It("doesn't reject 0-RTT when the server's transport stream limit increased", func() { const maxStreams = 1 tlsConf := getTLSConfig() diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index cae02873c83..7090fcca3b5 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -96,6 +96,7 @@ func NewCryptoSetupClient( quicConf := &qtls.QUICConfig{TLSConfig: tlsConf} qtls.SetupConfigForClient(quicConf, cs.marshalDataForSessionState, cs.handleDataFromSessionState) cs.tlsConf = tlsConf + cs.allow0RTT = enable0RTT cs.conn = qtls.QUICClient(quicConf) cs.conn.SetTransportParameters(cs.ourParams.Marshal(protocol.PerspectiveClient)) @@ -316,13 +317,20 @@ func (h *cryptoSetup) marshalDataForSessionState() []byte { return h.peerParams.MarshalForSessionTicket(b) } -func (h *cryptoSetup) handleDataFromSessionState(data []byte) { +func (h *cryptoSetup) handleDataFromSessionState(data []byte) (allowEarlyData bool) { tp, err := h.handleDataFromSessionStateImpl(data) if err != nil { h.logger.Debugf("Restoring of transport parameters from session ticket failed: %s", err.Error()) return } - h.zeroRTTParameters = tp + // The session ticket might have been saved from a connection that allowed 0-RTT, + // and therefore contain transport parameters. + // Only use them if 0-RTT is actually used on the new connection. + if tp != nil && h.allow0RTT { + h.zeroRTTParameters = tp + return true + } + return false } func (h *cryptoSetup) handleDataFromSessionStateImpl(data []byte) (*wire.TransportParameters, error) { @@ -383,7 +391,9 @@ func (h *cryptoSetup) GetSessionTicket() ([]byte, error) { } // 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. +// It reads parameters from the session ticket and checks whether to accept 0-RTT if the session ticket enabled 0-RTT. +// Note that the fact that the session ticket allows 0-RTT doesn't mean that the actual TLS handshake enables 0-RTT: +// A client may use a 0-RTT enabled session to resume a TLS session without using 0-RTT. func (h *cryptoSetup) handleSessionTicket(sessionTicketData []byte, using0RTT bool) bool { var t sessionTicket if err := t.Unmarshal(sessionTicketData, using0RTT); err != nil { diff --git a/internal/handshake/crypto_setup_test.go b/internal/handshake/crypto_setup_test.go index 9b2844f703b..b32d12a33e5 100644 --- a/internal/handshake/crypto_setup_test.go +++ b/internal/handshake/crypto_setup_test.go @@ -450,8 +450,8 @@ var _ = Describe("Crypto Setup TLS", func() { Eventually(receivedSessionTicket).Should(BeClosed()) 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(clientRTTStats.SmoothedRTT()).To(Equal(clientRTT)) Expect(serverRTTStats.SmoothedRTT()).To(Equal(serverRTT)) } }) diff --git a/internal/qtls/client_session_cache.go b/internal/qtls/client_session_cache.go index 519895ee624..336d6035af9 100644 --- a/internal/qtls/client_session_cache.go +++ b/internal/qtls/client_session_cache.go @@ -8,7 +8,7 @@ import ( type clientSessionCache struct { getData func() []byte - setData func([]byte) + setData func([]byte) (allowEarlyData bool) wrapped tls.ClientSessionCache } @@ -46,10 +46,12 @@ func (c clientSessionCache) Get(key string) (*tls.ClientSessionState, bool) { c.wrapped.Put(key, nil) return nil, false } + var earlyData bool // restore QUIC transport parameters and RTT stored in state.Extra if extra := findExtraData(state.Extra); extra != nil { - c.setData(extra) + earlyData = c.setData(extra) } + state.EarlyData = earlyData session, err := tls.NewResumptionState(ticket, state) if err != nil { // It's not clear why this would error. diff --git a/internal/qtls/client_session_cache_test.go b/internal/qtls/client_session_cache_test.go index a299551a29d..6af192935fa 100644 --- a/internal/qtls/client_session_cache_test.go +++ b/internal/qtls/client_session_cache_test.go @@ -41,7 +41,10 @@ var _ = Describe("Client Session Cache", func() { ClientSessionCache: &clientSessionCache{ wrapped: tls.NewLRUClientSessionCache(10), getData: func() []byte { return []byte("session") }, - setData: func(data []byte) { restored <- data }, + setData: func(data []byte) bool { + restored <- data + return true + }, }, } conn, err := tls.Dial( diff --git a/internal/qtls/go120.go b/internal/qtls/go120.go index 898f03526c8..7e7eee1ea3a 100644 --- a/internal/qtls/go120.go +++ b/internal/qtls/go120.go @@ -52,7 +52,7 @@ func SetupConfigForServer(conf *QUICConfig, enable0RTT bool, getDataForSessionTi } } -func SetupConfigForClient(conf *QUICConfig, getDataForSessionState func() []byte, setDataFromSessionState func([]byte)) { +func SetupConfigForClient(conf *QUICConfig, getDataForSessionState func() []byte, setDataFromSessionState func([]byte) bool) { conf.ExtraConfig = &qtls.ExtraConfig{ GetAppDataForSessionState: getDataForSessionState, SetAppDataFromSessionState: setDataFromSessionState, diff --git a/internal/qtls/go121.go b/internal/qtls/go121.go index 65a274ac0a7..35a52ce09b6 100644 --- a/internal/qtls/go121.go +++ b/internal/qtls/go121.go @@ -93,7 +93,7 @@ func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, hand } } -func SetupConfigForClient(qconf *QUICConfig, getData func() []byte, setData func([]byte)) { +func SetupConfigForClient(qconf *QUICConfig, getData func() []byte, setData func([]byte) bool) { conf := qconf.TLSConfig if conf.ClientSessionCache != nil { origCache := conf.ClientSessionCache From e2622bfad865bf4633fb752187c9663402515c6f Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 25 Oct 2023 23:49:53 +0700 Subject: [PATCH 096/225] reject ClientHellos that offer TLS versions older than 1.3 (for Go 1.20) (#4130) --- go.mod | 2 +- go.sum | 4 ++-- integrationtests/gomodvendor/go.sum | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 238490916cf..c2a45a2c02a 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/onsi/ginkgo/v2 v2.9.5 github.com/onsi/gomega v1.27.6 github.com/quic-go/qpack v0.4.0 - github.com/quic-go/qtls-go1-20 v0.4.0 + github.com/quic-go/qtls-go1-20 v0.4.1 go.uber.org/mock v0.3.0 golang.org/x/crypto v0.4.0 golang.org/x/exp v0.0.0-20221205204356-47842c84f3db diff --git a/go.sum b/go.sum index 89f4f3b53c4..01249e3cecb 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,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.4.0 h1:irfww1426oQ9Nbro3DsxySpIwVmoxRS1LCA9RL73C8Y= -github.com/quic-go/qtls-go1-20 v0.4.0/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= +github.com/quic-go/qtls-go1-20 v0.4.1/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= diff --git a/integrationtests/gomodvendor/go.sum b/integrationtests/gomodvendor/go.sum index 06185fcec21..d65b491abbd 100644 --- a/integrationtests/gomodvendor/go.sum +++ b/integrationtests/gomodvendor/go.sum @@ -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.4.0 h1:irfww1426oQ9Nbro3DsxySpIwVmoxRS1LCA9RL73C8Y= -github.com/quic-go/qtls-go1-20 v0.4.0/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= +github.com/quic-go/qtls-go1-20 v0.4.1/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= From d309060cded7aea6c3620c1238095e9a72175ecc Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 27 Oct 2023 12:22:20 +0700 Subject: [PATCH 097/225] handshake: clone the tls.Config returned by GetConfigForClient (#4133) We modify this tls.Config, so we should clone it first. Otherwise, this could cause conflicts with how the application is using that config. --- internal/handshake/crypto_setup.go | 1 + internal/handshake/crypto_setup_test.go | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index 7090fcca3b5..e15aad54acb 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -147,6 +147,7 @@ func addConnToClientHelloInfo(conf *tls.Config, localAddr, remoteAddr net.Addr) info.Conn = &conn{localAddr: localAddr, remoteAddr: remoteAddr} c, err := gcfc(info) if c != nil { + c = c.Clone() // We're returning a tls.Config here, so we need to apply this recursively. addConnToClientHelloInfo(c, localAddr, remoteAddr) } diff --git a/internal/handshake/crypto_setup_test.go b/internal/handshake/crypto_setup_test.go index b32d12a33e5..21278339303 100644 --- a/internal/handshake/crypto_setup_test.go +++ b/internal/handshake/crypto_setup_test.go @@ -8,6 +8,7 @@ import ( "crypto/x509/pkix" "math/big" "net" + "reflect" "runtime" "strings" "time" @@ -148,15 +149,17 @@ var _ = Describe("Crypto Setup TLS", func() { It("wraps GetConfigForClient, recursively", func() { var localAddr, remoteAddr net.Addr tlsConf := &tls.Config{} + var innerConf *tls.Config + getCert := func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { //nolint:unparam + localAddr = info.Conn.LocalAddr() + remoteAddr = info.Conn.RemoteAddr() + cert := generateCert() + return &cert, nil + } tlsConf.GetConfigForClient = func(info *tls.ClientHelloInfo) (*tls.Config, error) { - conf := tlsConf.Clone() - conf.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { - localAddr = info.Conn.LocalAddr() - remoteAddr = info.Conn.RemoteAddr() - cert := generateCert() - return &cert, nil - } - return conf, nil + innerConf = tlsConf.Clone() + innerConf.GetCertificate = getCert + return innerConf, nil } addConnToClientHelloInfo(tlsConf, local, remote) conf, err := tlsConf.GetConfigForClient(&tls.ClientHelloInfo{}) @@ -165,6 +168,8 @@ var _ = Describe("Crypto Setup TLS", func() { Expect(err).ToNot(HaveOccurred()) Expect(localAddr).To(Equal(local)) Expect(remoteAddr).To(Equal(remote)) + // make sure that the tls.Config returned by GetConfigForClient isn't modified + Expect(reflect.ValueOf(innerConf.GetCertificate).Pointer() == reflect.ValueOf(getCert).Pointer()).To(BeTrue()) }) }) From ef800d6f7137e281f347c0d4a363fa8ed629cd9b Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 27 Oct 2023 12:35:07 +0700 Subject: [PATCH 098/225] handshake: set MinVersion on the Config returned by GetConfigForClient (#4134) --- internal/handshake/crypto_setup.go | 2 ++ internal/handshake/crypto_setup_test.go | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index e15aad54acb..c5787e86a6d 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -148,6 +148,8 @@ func addConnToClientHelloInfo(conf *tls.Config, localAddr, remoteAddr net.Addr) c, err := gcfc(info) if c != nil { c = c.Clone() + // This won't be necessary anymore once https://github.com/golang/go/issues/63722 is accepted. + c.MinVersion = tls.VersionTLS13 // We're returning a tls.Config here, so we need to apply this recursively. addConnToClientHelloInfo(c, localAddr, remoteAddr) } diff --git a/internal/handshake/crypto_setup_test.go b/internal/handshake/crypto_setup_test.go index 21278339303..4e92118a13b 100644 --- a/internal/handshake/crypto_setup_test.go +++ b/internal/handshake/crypto_setup_test.go @@ -140,10 +140,12 @@ var _ = Describe("Crypto Setup TLS", func() { }, } addConnToClientHelloInfo(tlsConf, local, remote) - _, err := tlsConf.GetConfigForClient(&tls.ClientHelloInfo{}) + conf, err := tlsConf.GetConfigForClient(&tls.ClientHelloInfo{}) Expect(err).ToNot(HaveOccurred()) Expect(localAddr).To(Equal(local)) Expect(remoteAddr).To(Equal(remote)) + Expect(conf).ToNot(BeNil()) + Expect(conf.MinVersion).To(BeEquivalentTo(tls.VersionTLS13)) }) It("wraps GetConfigForClient, recursively", func() { @@ -158,18 +160,23 @@ var _ = Describe("Crypto Setup TLS", func() { } tlsConf.GetConfigForClient = func(info *tls.ClientHelloInfo) (*tls.Config, error) { innerConf = tlsConf.Clone() + // set the MaxVersion, so we can check that quic-go doesn't overwrite the user's config + innerConf.MaxVersion = tls.VersionTLS12 innerConf.GetCertificate = getCert return innerConf, nil } addConnToClientHelloInfo(tlsConf, local, remote) conf, err := tlsConf.GetConfigForClient(&tls.ClientHelloInfo{}) Expect(err).ToNot(HaveOccurred()) + Expect(conf).ToNot(BeNil()) + Expect(conf.MinVersion).To(BeEquivalentTo(tls.VersionTLS13)) _, err = conf.GetCertificate(&tls.ClientHelloInfo{}) Expect(err).ToNot(HaveOccurred()) Expect(localAddr).To(Equal(local)) Expect(remoteAddr).To(Equal(remote)) // make sure that the tls.Config returned by GetConfigForClient isn't modified Expect(reflect.ValueOf(innerConf.GetCertificate).Pointer() == reflect.ValueOf(getCert).Pointer()).To(BeTrue()) + Expect(innerConf.MaxVersion).To(BeEquivalentTo(tls.VersionTLS12)) }) }) From dda63b90ebbbff4ef4e5af0fb9090171320457c3 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 27 Oct 2023 13:10:13 +0700 Subject: [PATCH 099/225] don't close established connections on Listener.Close, when using a Transport (#4072) * don't close established connections on Listener.Close * only close once --- integrationtests/self/deadline_test.go | 26 +++++---- integrationtests/self/handshake_test.go | 7 ++- integrationtests/self/resumption_test.go | 30 ++++++---- integrationtests/self/timeout_test.go | 12 +++- integrationtests/self/uni_stream_test.go | 1 + mock_packet_handler_manager_test.go | 36 ------------ packet_handler_map.go | 17 ------ packet_handler_map_test.go | 17 ------ server.go | 62 +++++++++----------- server_test.go | 72 +++++++++++++++++++----- transport.go | 6 +- transport_test.go | 1 - 12 files changed, 136 insertions(+), 151 deletions(-) diff --git a/integrationtests/self/deadline_test.go b/integrationtests/self/deadline_test.go index b165aff0e90..43e3b2473f1 100644 --- a/integrationtests/self/deadline_test.go +++ b/integrationtests/self/deadline_test.go @@ -14,7 +14,7 @@ import ( ) var _ = Describe("Stream deadline tests", func() { - setup := func() (*quic.Listener, quic.Stream, quic.Stream) { + setup := func() (serverStr, clientStr quic.Stream, close func()) { server, err := quic.ListenAddr("localhost:0", getTLSConfig(), getQuicConfig(nil)) Expect(err).ToNot(HaveOccurred()) strChan := make(chan quic.SendStream) @@ -36,19 +36,21 @@ var _ = Describe("Stream deadline tests", func() { getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) - clientStr, err := conn.OpenStream() + clientStr, err = conn.OpenStream() Expect(err).ToNot(HaveOccurred()) _, err = clientStr.Write([]byte{0}) // need to write one byte so the server learns about the stream Expect(err).ToNot(HaveOccurred()) - var serverStr quic.Stream Eventually(strChan).Should(Receive(&serverStr)) - return server, serverStr, clientStr + return serverStr, clientStr, func() { + Expect(server.Close()).To(Succeed()) + Expect(conn.CloseWithError(0, "")).To(Succeed()) + } } Context("read deadlines", func() { It("completes a transfer when the deadline is set", func() { - server, serverStr, clientStr := setup() - defer server.Close() + serverStr, clientStr, closeFn := setup() + defer closeFn() const timeout = time.Millisecond done := make(chan struct{}) @@ -82,8 +84,8 @@ var _ = Describe("Stream deadline tests", func() { }) It("completes a transfer when the deadline is set concurrently", func() { - server, serverStr, clientStr := setup() - defer server.Close() + serverStr, clientStr, closeFn := setup() + defer closeFn() const timeout = time.Millisecond go func() { @@ -132,8 +134,8 @@ var _ = Describe("Stream deadline tests", func() { Context("write deadlines", func() { It("completes a transfer when the deadline is set", func() { - server, serverStr, clientStr := setup() - defer server.Close() + serverStr, clientStr, closeFn := setup() + defer closeFn() const timeout = time.Millisecond done := make(chan struct{}) @@ -165,8 +167,8 @@ var _ = Describe("Stream deadline tests", func() { }) It("completes a transfer when the deadline is set concurrently", func() { - server, serverStr, clientStr := setup() - defer server.Close() + serverStr, clientStr, closeFn := setup() + defer closeFn() const timeout = time.Millisecond readDone := make(chan struct{}) diff --git a/integrationtests/self/handshake_test.go b/integrationtests/self/handshake_test.go index d4f65a12b82..141487abf9b 100644 --- a/integrationtests/self/handshake_test.go +++ b/integrationtests/self/handshake_test.go @@ -152,13 +152,14 @@ var _ = Describe("Handshake tests", func() { Context("Certificate validation", func() { It("accepts the certificate", func() { runServer(getTLSConfig()) - _, err := quic.DialAddr( + conn, err := quic.DialAddr( context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), getTLSClientConfig(), getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) + conn.CloseWithError(0, "") }) It("has the right local and remote address on the tls.Config.GetConfigForClient ClientHelloInfo.Conn", func() { @@ -187,6 +188,7 @@ var _ = Describe("Handshake tests", func() { getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) + defer conn.CloseWithError(0, "") Eventually(done).Should(BeClosed()) Expect(server.Addr()).To(Equal(local)) Expect(conn.LocalAddr().(*net.UDPAddr).Port).To(Equal(remote.(*net.UDPAddr).Port)) @@ -196,13 +198,14 @@ var _ = Describe("Handshake tests", func() { It("works with a long certificate chain", func() { runServer(getTLSConfigWithLongCertChain()) - _, err := quic.DialAddr( + conn, err := quic.DialAddr( context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), getTLSClientConfig(), getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) + conn.CloseWithError(0, "") }) It("errors if the server name doesn't match", func() { diff --git a/integrationtests/self/resumption_test.go b/integrationtests/self/resumption_test.go index bedf04704b0..23f241be7ac 100644 --- a/integrationtests/self/resumption_test.go +++ b/integrationtests/self/resumption_test.go @@ -52,22 +52,23 @@ var _ = Describe("TLS session resumption", func() { cache := newClientSessionCache(tls.NewLRUClientSessionCache(10), gets, puts) tlsConf := getTLSClientConfig() tlsConf.ClientSessionCache = cache - conn, err := quic.DialAddr( + conn1, err := quic.DialAddr( context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) + defer conn1.CloseWithError(0, "") var sessionKey string Eventually(puts).Should(Receive(&sessionKey)) - Expect(conn.ConnectionState().TLS.DidResume).To(BeFalse()) + Expect(conn1.ConnectionState().TLS.DidResume).To(BeFalse()) serverConn, err := server.Accept(context.Background()) Expect(err).ToNot(HaveOccurred()) Expect(serverConn.ConnectionState().TLS.DidResume).To(BeFalse()) - conn, err = quic.DialAddr( + conn2, err := quic.DialAddr( context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, @@ -75,11 +76,12 @@ var _ = Describe("TLS session resumption", func() { ) Expect(err).ToNot(HaveOccurred()) Expect(gets).To(Receive(Equal(sessionKey))) - Expect(conn.ConnectionState().TLS.DidResume).To(BeTrue()) + Expect(conn2.ConnectionState().TLS.DidResume).To(BeTrue()) serverConn, err = server.Accept(context.Background()) Expect(err).ToNot(HaveOccurred()) Expect(serverConn.ConnectionState().TLS.DidResume).To(BeTrue()) + conn2.CloseWithError(0, "") }) It("doesn't use session resumption, if the config disables it", func() { @@ -94,15 +96,16 @@ var _ = Describe("TLS session resumption", func() { cache := newClientSessionCache(tls.NewLRUClientSessionCache(10), gets, puts) tlsConf := getTLSClientConfig() tlsConf.ClientSessionCache = cache - conn, err := quic.DialAddr( + conn1, err := quic.DialAddr( context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) + defer conn1.CloseWithError(0, "") Consistently(puts).ShouldNot(Receive()) - Expect(conn.ConnectionState().TLS.DidResume).To(BeFalse()) + Expect(conn1.ConnectionState().TLS.DidResume).To(BeFalse()) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() @@ -110,14 +113,15 @@ var _ = Describe("TLS session resumption", func() { Expect(err).ToNot(HaveOccurred()) Expect(serverConn.ConnectionState().TLS.DidResume).To(BeFalse()) - conn, err = quic.DialAddr( + conn2, err := quic.DialAddr( context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) - Expect(conn.ConnectionState().TLS.DidResume).To(BeFalse()) + Expect(conn2.ConnectionState().TLS.DidResume).To(BeFalse()) + defer conn2.CloseWithError(0, "") serverConn, err = server.Accept(context.Background()) Expect(err).ToNot(HaveOccurred()) @@ -142,7 +146,7 @@ var _ = Describe("TLS session resumption", func() { cache := newClientSessionCache(tls.NewLRUClientSessionCache(10), gets, puts) tlsConf := getTLSClientConfig() tlsConf.ClientSessionCache = cache - conn, err := quic.DialAddr( + conn1, err := quic.DialAddr( context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, @@ -150,7 +154,8 @@ var _ = Describe("TLS session resumption", func() { ) Expect(err).ToNot(HaveOccurred()) Consistently(puts).ShouldNot(Receive()) - Expect(conn.ConnectionState().TLS.DidResume).To(BeFalse()) + Expect(conn1.ConnectionState().TLS.DidResume).To(BeFalse()) + defer conn1.CloseWithError(0, "") ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() @@ -158,14 +163,15 @@ var _ = Describe("TLS session resumption", func() { Expect(err).ToNot(HaveOccurred()) Expect(serverConn.ConnectionState().TLS.DidResume).To(BeFalse()) - conn, err = quic.DialAddr( + conn2, err := quic.DialAddr( context.Background(), fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, getQuicConfig(nil), ) Expect(err).ToNot(HaveOccurred()) - Expect(conn.ConnectionState().TLS.DidResume).To(BeFalse()) + Expect(conn2.ConnectionState().TLS.DidResume).To(BeFalse()) + defer conn2.CloseWithError(0, "") serverConn, err = server.Accept(context.Background()) Expect(err).ToNot(HaveOccurred()) diff --git a/integrationtests/self/timeout_test.go b/integrationtests/self/timeout_test.go index dd18c4ea3bc..da4c6883bb6 100644 --- a/integrationtests/self/timeout_test.go +++ b/integrationtests/self/timeout_test.go @@ -185,11 +185,13 @@ var _ = Describe("Timeout tests", func() { Expect(err).ToNot(HaveOccurred()) defer server.Close() + serverConnChan := make(chan quic.Connection, 1) serverConnClosed := make(chan struct{}) go func() { defer GinkgoRecover() conn, err := server.Accept(context.Background()) Expect(err).ToNot(HaveOccurred()) + serverConnChan <- conn conn.AcceptStream(context.Background()) // blocks until the connection is closed close(serverConnClosed) }() @@ -240,7 +242,7 @@ var _ = Describe("Timeout tests", func() { Consistently(serverConnClosed).ShouldNot(BeClosed()) // make the go routine return - Expect(server.Close()).To(Succeed()) + (<-serverConnChan).CloseWithError(0, "") Eventually(serverConnClosed).Should(BeClosed()) }) @@ -266,11 +268,13 @@ var _ = Describe("Timeout tests", func() { Expect(err).ToNot(HaveOccurred()) defer proxy.Close() + serverConnChan := make(chan quic.Connection, 1) serverConnClosed := make(chan struct{}) go func() { defer GinkgoRecover() conn, err := server.Accept(context.Background()) Expect(err).ToNot(HaveOccurred()) + serverConnChan <- conn <-conn.Context().Done() // block until the connection is closed close(serverConnClosed) }() @@ -309,7 +313,7 @@ var _ = Describe("Timeout tests", func() { Consistently(serverConnClosed).ShouldNot(BeClosed()) // make the go routine return - Expect(server.Close()).To(Succeed()) + (<-serverConnChan).CloseWithError(0, "") Eventually(serverConnClosed).Should(BeClosed()) }) }) @@ -325,11 +329,13 @@ var _ = Describe("Timeout tests", func() { Expect(err).ToNot(HaveOccurred()) defer server.Close() + serverConnChan := make(chan quic.Connection, 1) serverConnClosed := make(chan struct{}) go func() { defer GinkgoRecover() conn, err := server.Accept(context.Background()) Expect(err).ToNot(HaveOccurred()) + serverConnChan <- conn conn.AcceptStream(context.Background()) // blocks until the connection is closed close(serverConnClosed) }() @@ -370,7 +376,7 @@ var _ = Describe("Timeout tests", func() { _, err = str.Write([]byte("foobar")) checkTimeoutError(err) - Expect(server.Close()).To(Succeed()) + (<-serverConnChan).CloseWithError(0, "") Eventually(serverConnClosed).Should(BeClosed()) }) diff --git a/integrationtests/self/uni_stream_test.go b/integrationtests/self/uni_stream_test.go index a2fe4e50163..d47df35f647 100644 --- a/integrationtests/self/uni_stream_test.go +++ b/integrationtests/self/uni_stream_test.go @@ -142,5 +142,6 @@ var _ = Describe("Unidirectional Streams", func() { runReceivingPeer(client) <-done1 <-done2 + client.CloseWithError(0, "") }) }) diff --git a/mock_packet_handler_manager_test.go b/mock_packet_handler_manager_test.go index fafd43c9870..e3f1e00cef5 100644 --- a/mock_packet_handler_manager_test.go +++ b/mock_packet_handler_manager_test.go @@ -186,42 +186,6 @@ func (c *PacketHandlerManagerCloseCall) DoAndReturn(f func(error)) *PacketHandle return c } -// CloseServer mocks base method. -func (m *MockPacketHandlerManager) CloseServer() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "CloseServer") -} - -// CloseServer indicates an expected call of CloseServer. -func (mr *MockPacketHandlerManagerMockRecorder) CloseServer() *PacketHandlerManagerCloseServerCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseServer", reflect.TypeOf((*MockPacketHandlerManager)(nil).CloseServer)) - return &PacketHandlerManagerCloseServerCall{Call: call} -} - -// PacketHandlerManagerCloseServerCall wrap *gomock.Call -type PacketHandlerManagerCloseServerCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *PacketHandlerManagerCloseServerCall) Return() *PacketHandlerManagerCloseServerCall { - c.Call = c.Call.Return() - return c -} - -// Do rewrite *gomock.Call.Do -func (c *PacketHandlerManagerCloseServerCall) Do(f func()) *PacketHandlerManagerCloseServerCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *PacketHandlerManagerCloseServerCall) DoAndReturn(f func()) *PacketHandlerManagerCloseServerCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - // Get mocks base method. func (m *MockPacketHandlerManager) Get(arg0 protocol.ConnectionID) (packetHandler, bool) { m.ctrl.T.Helper() diff --git a/packet_handler_map.go b/packet_handler_map.go index 006eadf9218..ba62b1e54dd 100644 --- a/packet_handler_map.go +++ b/packet_handler_map.go @@ -220,23 +220,6 @@ func (h *packetHandlerMap) GetByResetToken(token protocol.StatelessResetToken) ( return handler, ok } -func (h *packetHandlerMap) CloseServer() { - h.mutex.Lock() - var wg sync.WaitGroup - for _, handler := range h.handlers { - if handler.getPerspective() == protocol.PerspectiveServer { - wg.Add(1) - go func(handler packetHandler) { - // blocks until the CONNECTION_CLOSE has been sent and the run-loop has stopped - handler.shutdown() - wg.Done() - }(handler) - } - } - h.mutex.Unlock() - wg.Wait() -} - func (h *packetHandlerMap) Close(e error) { h.mutex.Lock() diff --git a/packet_handler_map_test.go b/packet_handler_map_test.go index 24cef871e44..d40c395fff8 100644 --- a/packet_handler_map_test.go +++ b/packet_handler_map_test.go @@ -159,23 +159,6 @@ var _ = Describe("Packet Handler Map", func() { Eventually(func() bool { _, ok := m.Get(connID); return ok }).Should(BeFalse()) }) - It("closes the server", func() { - m := newPacketHandlerMap(nil, nil, utils.DefaultLogger) - for i := 0; i < 10; i++ { - conn := NewMockPacketHandler(mockCtrl) - if i%2 == 0 { - conn.EXPECT().getPerspective().Return(protocol.PerspectiveClient) - } else { - conn.EXPECT().getPerspective().Return(protocol.PerspectiveServer) - conn.EXPECT().shutdown() - } - b := make([]byte, 12) - rand.Read(b) - m.Add(protocol.ParseConnectionID(b), conn) - } - m.CloseServer() - }) - It("closes", func() { m := newPacketHandlerMap(nil, nil, utils.DefaultLogger) testErr := errors.New("shutdown") diff --git a/server.go b/server.go index 8353cdeba59..f7c638b9350 100644 --- a/server.go +++ b/server.go @@ -34,7 +34,6 @@ type packetHandlerManager interface { GetByResetToken(protocol.StatelessResetToken) (packetHandler, bool) AddWithConnID(protocol.ConnectionID, protocol.ConnectionID, func() (packetHandler, bool)) bool Close(error) - CloseServer() connRunner } @@ -61,8 +60,6 @@ type rejectedPacket struct { // A Listener of QUIC type baseServer struct { - mutex sync.Mutex - disableVersionNegotiation bool acceptEarlyConns bool @@ -104,10 +101,11 @@ type baseServer struct { protocol.VersionNumber, ) quicConn - serverError error - errorChan chan struct{} - closed bool - running chan struct{} // closed as soon as run() returns + closeOnce sync.Once + errorChan chan struct{} // is closed when the server is closed + closeErr error + running chan struct{} // closed as soon as run() returns + versionNegotiationQueue chan receivedPacket invalidTokenQueue chan rejectedPacket connectionRefusedQueue chan rejectedPacket @@ -132,7 +130,10 @@ func (l *Listener) Accept(ctx context.Context) (Connection, error) { return l.baseServer.Accept(ctx) } -// Close the server. All active connections will be closed. +// Close closes the listener. +// Accept will return ErrServerClosed as soon as all connections in the accept queue have been accepted. +// QUIC handshakes that are still in flight will be rejected with a CONNECTION_REFUSED error. +// Closing the listener doesn't have any effect on already established connections. func (l *Listener) Close() error { return l.baseServer.Close() } @@ -321,38 +322,25 @@ func (s *baseServer) accept(ctx context.Context) (quicConn, error) { atomic.AddInt32(&s.connQueueLen, -1) return conn, nil case <-s.errorChan: - return nil, s.serverError + return nil, s.closeErr } } -// Close the server func (s *baseServer) Close() error { - s.mutex.Lock() - if s.closed { - s.mutex.Unlock() - return nil - } - if s.serverError == nil { - s.serverError = ErrServerClosed - } - s.closed = true - close(s.errorChan) - s.mutex.Unlock() - - <-s.running - s.onClose() + s.close(ErrServerClosed, true) return nil } -func (s *baseServer) setCloseError(e error) { - s.mutex.Lock() - defer s.mutex.Unlock() - if s.closed { - return - } - s.closed = true - s.serverError = e - close(s.errorChan) +func (s *baseServer) close(e error, notifyOnClose bool) { + s.closeOnce.Do(func() { + s.closeErr = e + close(s.errorChan) + + <-s.running + if notifyOnClose { + s.onClose() + } + }) } // Addr returns the server's network address @@ -701,8 +689,11 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error func (s *baseServer) handleNewConn(conn quicConn) { connCtx := conn.Context() if s.acceptEarlyConns { - // wait until the early connection is ready (or the handshake fails) + // wait until the early connection is ready, the handshake fails, or the server is closed select { + case <-s.errorChan: + conn.destroy(&qerr.TransportError{ErrorCode: ConnectionRefused}) + return case <-conn.earlyConnReady(): case <-connCtx.Done(): return @@ -710,6 +701,9 @@ func (s *baseServer) handleNewConn(conn quicConn) { } else { // wait until the handshake is complete (or fails) select { + case <-s.errorChan: + conn.destroy(&qerr.TransportError{ErrorCode: ConnectionRefused}) + return case <-conn.HandshakeComplete(): case <-connCtx.Done(): return diff --git a/server_test.go b/server_test.go index 6b250c33227..eeea3b8c996 100644 --- a/server_test.go +++ b/server_test.go @@ -326,6 +326,8 @@ var _ = Describe("Server", func() { // make sure we're using a server-generated connection ID Eventually(run).Should(BeClosed()) Eventually(done).Should(BeClosed()) + // shutdown + conn.EXPECT().destroy(gomock.Any()) }) It("sends a Version Negotiation Packet for unsupported versions", func() { @@ -527,6 +529,8 @@ var _ = Describe("Server", func() { // make sure we're using a server-generated connection ID Eventually(run).Should(BeClosed()) Eventually(done).Should(BeClosed()) + // shutdown + conn.EXPECT().destroy(gomock.Any()) }) It("drops packets if the receive queue is full", func() { @@ -565,6 +569,8 @@ var _ = Describe("Server", func() { conn.EXPECT().run().MaxTimes(1) conn.EXPECT().Context().Return(context.Background()).MaxTimes(1) conn.EXPECT().HandshakeComplete().Return(make(chan struct{})).MaxTimes(1) + // shutdown + conn.EXPECT().destroy(gomock.Any()).MaxTimes(1) return conn } @@ -956,30 +962,69 @@ var _ = Describe("Server", func() { }) Context("accepting connections", func() { - It("returns Accept when an error occurs", func() { - testErr := errors.New("test err") - + It("returns Accept when closed", func() { done := make(chan struct{}) go func() { defer GinkgoRecover() _, err := serv.Accept(context.Background()) - Expect(err).To(MatchError(testErr)) + Expect(err).To(MatchError(ErrServerClosed)) close(done) }() - serv.setCloseError(testErr) + serv.Close() Eventually(done).Should(BeClosed()) - serv.onClose() // shutdown }) It("returns immediately, if an error occurred before", func() { - testErr := errors.New("test err") - serv.setCloseError(testErr) + serv.Close() for i := 0; i < 3; i++ { _, err := serv.Accept(context.Background()) - Expect(err).To(MatchError(testErr)) + Expect(err).To(MatchError(ErrServerClosed)) } - serv.onClose() // shutdown + }) + + It("closes connection that are still handshaking after Close", func() { + serv.Close() + + destroyed := make(chan struct{}) + serv.newConn = func( + _ sendConn, + _ connRunner, + _ protocol.ConnectionID, + _ *protocol.ConnectionID, + _ protocol.ConnectionID, + _ protocol.ConnectionID, + _ protocol.ConnectionID, + _ ConnectionIDGenerator, + _ protocol.StatelessResetToken, + conf *Config, + _ *tls.Config, + _ *handshake.TokenGenerator, + _ bool, + _ *logging.ConnectionTracer, + _ uint64, + _ utils.Logger, + _ protocol.VersionNumber, + ) quicConn { + conn := NewMockQUICConn(mockCtrl) + conn.EXPECT().handlePacket(gomock.Any()) + conn.EXPECT().destroy(&qerr.TransportError{ErrorCode: ConnectionRefused}).Do(func(error) { close(destroyed) }) + conn.EXPECT().HandshakeComplete().Return(make(chan struct{})) + conn.EXPECT().run().MaxTimes(1) + conn.EXPECT().Context().Return(context.Background()) + return conn + } + phm.EXPECT().Get(gomock.Any()) + phm.EXPECT().AddWithConnID(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ protocol.ConnectionID, fn func() (packetHandler, bool)) bool { + phm.EXPECT().GetStatelessResetToken(gomock.Any()) + _, ok := fn() + return ok + }) + serv.handleInitialImpl( + receivedPacket{buffer: getPacketBuffer()}, + &wire.Header{DestConnectionID: protocol.ParseConnectionID([]byte{1, 2, 3, 4, 5, 6, 7, 8})}, + ) + Eventually(destroyed).Should(BeClosed()) }) It("returns when the context is canceled", func() { @@ -1343,10 +1388,7 @@ var _ = Describe("Server", func() { serv.connHandler = phm }) - AfterEach(func() { - phm.EXPECT().CloseServer().MaxTimes(1) - tr.Close() - }) + AfterEach(func() { tr.Close() }) It("passes packets to existing connections", func() { connID := protocol.ParseConnectionID([]byte{1, 2, 3, 4, 5, 6, 7, 8}) @@ -1425,6 +1467,8 @@ var _ = Describe("Server", func() { conn.EXPECT().earlyConnReady() conn.EXPECT().Context().Return(context.Background()) close(called) + // shutdown + conn.EXPECT().destroy(gomock.Any()) return conn } diff --git a/transport.go b/transport.go index 60d44a43e84..38d35238feb 100644 --- a/transport.go +++ b/transport.go @@ -275,7 +275,8 @@ func (t *Transport) runSendQueue() { } } -// Close closes the underlying connection and waits until listen has returned. +// Close closes the underlying connection. +// If any listener was started, it will be closed as well. // It is invalid to start new listeners or connections after that. func (t *Transport) Close() error { t.close(errors.New("closing")) @@ -294,7 +295,6 @@ func (t *Transport) Close() error { } func (t *Transport) closeServer() { - t.handlerMap.CloseServer() t.mutex.Lock() t.server = nil if t.isSingleUse { @@ -322,7 +322,7 @@ func (t *Transport) close(e error) { t.handlerMap.Close(e) } if t.server != nil { - t.server.setCloseError(e) + t.server.close(e, false) } t.closed = true } diff --git a/transport_test.go b/transport_test.go index 5fa6321361e..c93d1da9078 100644 --- a/transport_test.go +++ b/transport_test.go @@ -114,7 +114,6 @@ var _ = Describe("Transport", func() { phm := NewMockPacketHandlerManager(mockCtrl) tr.handlerMap = phm - phm.EXPECT().CloseServer() Expect(ln.Close()).To(Succeed()) // shutdown From 5311f8178c285a2e081319f4b6a892967dd090e6 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 27 Oct 2023 16:21:26 +0700 Subject: [PATCH 100/225] README: link to webtransport-go repo (#4117) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 30265c3ab3f..a899f7180e9 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ In addition to these base RFCs, it also implements the following RFCs: * QUIC Version 2 ([RFC 9369](https://datatracker.ietf.org/doc/html/rfc9369)) * QUIC Event Logging using qlog ([draft-ietf-quic-qlog-main-schema](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-main-schema/) and [draft-ietf-quic-qlog-quic-events](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-quic-events/)) +Support for WebTransport over HTTP/3 ([draft-ietf-webtrans-http3](https://datatracker.ietf.org/doc/draft-ietf-webtrans-http3/)) is implemented in [webtransport-go](https://github.com/quic-go/webtransport-go). + ## Using QUIC ### Running a Server From 6eb0caca1a433ed236386eca6b33f473b8ecc2ff Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 28 Oct 2023 12:08:49 +0700 Subject: [PATCH 101/225] fix race condition in multiplex integration test (#4136) --- integrationtests/self/multiplex_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/integrationtests/self/multiplex_test.go b/integrationtests/self/multiplex_test.go index 72c858a10cf..dace9a8c117 100644 --- a/integrationtests/self/multiplex_test.go +++ b/integrationtests/self/multiplex_test.go @@ -251,6 +251,9 @@ var _ = Describe("Multiplexing", func() { b := make([]byte, packetLen) rand.Read(b[1:]) // keep the first byte set to 0, so it's not classified as a QUIC packet _, err := tr1.WriteTo(b, tr2.Conn.LocalAddr()) + if ctx.Err() != nil { // ctx canceled while Read was executing + return + } Expect(err).ToNot(HaveOccurred()) sentPackets.Add(1) } From a3603549eebd4e22fd8ea4d4fe0c9011bc08daa4 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 28 Oct 2023 13:40:50 +0700 Subject: [PATCH 102/225] document what happens to established connections on Listener.Close (#4138) --- server.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server.go b/server.go index f7c638b9350..124e30be6f6 100644 --- a/server.go +++ b/server.go @@ -133,7 +133,9 @@ func (l *Listener) Accept(ctx context.Context) (Connection, error) { // Close closes the listener. // Accept will return ErrServerClosed as soon as all connections in the accept queue have been accepted. // QUIC handshakes that are still in flight will be rejected with a CONNECTION_REFUSED error. -// Closing the listener doesn't have any effect on already established connections. +// The effect of closing the listener depends on how it was created: +// * if it was created using Transport.Listen, already established connections will be unaffected +// * if it was created using the Listen convenience method, all established connection will be closed immediately func (l *Listener) Close() error { return l.baseServer.Close() } @@ -216,6 +218,7 @@ func listenUDP(addr string) (*net.UDPConn, error) { // This is a convenience function. More advanced use cases should instantiate a Transport, // which offers configuration options for a more fine-grained control of the connection establishment, // including reusing the underlying UDP socket for outgoing QUIC connections. +// When closing a listener created with Listen, all established QUIC connections will be closed immediately. func Listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (*Listener, error) { tr := &Transport{Conn: conn, isSingleUse: true} return tr.Listen(tlsConf, config) From f23da7da4767d3a27fbed72d6257dddfb7e58405 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 31 Oct 2023 16:21:42 +0700 Subject: [PATCH 103/225] congestion: don't use floating point math when calculating pacing times (#4148) --- internal/congestion/pacer.go | 19 ++++++++++++------- internal/congestion/pacer_test.go | 11 +++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/internal/congestion/pacer.go b/internal/congestion/pacer.go index 09ea268066d..94eae8f8ddc 100644 --- a/internal/congestion/pacer.go +++ b/internal/congestion/pacer.go @@ -1,7 +1,6 @@ package congestion import ( - "math" "time" "github.com/quic-go/quic-go/internal/protocol" @@ -26,7 +25,7 @@ func newPacer(getBandwidth func() Bandwidth) *pacer { bw := uint64(getBandwidth() / BytesPerSecond) // Use a slightly higher value than the actual measured bandwidth. // RTT variations then won't result in under-utilization of the congestion window. - // Ultimately, this will result in sending packets as acknowledgments are received rather than when timers fire, + // Ultimately, this will result in sending packets as acknowledgments are received rather than when timers fire, // provided the congestion window is fully utilized and acknowledgments arrive at regular intervals. return bw * 5 / 4 }, @@ -37,7 +36,7 @@ func newPacer(getBandwidth func() Bandwidth) *pacer { func (p *pacer) SentPacket(sendTime time.Time, size protocol.ByteCount) { budget := p.Budget(sendTime) - if size > budget { + if size >= budget { p.budgetAtLastSent = 0 } else { p.budgetAtLastSent = budget - size @@ -69,10 +68,16 @@ func (p *pacer) TimeUntilSend() time.Time { if p.budgetAtLastSent >= p.maxDatagramSize { return time.Time{} } - return p.lastSentTime.Add(utils.Max( - protocol.MinPacingDelay, - time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/float64(p.adjustedBandwidth())))*time.Nanosecond, - )) + diff := 1e9 * uint64(p.maxDatagramSize-p.budgetAtLastSent) + bw := p.adjustedBandwidth() + // We might need to round up this value. + // Otherwise, we might have a budget (slightly) smaller than the datagram size when the timer expires. + d := diff / bw + // this is effectively a math.Ceil, but using only integer math + if diff%bw > 0 { + d++ + } + return p.lastSentTime.Add(utils.Max(protocol.MinPacingDelay, time.Duration(d)*time.Nanosecond)) } func (p *pacer) SetMaxDatagramSize(s protocol.ByteCount) { diff --git a/internal/congestion/pacer_test.go b/internal/congestion/pacer_test.go index 69f58fcc251..04ece345927 100644 --- a/internal/congestion/pacer_test.go +++ b/internal/congestion/pacer_test.go @@ -101,6 +101,17 @@ var _ = Describe("Pacer", func() { Expect(p.Budget(t.Add(5 * t2.Sub(t)))).To(BeEquivalentTo(5 * packetSize)) }) + It("has enough budget for at least one packet when the timer expires", func() { + t := time.Now() + sendBurst(t) + for bw := uint64(100); bw < uint64(5*initialMaxDatagramSize); bw++ { + bandwidth = bw // reduce the bandwidth to 5 packet per second + t2 := p.TimeUntilSend() + Expect(t2).To(BeTemporally(">", t)) + Expect(p.Budget(t2)).To(BeNumerically(">=", initialMaxDatagramSize)) + } + }) + It("never allows bursts larger than the maximum burst size", func() { t := time.Now() sendBurst(t) From d4ab27de1f86ec60f067665510d06ce148beee0e Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 1 Nov 2023 12:27:13 +0700 Subject: [PATCH 104/225] don't set the TLS version in the transport (#4135) This is already done in the crypto setup. --- transport.go | 1 - 1 file changed, 1 deletion(-) diff --git a/transport.go b/transport.go index 38d35238feb..6dee5184aef 100644 --- a/transport.go +++ b/transport.go @@ -191,7 +191,6 @@ func (t *Transport) dial(ctx context.Context, addr net.Addr, host string, tlsCon onClose = func() { t.Close() } } tlsConf = tlsConf.Clone() - tlsConf.MinVersion = tls.VersionTLS13 setTLSConfigServerName(tlsConf, addr, host) return dial(ctx, newSendConn(t.conn, addr, packetInfo{}, utils.DefaultLogger), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, use0RTT) } From 9414ea49100d5cf75a2044d85a6becf3985171db Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 3 Nov 2023 22:28:16 +0700 Subject: [PATCH 105/225] ackhandler: immediately acknowledge ECN-CE marked packets (#4147) * ackhandler: immediately acknowledge ECN-CE marked packets * shorter debug statements --- internal/ackhandler/received_packet_tracker.go | 16 ++++++++++------ .../ackhandler/received_packet_tracker_test.go | 11 +++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/internal/ackhandler/received_packet_tracker.go b/internal/ackhandler/received_packet_tracker.go index 7fd071e6833..8d15d7c18d9 100644 --- a/internal/ackhandler/received_packet_tracker.go +++ b/internal/ackhandler/received_packet_tracker.go @@ -58,11 +58,9 @@ func (h *receivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn pro if ackEliciting { h.hasNewAck = true + h.maybeQueueACK(pn, rcvTime, ecn, isMissing) } - if ackEliciting { - h.maybeQueueACK(pn, rcvTime, isMissing) - } - //nolint:exhaustive // Only need to count ECT(0), ECT(1) and ECNCE. + //nolint:exhaustive // Only need to count ECT(0), ECT(1) and ECN-CE. switch ecn { case protocol.ECT0: h.ect0++ @@ -104,7 +102,7 @@ func (h *receivedPacketTracker) hasNewMissingPackets() bool { } // maybeQueueACK queues an ACK, if necessary. -func (h *receivedPacketTracker) maybeQueueACK(pn protocol.PacketNumber, rcvTime time.Time, wasMissing bool) { +func (h *receivedPacketTracker) maybeQueueACK(pn protocol.PacketNumber, rcvTime time.Time, ecn protocol.ECN, wasMissing bool) { // always acknowledge the first packet if h.lastAck == nil { if !h.ackQueued { @@ -143,12 +141,18 @@ func (h *receivedPacketTracker) maybeQueueACK(pn protocol.PacketNumber, rcvTime h.ackAlarm = rcvTime.Add(h.maxAckDelay) } - // Queue an ACK if there are new missing packets to report. + // queue an ACK if there are new missing packets to report if h.hasNewMissingPackets() { h.logger.Debugf("\tQueuing ACK because there's a new missing packet to report.") h.ackQueued = true } + // queue an ACK if the packet was ECN-CE marked + if ecn == protocol.ECNCE { + h.logger.Debugf("\tQueuing ACK because the packet was ECN-CE marked.") + h.ackQueued = true + } + if h.ackQueued { // cancel the ack alarm h.ackAlarm = time.Time{} diff --git a/internal/ackhandler/received_packet_tracker_test.go b/internal/ackhandler/received_packet_tracker_test.go index 8c76f207b14..b0d7db3c38a 100644 --- a/internal/ackhandler/received_packet_tracker_test.go +++ b/internal/ackhandler/received_packet_tracker_test.go @@ -50,6 +50,7 @@ var _ = Describe("Received Packet Tracker", func() { Context("ACKs", func() { Context("queueing ACKs", func() { + // receives and gets ACKs for packet numbers 1 to 10 (including) receiveAndAck10Packets := func() { for i := 1; i <= 10; i++ { Expect(tracker.ReceivedPacket(protocol.PacketNumber(i), protocol.ECNNon, time.Time{}, true)).To(Succeed()) @@ -126,6 +127,16 @@ var _ = Describe("Received Packet Tracker", func() { Expect(tracker.GetAlarmTimeout()).To(Equal(rcvTime.Add(protocol.MaxAckDelay))) }) + It("queues an ACK if the packet was ECN-CE marked", func() { + receiveAndAck10Packets() + Expect(tracker.ReceivedPacket(11, protocol.ECNCE, time.Now(), true)).To(Succeed()) + ack := tracker.GetAckFrame(true) + Expect(ack).ToNot(BeNil()) + Expect(ack.AckRanges).To(HaveLen(1)) + Expect(ack.AckRanges[0].Largest).To(Equal(protocol.PacketNumber(11))) + Expect(ack.ECNCE).To(BeEquivalentTo(1)) + }) + It("queues an ACK if it was reported missing before", func() { receiveAndAck10Packets() Expect(tracker.ReceivedPacket(11, protocol.ECNNon, time.Now(), true)).To(Succeed()) From 740119b1449fa7b65563b4e7c3dedbc51e65e8d8 Mon Sep 17 00:00:00 2001 From: Anders Pitman Date: Tue, 14 Nov 2023 02:09:47 -0700 Subject: [PATCH 106/225] README: fix typo (#4166) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a899f7180e9..71f857ac20b 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ In case the application wishes to abort sending on a `quic.SendStream` or a `qui Conversely, in case the application wishes to abort receiving from a `quic.ReceiveStream` or a `quic.Stream`, it can ask the sender to abort data transmission by calling `CancelRead` with an application-defined error code (an unsigned 62-bit number). On the receiver side, this surfaced as a `quic.StreamError` containing that error code on the `io.Writer`. Note that for bidirectional streams, `CancelWrite` _only_ resets the receive side of the stream. It is still possible to write to the stream. -A bidirectional stream is only closed once both the read and the write side of the stream have been either closed and reset. Only then the peer is granted a new stream according to the maximum number of concurrent streams configured via `quic.Config.MaxIncomingStreams`. +A bidirectional stream is only closed once both the read and the write side of the stream have been either closed or reset. Only then the peer is granted a new stream according to the maximum number of concurrent streams configured via `quic.Config.MaxIncomingStreams`. ### Configuring QUIC From 427f53328bb18ed1f84f352914cec805d0051494 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 14 Nov 2023 11:00:42 +0100 Subject: [PATCH 107/225] fix flaky server test (#4167) --- server_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_test.go b/server_test.go index eeea3b8c996..2e6ee0180d7 100644 --- a/server_test.go +++ b/server_test.go @@ -530,7 +530,7 @@ var _ = Describe("Server", func() { Eventually(run).Should(BeClosed()) Eventually(done).Should(BeClosed()) // shutdown - conn.EXPECT().destroy(gomock.Any()) + conn.EXPECT().destroy(gomock.Any()).MaxTimes(1) }) It("drops packets if the receive queue is full", func() { From 96ab48eb7d8ac3cd1337a5f66565ea8019c72e48 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 17 Nov 2023 07:06:42 +0100 Subject: [PATCH 108/225] fix serialization of connection ID in filenames of qlog files (#4170) --- README.md | 2 +- example/client/main.go | 2 +- example/main.go | 2 +- integrationtests/tools/qlog.go | 2 +- interop/utils/logging.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 71f857ac20b..cfb4e612372 100644 --- a/README.md +++ b/README.md @@ -192,7 +192,7 @@ quic.Config{ if p == logging.PerspectiveClient { role = "client" } - filename := fmt.Sprintf("./log_%x_%s.qlog", connID, role) + filename := fmt.Sprintf("./log_%s_%s.qlog", connID, role) f, err := os.Create(filename) // handle the error return qlog.NewConnectionTracer(f, p, connID) diff --git a/example/client/main.go b/example/client/main.go index 5b86faa37c8..847acb72485 100644 --- a/example/client/main.go +++ b/example/client/main.go @@ -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 { - filename := fmt.Sprintf("client_%x.qlog", connID) + filename := fmt.Sprintf("client_%s.qlog", connID) f, err := os.Create(filename) if err != nil { log.Fatal(err) diff --git a/example/main.go b/example/main.go index c2fb574d49d..cd476e44ecf 100644 --- a/example/main.go +++ b/example/main.go @@ -164,7 +164,7 @@ func main() { quicConf := &quic.Config{} if *enableQlog { quicConf.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer { - filename := fmt.Sprintf("server_%x.qlog", connID) + filename := fmt.Sprintf("server_%s.qlog", connID) f, err := os.Create(filename) if err != nil { log.Fatal(err) diff --git a/integrationtests/tools/qlog.go b/integrationtests/tools/qlog.go index ea37456e8b1..049432cc694 100644 --- a/integrationtests/tools/qlog.go +++ b/integrationtests/tools/qlog.go @@ -20,7 +20,7 @@ func NewQlogger(logger io.Writer) func(context.Context, logging.Perspective, qui if p == logging.PerspectiveClient { role = "client" } - filename := fmt.Sprintf("log_%x_%s.qlog", connID.Bytes(), role) + filename := fmt.Sprintf("log_%s_%s.qlog", connID, role) fmt.Fprintf(logger, "Creating %s.\n", filename) f, err := os.Create(filename) if err != nil { diff --git a/interop/utils/logging.go b/interop/utils/logging.go index 3cb42244b0f..fa076ef47fe 100644 --- a/interop/utils/logging.go +++ b/interop/utils/logging.go @@ -39,7 +39,7 @@ func NewQLOGConnectionTracer(_ context.Context, p logging.Perspective, connID qu log.Fatalf("failed to create qlog dir %s: %v", qlogDir, err) } } - path := fmt.Sprintf("%s/%x.qlog", strings.TrimRight(qlogDir, "/"), connID) + path := fmt.Sprintf("%s/%s.qlog", strings.TrimRight(qlogDir, "/"), connID) f, err := os.Create(path) if err != nil { log.Printf("Failed to create qlog file %s: %s", path, err.Error()) From 3bf2e19d0dc617135ec9d6f3c5191740a27097c7 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 17 Nov 2023 13:11:16 +0100 Subject: [PATCH 109/225] logging: pass the packet number to ConnectionTracer.DroppedPacket (#4171) In most cases the packet number is not known when a packet is dropped, but it's useful to log the packet number when dropping a duplicate packet. --- connection.go | 42 +++++++++---------- connection_test.go | 38 ++++++++--------- internal/mocks/logging/connection_tracer.go | 4 +- .../logging/internal/connection_tracer.go | 12 +++--- internal/mocks/logging/mockgen.go | 2 +- logging/connection_tracer.go | 6 +-- logging/multiplex_test.go | 6 +-- qlog/event.go | 14 ++++--- qlog/packet_header.go | 8 +++- qlog/qlog.go | 13 +++--- qlog/qlog_test.go | 20 ++++++++- 11 files changed, 95 insertions(+), 70 deletions(-) diff --git a/connection.go b/connection.go index 93c159137bf..7f26ef5e565 100644 --- a/connection.go +++ b/connection.go @@ -804,14 +804,14 @@ func (s *connection) handlePacketImpl(rp receivedPacket) bool { destConnID, err = wire.ParseConnectionID(p.data, s.srcConnIDLen) if err != nil { if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(data)), logging.PacketDropHeaderParseError) + s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, 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 && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(data)), logging.PacketDropUnknownConnectionID) + s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnknownConnectionID) } s.logger.Debugf("coalesced packet has different destination connection ID: %s, expected %s", destConnID, lastConnID) break @@ -826,7 +826,7 @@ func (s *connection) handlePacketImpl(rp receivedPacket) bool { if err == wire.ErrUnsupportedVersion { dropReason = logging.PacketDropUnsupportedVersion } - s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(data)), dropReason) + s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), dropReason) } s.logger.Debugf("error parsing packet: %s", err) break @@ -835,7 +835,7 @@ func (s *connection) handlePacketImpl(rp receivedPacket) bool { if hdr.Version != s.version { if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(data)), logging.PacketDropUnexpectedVersion) + s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedVersion) } s.logger.Debugf("Dropping packet with version %x. Expected %x.", hdr.Version, s.version) break @@ -894,7 +894,7 @@ 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 && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketType1RTT, p.Size(), logging.PacketDropDuplicate) + s.tracer.DroppedPacket(logging.PacketType1RTT, pn, p.Size(), logging.PacketDropDuplicate) } return false } @@ -940,7 +940,7 @@ func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header) // 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 && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeInitial, p.Size(), logging.PacketDropUnknownConnectionID) + s.tracer.DroppedPacket(logging.PacketTypeInitial, protocol.InvalidPacketNumber, 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) return false @@ -948,7 +948,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 && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketType0RTT, p.Size(), logging.PacketDropKeyUnavailable) + s.tracer.DroppedPacket(logging.PacketType0RTT, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropKeyUnavailable) } return false } @@ -964,10 +964,10 @@ func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header) packet.hdr.Log(s.logger) } - if s.receivedPacketHandler.IsPotentiallyDuplicate(packet.hdr.PacketNumber, packet.encryptionLevel) { + if pn := packet.hdr.PacketNumber; s.receivedPacketHandler.IsPotentiallyDuplicate(pn, packet.encryptionLevel) { s.logger.Debugf("Dropping (potentially) duplicate packet.") if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropDuplicate) + s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), pn, p.Size(), logging.PacketDropDuplicate) } return false } @@ -983,7 +983,7 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P switch err { case handshake.ErrKeysDropped: if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropKeyUnavailable) + s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropKeyUnavailable) } s.logger.Debugf("Dropping %s packet (%d bytes) because we already dropped the keys.", pt, p.Size()) case handshake.ErrKeysNotYetAvailable: @@ -999,7 +999,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 && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropPayloadDecryptError) + s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropPayloadDecryptError) } s.logger.Debugf("Dropping %s packet (%d bytes) that could not be unpacked. Error: %s", pt, p.Size(), err) default: @@ -1007,7 +1007,7 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P if errors.As(err, &headerErr) { // This might be a packet injected by an attacker. Drop it. if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropHeaderParseError) + s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, 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) } else { @@ -1022,14 +1022,14 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P 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 && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) + s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) } s.logger.Debugf("Ignoring Retry.") return false } if s.receivedFirstPacket { if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) + s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) } s.logger.Debugf("Ignoring Retry, since we already received a packet.") return false @@ -1037,7 +1037,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime ti destConnID := s.connIDManager.Get() if hdr.SrcConnectionID == destConnID { if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) + s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) } s.logger.Debugf("Ignoring Retry, since the server didn't change the Source Connection ID.") return false @@ -1052,7 +1052,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime ti tag := handshake.GetRetryIntegrityTag(data[:len(data)-16], destConnID, hdr.Version) if !bytes.Equal(data[len(data)-16:], tag[:]) { if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropPayloadDecryptError) + s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropPayloadDecryptError) } s.logger.Debugf("Ignoring spoofed Retry. Integrity Tag doesn't match.") return false @@ -1085,7 +1085,7 @@ 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 && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedPacket) + s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket) } return } @@ -1093,7 +1093,7 @@ func (s *connection) handleVersionNegotiationPacket(p receivedPacket) { src, dest, supportedVersions, err := wire.ParseVersionNegotiationPacket(p.data) if err != nil { if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropHeaderParseError) + s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError) } s.logger.Debugf("Error parsing Version Negotiation packet: %s", err) return @@ -1102,7 +1102,7 @@ func (s *connection) handleVersionNegotiationPacket(p receivedPacket) { for _, v := range supportedVersions { if v == s.version { if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedVersion) + s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedVersion) } // The Version Negotiation packet contains the version that we offered. // This might be a packet sent by an attacker, or it was corrupted. @@ -1343,7 +1343,7 @@ func (s *connection) handlePacket(p receivedPacket) { case s.receivedPackets <- p: default: if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention) + s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropDOSPrevention) } } } @@ -2305,7 +2305,7 @@ func (s *connection) tryQueueingUndecryptablePacket(p receivedPacket, pt logging } if len(s.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets { if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropDOSPrevention) + s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropDOSPrevention) } s.logger.Infof("Dropping undecryptable packet (%d bytes). Undecryptable packet queue full.", p.Size()) return diff --git a/connection_test.go b/connection_test.go index 7bc5b96d66f..b5f786569ba 100644 --- a/connection_test.go +++ b/connection_test.go @@ -686,7 +686,7 @@ var _ = Describe("Connection", func() { Version: conn.version, Token: []byte("foobar"), }}, make([]byte, 16) /* Retry integrity tag */) - tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, p.Size(), logging.PacketDropUnexpectedPacket) + tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket) Expect(conn.handlePacketImpl(p)).To(BeFalse()) }) @@ -696,7 +696,7 @@ var _ = Describe("Connection", func() { protocol.ArbitraryLenConnectionID(destConnID.Bytes()), conn.config.Versions, ) - tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.ByteCount(len(b)), logging.PacketDropUnexpectedPacket) + tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, protocol.ByteCount(len(b)), logging.PacketDropUnexpectedPacket) Expect(conn.handlePacketImpl(receivedPacket{ data: b, buffer: getPacketBuffer(), @@ -712,7 +712,7 @@ var _ = Describe("Connection", func() { PacketNumberLen: protocol.PacketNumberLen2, }, nil) p.data[0] ^= 0x40 // unset the QUIC bit - tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError) + tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError) Expect(conn.handlePacketImpl(p)).To(BeFalse()) }) @@ -724,7 +724,7 @@ var _ = Describe("Connection", func() { }, PacketNumberLen: protocol.PacketNumberLen2, }, nil) - tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnsupportedVersion) + tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnsupportedVersion) Expect(conn.handlePacketImpl(p)).To(BeFalse()) }) @@ -745,7 +745,7 @@ var _ = Describe("Connection", func() { }, PacketNumberLen: protocol.PacketNumberLen2, }, nil) - tracer.EXPECT().DroppedPacket(logging.PacketTypeHandshake, p.Size(), logging.PacketDropUnexpectedVersion) + tracer.EXPECT().DroppedPacket(logging.PacketTypeHandshake, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedVersion) Expect(conn.handlePacketImpl(p)).To(BeFalse()) }) @@ -811,7 +811,7 @@ var _ = Describe("Connection", func() { rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl) rph.EXPECT().IsPotentiallyDuplicate(protocol.PacketNumber(0x1337), protocol.Encryption1RTT).Return(true) conn.receivedPacketHandler = rph - tracer.EXPECT().DroppedPacket(logging.PacketType1RTT, protocol.ByteCount(len(packet.data)), logging.PacketDropDuplicate) + tracer.EXPECT().DroppedPacket(logging.PacketType1RTT, protocol.PacketNumber(0x1337), protocol.ByteCount(len(packet.data)), logging.PacketDropDuplicate) Expect(conn.handlePacketImpl(packet)).To(BeFalse()) }) @@ -837,7 +837,7 @@ var _ = Describe("Connection", func() { PacketNumber: 0x1337, PacketNumberLen: protocol.PacketNumberLen2, }, []byte("foobar")) - tracer.EXPECT().DroppedPacket(logging.PacketTypeHandshake, p.Size(), logging.PacketDropPayloadDecryptError) + tracer.EXPECT().DroppedPacket(logging.PacketTypeHandshake, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropPayloadDecryptError) conn.handlePacket(p) Consistently(conn.Context().Done()).ShouldNot(BeClosed()) // make the go routine return @@ -955,7 +955,7 @@ var _ = Describe("Connection", func() { runErr <- conn.run() }() expectReplaceWithClosed() - tracer.EXPECT().DroppedPacket(logging.PacketType1RTT, gomock.Any(), logging.PacketDropHeaderParseError) + tracer.EXPECT().DroppedPacket(logging.PacketType1RTT, protocol.InvalidPacketNumber, gomock.Any(), logging.PacketDropHeaderParseError) conn.handlePacket(getShortHeaderPacket(srcConnID, 0x42, nil)) Consistently(runErr).ShouldNot(Receive()) // make the go routine return @@ -1028,7 +1028,7 @@ var _ = Describe("Connection", func() { 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) - tracer.EXPECT().DroppedPacket(logging.PacketTypeInitial, protocol.ByteCount(len(p2.data)), logging.PacketDropUnknownConnectionID) + tracer.EXPECT().DroppedPacket(logging.PacketTypeInitial, protocol.InvalidPacketNumber, protocol.ByteCount(len(p2.data)), logging.PacketDropUnknownConnectionID) Expect(conn.handlePacketImpl(p2)).To(BeFalse()) }) @@ -1183,7 +1183,7 @@ var _ = Describe("Connection", func() { // don't EXPECT any more calls to unpacker.UnpackLongHeader() gomock.InOrder( 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), + tracer.EXPECT().DroppedPacket(gomock.Any(), protocol.InvalidPacketNumber, protocol.ByteCount(len(packet2.data)), logging.PacketDropUnknownConnectionID), ) packet1.data = append(packet1.data, packet2.data...) Expect(conn.handlePacketImpl(packet1)).To(BeTrue()) @@ -2430,7 +2430,7 @@ var _ = Describe("Connection", func() { It("stores up to MaxConnUnprocessedPackets packets", func() { done := make(chan struct{}) - tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, logging.ByteCount(6), logging.PacketDropDOSPrevention).Do(func(logging.PacketType, logging.ByteCount, logging.PacketDropReason) { + tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, logging.ByteCount(6), logging.PacketDropDOSPrevention).Do(func(logging.PacketType, logging.PacketNumber, logging.ByteCount, logging.PacketDropReason) { close(done) }) // Nothing here should block @@ -2790,14 +2790,14 @@ var _ = Describe("Client Connection", func() { It("ignores Version Negotiation packets that offer the current version", func() { p := getVNP(conn.version) - tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedVersion) + tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedVersion) Expect(conn.handlePacketImpl(p)).To(BeFalse()) }) It("ignores unparseable Version Negotiation packets", func() { p := getVNP(conn.version) p.data = p.data[:len(p.data)-2] - tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropHeaderParseError) + tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError) Expect(conn.handlePacketImpl(p)).To(BeFalse()) }) }) @@ -2846,14 +2846,14 @@ var _ = Describe("Client Connection", func() { It("ignores Retry packets after receiving a regular packet", func() { conn.receivedFirstPacket = true p := getPacket(retryHdr, getRetryTag(retryHdr)) - tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, p.Size(), logging.PacketDropUnexpectedPacket) + tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket) Expect(conn.handlePacketImpl(p)).To(BeFalse()) }) It("ignores Retry packets if the server didn't change the connection ID", func() { retryHdr.SrcConnectionID = destConnID p := getPacket(retryHdr, getRetryTag(retryHdr)) - tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, p.Size(), logging.PacketDropUnexpectedPacket) + tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket) Expect(conn.handlePacketImpl(p)).To(BeFalse()) }) @@ -2861,7 +2861,7 @@ var _ = Describe("Client Connection", func() { tag := getRetryTag(retryHdr) tag[0]++ p := getPacket(retryHdr, tag) - tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, p.Size(), logging.PacketDropPayloadDecryptError) + tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropPayloadDecryptError) Expect(conn.handlePacketImpl(p)).To(BeFalse()) }) }) @@ -3159,7 +3159,7 @@ var _ = Describe("Client Connection", func() { 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()) + tracer.EXPECT().DroppedPacket(gomock.Any(), protocol.InvalidPacketNumber, gomock.Any(), gomock.Any()) Expect(conn.handlePacketImpl(getPacket(hdr2, nil))).To(BeFalse()) }) @@ -3174,7 +3174,7 @@ var _ = Describe("Client Connection", func() { PacketNumber: 0x42, PacketNumberLen: protocol.PacketNumberLen2, }, []byte("foobar")) - tracer.EXPECT().DroppedPacket(logging.PacketType0RTT, p.Size(), gomock.Any()) + tracer.EXPECT().DroppedPacket(logging.PacketType0RTT, protocol.InvalidPacketNumber, p.Size(), gomock.Any()) Expect(conn.handlePacketImpl(p)).To(BeFalse()) }) @@ -3213,7 +3213,7 @@ var _ = Describe("Client Connection", func() { tracer.EXPECT().ReceivedRetry(gomock.Any()) conn.handlePacketImpl(wrapPacket(testutils.ComposeRetryPacket(newSrcConnID, destConnID, destConnID, []byte("foobar"), conn.version))) initialPacket := testutils.ComposeInitialPacket(conn.connIDManager.Get(), srcConnID, conn.version, conn.connIDManager.Get(), nil) - tracer.EXPECT().DroppedPacket(gomock.Any(), gomock.Any(), gomock.Any()) + tracer.EXPECT().DroppedPacket(gomock.Any(), protocol.InvalidPacketNumber, gomock.Any(), gomock.Any()) Expect(conn.handlePacketImpl(wrapPacket(initialPacket))).To(BeFalse()) }) }) diff --git a/internal/mocks/logging/connection_tracer.go b/internal/mocks/logging/connection_tracer.go index a2c74b1eb39..4c15dcd0870 100644 --- a/internal/mocks/logging/connection_tracer.go +++ b/internal/mocks/logging/connection_tracer.go @@ -56,8 +56,8 @@ func NewMockConnectionTracer(ctrl *gomock.Controller) (*logging.ConnectionTracer 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) + DroppedPacket: func(typ logging.PacketType, pn logging.PacketNumber, size logging.ByteCount, reason logging.PacketDropReason) { + t.DroppedPacket(typ, pn, size, reason) }, UpdatedMetrics: func(rttStats *logging.RTTStats, cwnd, bytesInFlight logging.ByteCount, packetsInFlight int) { t.UpdatedMetrics(rttStats, cwnd, bytesInFlight, packetsInFlight) diff --git a/internal/mocks/logging/internal/connection_tracer.go b/internal/mocks/logging/internal/connection_tracer.go index b83831a20d7..ab2a21820a7 100644 --- a/internal/mocks/logging/internal/connection_tracer.go +++ b/internal/mocks/logging/internal/connection_tracer.go @@ -296,15 +296,15 @@ func (c *ConnectionTracerDroppedKeyCall) DoAndReturn(f func(protocol.KeyPhase)) } // DroppedPacket mocks base method. -func (m *MockConnectionTracer) DroppedPacket(arg0 logging.PacketType, arg1 protocol.ByteCount, arg2 logging.PacketDropReason) { +func (m *MockConnectionTracer) DroppedPacket(arg0 logging.PacketType, arg1 protocol.PacketNumber, arg2 protocol.ByteCount, arg3 logging.PacketDropReason) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DroppedPacket", arg0, arg1, arg2) + m.ctrl.Call(m, "DroppedPacket", arg0, arg1, arg2, arg3) } // DroppedPacket indicates an expected call of DroppedPacket. -func (mr *MockConnectionTracerMockRecorder) DroppedPacket(arg0, arg1, arg2 any) *ConnectionTracerDroppedPacketCall { +func (mr *MockConnectionTracerMockRecorder) DroppedPacket(arg0, arg1, arg2, arg3 any) *ConnectionTracerDroppedPacketCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedPacket), arg0, arg1, arg2) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedPacket), arg0, arg1, arg2, arg3) return &ConnectionTracerDroppedPacketCall{Call: call} } @@ -320,13 +320,13 @@ func (c *ConnectionTracerDroppedPacketCall) Return() *ConnectionTracerDroppedPac } // Do rewrite *gomock.Call.Do -func (c *ConnectionTracerDroppedPacketCall) Do(f func(logging.PacketType, protocol.ByteCount, logging.PacketDropReason)) *ConnectionTracerDroppedPacketCall { +func (c *ConnectionTracerDroppedPacketCall) Do(f func(logging.PacketType, protocol.PacketNumber, protocol.ByteCount, logging.PacketDropReason)) *ConnectionTracerDroppedPacketCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ConnectionTracerDroppedPacketCall) DoAndReturn(f func(logging.PacketType, protocol.ByteCount, logging.PacketDropReason)) *ConnectionTracerDroppedPacketCall { +func (c *ConnectionTracerDroppedPacketCall) DoAndReturn(f func(logging.PacketType, protocol.PacketNumber, protocol.ByteCount, logging.PacketDropReason)) *ConnectionTracerDroppedPacketCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/mocks/logging/mockgen.go b/internal/mocks/logging/mockgen.go index b808ee6d1c0..65aa5f3d966 100644 --- a/internal/mocks/logging/mockgen.go +++ b/internal/mocks/logging/mockgen.go @@ -31,7 +31,7 @@ type ConnectionTracer interface { 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) + DroppedPacket(logging.PacketType, logging.PacketNumber, 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) diff --git a/logging/connection_tracer.go b/logging/connection_tracer.go index e3f322d91d1..218b0c6b826 100644 --- a/logging/connection_tracer.go +++ b/logging/connection_tracer.go @@ -20,7 +20,7 @@ type ConnectionTracer struct { ReceivedLongHeaderPacket func(*ExtendedHeader, ByteCount, ECN, []Frame) ReceivedShortHeaderPacket func(*ShortHeader, ByteCount, ECN, []Frame) BufferedPacket func(PacketType, ByteCount) - DroppedPacket func(PacketType, ByteCount, PacketDropReason) + DroppedPacket func(PacketType, PacketNumber, ByteCount, PacketDropReason) UpdatedMetrics func(rttStats *RTTStats, cwnd, bytesInFlight ByteCount, packetsInFlight int) AcknowledgedPacket func(EncryptionLevel, PacketNumber) LostPacket func(EncryptionLevel, PacketNumber, PacketLossReason) @@ -139,10 +139,10 @@ func NewMultiplexedConnectionTracer(tracers ...*ConnectionTracer) *ConnectionTra } } }, - DroppedPacket: func(typ PacketType, size ByteCount, reason PacketDropReason) { + DroppedPacket: func(typ PacketType, pn PacketNumber, size ByteCount, reason PacketDropReason) { for _, t := range tracers { if t.DroppedPacket != nil { - t.DroppedPacket(typ, size, reason) + t.DroppedPacket(typ, pn, size, reason) } } }, diff --git a/logging/multiplex_test.go b/logging/multiplex_test.go index 69606346262..e27ddc8cc62 100644 --- a/logging/multiplex_test.go +++ b/logging/multiplex_test.go @@ -184,9 +184,9 @@ var _ = Describe("Tracing", func() { }) It("traces the DroppedPacket event", func() { - tr1.EXPECT().DroppedPacket(PacketTypeInitial, ByteCount(1337), PacketDropHeaderParseError) - tr2.EXPECT().DroppedPacket(PacketTypeInitial, ByteCount(1337), PacketDropHeaderParseError) - tracer.DroppedPacket(PacketTypeInitial, 1337, PacketDropHeaderParseError) + tr1.EXPECT().DroppedPacket(PacketTypeInitial, PacketNumber(42), ByteCount(1337), PacketDropHeaderParseError) + tr2.EXPECT().DroppedPacket(PacketTypeInitial, PacketNumber(42), ByteCount(1337), PacketDropHeaderParseError) + tracer.DroppedPacket(PacketTypeInitial, 42, 1337, PacketDropHeaderParseError) }) It("traces the UpdatedCongestionState event", func() { diff --git a/qlog/event.go b/qlog/event.go index 740d3c2e19f..0082c04b85d 100644 --- a/qlog/event.go +++ b/qlog/event.go @@ -243,15 +243,16 @@ func (e eventPacketBuffered) IsNil() bool { return false } func (e eventPacketBuffered) MarshalJSONObject(enc *gojay.Encoder) { //nolint:gosimple - enc.ObjectKey("header", packetHeaderWithType{PacketType: e.PacketType}) + enc.ObjectKey("header", packetHeaderWithType{PacketType: e.PacketType, PacketNumber: protocol.InvalidPacketNumber}) enc.ObjectKey("raw", rawInfo{Length: e.PacketSize}) enc.StringKey("trigger", "keys_unavailable") } type eventPacketDropped struct { - PacketType logging.PacketType - PacketSize protocol.ByteCount - Trigger packetDropReason + PacketType logging.PacketType + PacketSize protocol.ByteCount + PacketNumber logging.PacketNumber + Trigger packetDropReason } func (e eventPacketDropped) Category() category { return categoryTransport } @@ -259,7 +260,10 @@ func (e eventPacketDropped) Name() string { return "packet_dropped" } func (e eventPacketDropped) IsNil() bool { return false } func (e eventPacketDropped) MarshalJSONObject(enc *gojay.Encoder) { - enc.ObjectKey("header", packetHeaderWithType{PacketType: e.PacketType}) + enc.ObjectKey("header", packetHeaderWithType{ + PacketType: e.PacketType, + PacketNumber: e.PacketNumber, + }) enc.ObjectKey("raw", rawInfo{Length: e.PacketSize}) enc.StringKey("trigger", e.Trigger.String()) } diff --git a/qlog/packet_header.go b/qlog/packet_header.go index 106499b0566..53c9f2b0da7 100644 --- a/qlog/packet_header.go +++ b/qlog/packet_header.go @@ -110,14 +110,18 @@ func (h packetHeaderVersionNegotiation) MarshalJSONObject(enc *gojay.Encoder) { enc.StringKey("dcid", h.DestConnectionID.String()) } -// a minimal header that only outputs the packet type +// a minimal header that only outputs the packet type, and potentially a packet number type packetHeaderWithType struct { - PacketType logging.PacketType + PacketType logging.PacketType + PacketNumber logging.PacketNumber } func (h packetHeaderWithType) IsNil() bool { return false } func (h packetHeaderWithType) MarshalJSONObject(enc *gojay.Encoder) { enc.StringKey("packet_type", packetType(h.PacketType).String()) + if h.PacketNumber != protocol.InvalidPacketNumber { + enc.Int64Key("packet_number", int64(h.PacketNumber)) + } } // a minimal header that only outputs the packet type diff --git a/qlog/qlog.go b/qlog/qlog.go index 7801b646358..90234b7dc59 100644 --- a/qlog/qlog.go +++ b/qlog/qlog.go @@ -106,8 +106,8 @@ func NewConnectionTracer(w io.WriteCloser, p protocol.Perspective, odcid protoco BufferedPacket: func(pt logging.PacketType, size protocol.ByteCount) { t.BufferedPacket(pt, size) }, - DroppedPacket: func(pt logging.PacketType, size protocol.ByteCount, reason logging.PacketDropReason) { - t.DroppedPacket(pt, size, reason) + DroppedPacket: func(pt logging.PacketType, pn logging.PacketNumber, size logging.ByteCount, reason logging.PacketDropReason) { + t.DroppedPacket(pt, pn, size, reason) }, UpdatedMetrics: func(rttStats *utils.RTTStats, cwnd, bytesInFlight protocol.ByteCount, packetsInFlight int) { t.UpdatedMetrics(rttStats, cwnd, bytesInFlight, packetsInFlight) @@ -444,12 +444,13 @@ func (t *connectionTracer) BufferedPacket(pt logging.PacketType, size protocol.B t.mutex.Unlock() } -func (t *connectionTracer) DroppedPacket(pt logging.PacketType, size protocol.ByteCount, reason logging.PacketDropReason) { +func (t *connectionTracer) DroppedPacket(pt logging.PacketType, pn logging.PacketNumber, size protocol.ByteCount, reason logging.PacketDropReason) { t.mutex.Lock() t.recordEvent(time.Now(), &eventPacketDropped{ - PacketType: pt, - PacketSize: size, - Trigger: packetDropReason(reason), + PacketType: pt, + PacketNumber: pn, + PacketSize: size, + Trigger: packetDropReason(reason), }) t.mutex.Unlock() } diff --git a/qlog/qlog_test.go b/qlog/qlog_test.go index a58f02780c8..11a49d88789 100644 --- a/qlog/qlog_test.go +++ b/qlog/qlog_test.go @@ -616,7 +616,7 @@ var _ = Describe("Tracing", func() { }) It("records dropped packets", func() { - tracer.DroppedPacket(logging.PacketTypeHandshake, 1337, logging.PacketDropPayloadDecryptError) + tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, 1337, logging.PacketDropPayloadDecryptError) entry := exportAndParseSingle() Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) Expect(entry.Name).To(Equal("transport:packet_dropped")) @@ -626,10 +626,26 @@ var _ = Describe("Tracing", func() { Expect(ev).To(HaveKey("header")) hdr := ev["header"].(map[string]interface{}) Expect(hdr).To(HaveLen(1)) - Expect(hdr).To(HaveKeyWithValue("packet_type", "handshake")) + Expect(hdr).To(HaveKeyWithValue("packet_type", "retry")) Expect(ev).To(HaveKeyWithValue("trigger", "payload_decrypt_error")) }) + It("records dropped packets with a packet number", func() { + tracer.DroppedPacket(logging.PacketTypeHandshake, 42, 1337, logging.PacketDropDuplicate) + entry := exportAndParseSingle() + Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) + Expect(entry.Name).To(Equal("transport:packet_dropped")) + ev := entry.Event + Expect(ev).To(HaveKey("raw")) + Expect(ev["raw"].(map[string]interface{})).To(HaveKeyWithValue("length", float64(1337))) + Expect(ev).To(HaveKey("header")) + hdr := ev["header"].(map[string]interface{}) + Expect(hdr).To(HaveLen(2)) + Expect(hdr).To(HaveKeyWithValue("packet_type", "handshake")) + Expect(hdr).To(HaveKeyWithValue("packet_number", float64(42))) + Expect(ev).To(HaveKeyWithValue("trigger", "duplicate")) + }) + It("records metrics updates", func() { now := time.Now() rttStats := utils.NewRTTStats() From 771d136fa9d3e6ee835422319f2897840378b7b6 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 23 Nov 2023 11:30:26 +0700 Subject: [PATCH 110/225] interop: update Go version to 1.21.4 (#4179) --- interop/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interop/Dockerfile b/interop/Dockerfile index afff1276773..636b9c59829 100644 --- a/interop/Dockerfile +++ b/interop/Dockerfile @@ -5,7 +5,7 @@ RUN echo "TARGETPLATFORM: ${TARGETPLATFORM}" RUN apt-get update && apt-get install -y wget tar git -ENV GOVERSION=1.20.7 +ENV GOVERSION=1.21.4 RUN platform=$(echo ${TARGETPLATFORM} | tr '/' '-') && \ filename="go${GOVERSION}.${platform}.tar.gz" && \ From 2d7ea376729d317e2fbce7ff5ae44ad180ffefdb Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 23 Nov 2023 17:41:12 +0700 Subject: [PATCH 111/225] wire: reject NEW_CONNECTION_ID frames with zero-length conneciton IDs (#4180) --- internal/wire/new_connection_id_frame.go | 4 ++++ internal/wire/new_connection_id_frame_test.go | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/internal/wire/new_connection_id_frame.go b/internal/wire/new_connection_id_frame.go index 83102d5d144..713ab99656f 100644 --- a/internal/wire/new_connection_id_frame.go +++ b/internal/wire/new_connection_id_frame.go @@ -2,6 +2,7 @@ package wire import ( "bytes" + "errors" "fmt" "io" @@ -34,6 +35,9 @@ func parseNewConnectionIDFrame(r *bytes.Reader, _ protocol.VersionNumber) (*NewC if err != nil { return nil, err } + if connIDLen == 0 { + return nil, errors.New("invalid zero-length connection ID") + } connID, err := protocol.ReadConnectionID(r, int(connIDLen)) if err != nil { return nil, err diff --git a/internal/wire/new_connection_id_frame_test.go b/internal/wire/new_connection_id_frame_test.go index 4628aaf24e3..02ef3000046 100644 --- a/internal/wire/new_connection_id_frame_test.go +++ b/internal/wire/new_connection_id_frame_test.go @@ -38,7 +38,15 @@ var _ = Describe("NEW_CONNECTION_ID frame", func() { Expect(err).To(MatchError("Retire Prior To value (1001) larger than Sequence Number (1000)")) }) - It("errors when the connection ID has an invalid length", func() { + It("errors when the connection ID has a zero-length connection ID", func() { + data := encodeVarInt(42) // sequence number + data = append(data, encodeVarInt(12)...) // retire prior to + data = append(data, 0) // connection ID length + _, err := parseNewConnectionIDFrame(bytes.NewReader(data), protocol.Version1) + Expect(err).To(MatchError("invalid zero-length connection ID")) + }) + + It("errors when the connection ID has an invalid length (too long)", func() { data := encodeVarInt(0xdeadbeef) // sequence number data = append(data, encodeVarInt(0xcafe)...) // retire prior to data = append(data, 21) // connection ID length From 7b9d21fbe6b96aa4942703df89fb93acc1ea77a9 Mon Sep 17 00:00:00 2001 From: chungthuang <7826979+chungthuang@users.noreply.github.com> Date: Sat, 2 Dec 2023 14:27:15 +0000 Subject: [PATCH 112/225] send large max_datagram_frame size, introduce a DatagramTooLargeError error (#4143) The size can be overwritten to a lower value for testing. --- connection.go | 10 ++++++---- errors.go | 12 ++++++++++++ integrationtests/self/datagram_test.go | 23 ++++++++++++++++------- internal/protocol/params.go | 4 ---- internal/wire/datagram_frame.go | 6 ++++++ internal/wire/transport_parameter_test.go | 2 +- 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/connection.go b/connection.go index 7f26ef5e565..1b288a2b3c6 100644 --- a/connection.go +++ b/connection.go @@ -307,7 +307,7 @@ var newConnection = func( RetrySourceConnectionID: retrySrcConnID, } if s.config.EnableDatagrams { - params.MaxDatagramFrameSize = protocol.MaxDatagramFrameSize + params.MaxDatagramFrameSize = wire.MaxDatagramSize } else { params.MaxDatagramFrameSize = protocol.InvalidByteCount } @@ -414,7 +414,7 @@ var newClientConnection = func( InitialSourceConnectionID: srcConnID, } if s.config.EnableDatagrams { - params.MaxDatagramFrameSize = protocol.MaxDatagramFrameSize + params.MaxDatagramFrameSize = wire.MaxDatagramSize } else { params.MaxDatagramFrameSize = protocol.InvalidByteCount } @@ -1522,7 +1522,7 @@ func (s *connection) handleAckFrame(frame *wire.AckFrame, encLevel protocol.Encr } func (s *connection) handleDatagramFrame(f *wire.DatagramFrame) error { - if f.Length(s.version) > protocol.MaxDatagramFrameSize { + if f.Length(s.version) > wire.MaxDatagramSize { return &qerr.TransportError{ ErrorCode: qerr.ProtocolViolation, ErrorMessage: "DATAGRAM frame too large", @@ -2350,7 +2350,9 @@ func (s *connection) SendDatagram(p []byte) error { f := &wire.DatagramFrame{DataLenPresent: true} if protocol.ByteCount(len(p)) > f.MaxDataLen(s.peerParams.MaxDatagramFrameSize, s.version) { - return errors.New("message too large") + return &DatagramTooLargeError{ + PeerMaxDatagramFrameSize: int64(s.peerParams.MaxDatagramFrameSize), + } } f.Data = make([]byte, len(p)) copy(f.Data, p) diff --git a/errors.go b/errors.go index c9fb0a07b08..fda3c9247cc 100644 --- a/errors.go +++ b/errors.go @@ -61,3 +61,15 @@ func (e *StreamError) Error() string { } return fmt.Sprintf("stream %d canceled by %s with error code %d", e.StreamID, pers, e.ErrorCode) } + +// DatagramTooLargeError is returned from Connection.SendDatagram if the payload is too large to be sent. +type DatagramTooLargeError struct { + PeerMaxDatagramFrameSize int64 +} + +func (e *DatagramTooLargeError) Is(target error) bool { + _, ok := target.(*DatagramTooLargeError) + return ok +} + +func (e *DatagramTooLargeError) Error() string { return "DATAGRAM frame too large" } diff --git a/integrationtests/self/datagram_test.go b/integrationtests/self/datagram_test.go index 55e85771620..f9608272b03 100644 --- a/integrationtests/self/datagram_test.go +++ b/integrationtests/self/datagram_test.go @@ -19,7 +19,8 @@ import ( ) var _ = Describe("Datagram test", func() { - const num = 100 + const concurrentSends = 100 + const maxDatagramSize = 250 var ( serverConn, clientConn *net.UDPConn @@ -47,11 +48,11 @@ var _ = Describe("Datagram test", func() { if expectDatagramSupport { Expect(conn.ConnectionState().SupportsDatagrams).To(BeTrue()) - if enableDatagram { + f := &wire.DatagramFrame{DataLenPresent: true} var wg sync.WaitGroup - wg.Add(num) - for i := 0; i < num; i++ { + wg.Add(concurrentSends) + for i := 0; i < concurrentSends; i++ { go func(i int) { defer GinkgoRecover() defer wg.Done() @@ -60,6 +61,11 @@ var _ = Describe("Datagram test", func() { Expect(conn.SendDatagram(b)).To(Succeed()) }(i) } + maxDatagramMessageSize := f.MaxDataLen(maxDatagramSize, conn.ConnectionState().Version) + b := make([]byte, maxDatagramMessageSize+1) + Expect(conn.SendDatagram(b)).To(MatchError(&quic.DatagramTooLargeError{ + PeerMaxDatagramFrameSize: int64(maxDatagramMessageSize), + })) wg.Wait() } } else { @@ -103,6 +109,8 @@ var _ = Describe("Datagram test", func() { }) It("sends datagrams", func() { + oldMaxDatagramSize := wire.MaxDatagramSize + wire.MaxDatagramSize = maxDatagramSize proxyPort, close := startServerAndProxy(true, true) defer close() raddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("localhost:%d", proxyPort)) @@ -128,14 +136,15 @@ var _ = Describe("Datagram test", func() { } numDropped := int(dropped.Load()) - expVal := num - numDropped + expVal := concurrentSends - numDropped fmt.Fprintf(GinkgoWriter, "Dropped %d out of %d packets.\n", numDropped, total.Load()) - fmt.Fprintf(GinkgoWriter, "Received %d out of %d sent datagrams.\n", counter, num) + fmt.Fprintf(GinkgoWriter, "Received %d out of %d sent datagrams.\n", counter, concurrentSends) Expect(counter).To(And( BeNumerically(">", expVal*9/10), - BeNumerically("<", num), + BeNumerically("<", concurrentSends), )) Eventually(conn.Context().Done).Should(BeClosed()) + wire.MaxDatagramSize = oldMaxDatagramSize }) It("server can disable datagram", func() { diff --git a/internal/protocol/params.go b/internal/protocol/params.go index 3ca68bf83d0..28b6da7cdd4 100644 --- a/internal/protocol/params.go +++ b/internal/protocol/params.go @@ -129,10 +129,6 @@ const MaxPostHandshakeCryptoFrameSize = 1000 // but must ensure that a maximum size ACK frame fits into one packet. const MaxAckFrameSize ByteCount = 1000 -// MaxDatagramFrameSize is the maximum size of a DATAGRAM frame (RFC 9221). -// The size is chosen such that a DATAGRAM frame fits into a QUIC packet. -const MaxDatagramFrameSize ByteCount = 1200 - // DatagramRcvQueueLen is the length of the receive queue for DATAGRAM frames (RFC 9221) const DatagramRcvQueueLen = 128 diff --git a/internal/wire/datagram_frame.go b/internal/wire/datagram_frame.go index e6c45196181..4d001084626 100644 --- a/internal/wire/datagram_frame.go +++ b/internal/wire/datagram_frame.go @@ -8,6 +8,12 @@ import ( "github.com/quic-go/quic-go/quicvarint" ) +// MaxDatagramSize is the maximum size of a DATAGRAM frame (RFC 9221). +// By setting it to a large value, we allow all datagrams that fit into a QUIC packet. +// The value is chosen such that it can still be encoded as a 2 byte varint. +// This is a var and not a const so it can be set in tests. +var MaxDatagramSize protocol.ByteCount = 16383 + // A DatagramFrame is a DATAGRAM frame type DatagramFrame struct { DataLenPresent bool diff --git a/internal/wire/transport_parameter_test.go b/internal/wire/transport_parameter_test.go index 2fb795395db..a82b6dcf522 100644 --- a/internal/wire/transport_parameter_test.go +++ b/internal/wire/transport_parameter_test.go @@ -503,7 +503,7 @@ var _ = Describe("Transport Parameters", func() { MaxBidiStreamNum: protocol.StreamNum(getRandomValueUpTo(int64(protocol.MaxStreamCount))), MaxUniStreamNum: protocol.StreamNum(getRandomValueUpTo(int64(protocol.MaxStreamCount))), ActiveConnectionIDLimit: 2 + getRandomValueUpTo(math.MaxInt64-2), - MaxDatagramFrameSize: protocol.ByteCount(getRandomValueUpTo(int64(protocol.MaxDatagramFrameSize))), + MaxDatagramFrameSize: protocol.ByteCount(getRandomValueUpTo(int64(MaxDatagramSize))), } Expect(params.ValidFor0RTT(params)).To(BeTrue()) b := params.MarshalForSessionTicket(nil) From 87ef8ec48d5525eeac357c2126c30bb3dc1fd490 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 3 Dec 2023 19:23:36 +0530 Subject: [PATCH 113/225] fuzzing: add transport parameter validation logic (#4175) --- fuzzing/transportparameters/fuzz.go | 50 +++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/fuzzing/transportparameters/fuzz.go b/fuzzing/transportparameters/fuzz.go index a3ca143d3ee..d0dd975fdcc 100644 --- a/fuzzing/transportparameters/fuzz.go +++ b/fuzzing/transportparameters/fuzz.go @@ -2,6 +2,7 @@ package transportparameters import ( "bytes" + "errors" "fmt" "github.com/quic-go/quic-go/fuzzing/internal/helper" @@ -26,23 +27,29 @@ func Fuzz(data []byte) int { return fuzzTransportParameters(data[PrefixLen:], helper.NthBit(data[0], 1)) } -func fuzzTransportParameters(data []byte, isServer bool) int { - perspective := protocol.PerspectiveClient - if isServer { - perspective = protocol.PerspectiveServer +func fuzzTransportParameters(data []byte, sentByServer bool) int { + sentBy := protocol.PerspectiveClient + if sentByServer { + sentBy = protocol.PerspectiveServer } tp := &wire.TransportParameters{} - if err := tp.Unmarshal(data, perspective); err != nil { + if err := tp.Unmarshal(data, sentBy); err != nil { return 0 } _ = tp.String() + if err := validateTransportParameters(tp, sentBy); err != nil { + panic(err) + } tp2 := &wire.TransportParameters{} - if err := tp2.Unmarshal(tp.Marshal(perspective), perspective); err != nil { + if err := tp2.Unmarshal(tp.Marshal(sentBy), sentBy); err != nil { fmt.Printf("%#v\n", tp) panic(err) } + if err := validateTransportParameters(tp2, sentBy); err != nil { + panic(err) + } return 1 } @@ -58,3 +65,34 @@ func fuzzTransportParametersForSessionTicket(data []byte) int { } return 1 } + +func validateTransportParameters(tp *wire.TransportParameters, sentBy protocol.Perspective) error { + if sentBy == protocol.PerspectiveClient && tp.StatelessResetToken != nil { + return errors.New("client's transport parameters contained stateless reset token") + } + if tp.MaxIdleTimeout < 0 { + return fmt.Errorf("negative max_idle_timeout: %s", tp.MaxIdleTimeout) + } + if tp.AckDelayExponent > 20 { + return fmt.Errorf("invalid ack_delay_exponent: %d", tp.AckDelayExponent) + } + if tp.MaxUDPPayloadSize < 1200 { + return fmt.Errorf("invalid max_udp_payload_size: %d", tp.MaxUDPPayloadSize) + } + if tp.ActiveConnectionIDLimit < 2 { + return fmt.Errorf("invalid active_connection_id_limit: %d", tp.ActiveConnectionIDLimit) + } + if tp.OriginalDestinationConnectionID.Len() > 20 { + return fmt.Errorf("invalid original_destination_connection_id length: %s", tp.InitialSourceConnectionID) + } + if tp.InitialSourceConnectionID.Len() > 20 { + return fmt.Errorf("invalid initial_source_connection_id length: %s", tp.InitialSourceConnectionID) + } + if tp.RetrySourceConnectionID != nil && tp.RetrySourceConnectionID.Len() > 20 { + return fmt.Errorf("invalid retry_source_connection_id length: %s", tp.RetrySourceConnectionID) + } + if tp.PreferredAddress != nil && tp.PreferredAddress.ConnectionID.Len() > 20 { + return fmt.Errorf("invalid preferred_address connection ID length: %s", tp.PreferredAddress.ConnectionID) + } + return nil +} From 45922f76d69e4a923ddd4ab43fb7888e7e887901 Mon Sep 17 00:00:00 2001 From: Benedikt Spies Date: Wed, 6 Dec 2023 15:00:58 +0100 Subject: [PATCH 114/225] reduce calls to time.Now() calls in connection (#4191) --- connection.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/connection.go b/connection.go index 1b288a2b3c6..75ede6cba9a 100644 --- a/connection.go +++ b/connection.go @@ -629,7 +629,7 @@ runLoop: sendQueueAvailable = s.sendQueue.Available() continue } - if err := s.triggerSending(); err != nil { + if err := s.triggerSending(now); err != nil { s.closeLocal(err) } if s.sendQueue.WouldBlock() { @@ -1767,9 +1767,8 @@ func (s *connection) applyTransportParameters() { } } -func (s *connection) triggerSending() error { +func (s *connection) triggerSending(now time.Time) error { s.pacingDeadline = time.Time{} - now := time.Now() sendMode := s.sentPacketHandler.SendMode(now) //nolint:exhaustive // No need to handle pacing limited here. @@ -1801,7 +1800,7 @@ func (s *connection) triggerSending() error { s.scheduleSending() return nil } - return s.triggerSending() + return s.triggerSending(now) case ackhandler.SendPTOHandshake: if err := s.sendProbePacket(protocol.EncryptionHandshake, now); err != nil { return err @@ -1810,7 +1809,7 @@ func (s *connection) triggerSending() error { s.scheduleSending() return nil } - return s.triggerSending() + return s.triggerSending(now) case ackhandler.SendPTOAppData: if err := s.sendProbePacket(protocol.Encryption1RTT, now); err != nil { return err @@ -1819,7 +1818,7 @@ func (s *connection) triggerSending() error { s.scheduleSending() return nil } - return s.triggerSending() + return s.triggerSending(now) default: return fmt.Errorf("BUG: invalid send mode %d", sendMode) } @@ -1988,7 +1987,7 @@ func (s *connection) maybeSendAckOnlyPacket(now time.Time) error { if packet == nil { return nil } - return s.sendPackedCoalescedPacket(packet, ecn, time.Now()) + return s.sendPackedCoalescedPacket(packet, ecn, now) } ecn := s.sentPacketHandler.ECNMode(true) From 9b40c50a738167184a9eb2c6e02b4171c8b16392 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 6 Dec 2023 19:52:23 +0530 Subject: [PATCH 115/225] http3: use the AdditionalSettings for requests (#4156) --- http3/roundtrip.go | 1 + http3/roundtrip_test.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/http3/roundtrip.go b/http3/roundtrip.go index bed42103009..d86b0bb22b1 100644 --- a/http3/roundtrip.go +++ b/http3/roundtrip.go @@ -202,6 +202,7 @@ func (r *RoundTripper) getClient(hostname string, onlyCached bool) (rtc *roundTr MaxHeaderBytes: r.MaxResponseHeaderBytes, StreamHijacker: r.StreamHijacker, UniStreamHijacker: r.UniStreamHijacker, + AdditionalSettings: r.AdditionalSettings, }, r.QuicConfig, dial, diff --git a/http3/roundtrip_test.go b/http3/roundtrip_test.go index 30672384a53..8b59a8bb72c 100644 --- a/http3/roundtrip_test.go +++ b/http3/roundtrip_test.go @@ -71,6 +71,21 @@ var _ = Describe("RoundTripper", func() { Expect(err).To(MatchError(testErr)) }) + It("creates new clients with additional settings", func() { + testErr := errors.New("test err") + req, err := http.NewRequest("GET", "https://quic.clemente.io/foobar.html", nil) + Expect(err).ToNot(HaveOccurred()) + rt.AdditionalSettings = map[uint64]uint64{1337: 42} + rt.newClient = func(_ string, _ *tls.Config, opts *roundTripperOpts, conf *quic.Config, _ dialFunc) (roundTripCloser, error) { + cl := NewMockRoundTripCloser(mockCtrl) + cl.EXPECT().RoundTripOpt(gomock.Any(), gomock.Any()).Return(nil, testErr) + Expect(opts.AdditionalSettings).To(HaveKeyWithValue(uint64(1337), uint64(42))) + return cl, nil + } + _, err = rt.RoundTrip(req) + Expect(err).To(MatchError(testErr)) + }) + It("uses the quic.Config, if provided", func() { config := &quic.Config{HandshakeIdleTimeout: time.Millisecond} var receivedConfig *quic.Config From 38eafe4ad82a21ff1f6ab57d9a64c71110fe9e7e Mon Sep 17 00:00:00 2001 From: Charles Xu <6831013+char8x@users.noreply.github.com> Date: Thu, 7 Dec 2023 11:18:33 +0800 Subject: [PATCH 116/225] README: add gost project (#4154) * chore: add project * fix name * revert unrelated whitespace fix --------- Co-authored-by: Marten Seemann --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cfb4e612372..cc4f609f1d9 100644 --- a/README.md +++ b/README.md @@ -227,12 +227,13 @@ http.Client{ ## Projects using quic-go | Project | Description | Stars | -| --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | [AdGuardHome](https://github.com/AdguardTeam/AdGuardHome) | Free and open source, powerful network-wide ads & trackers blocking DNS server. | ![GitHub Repo stars](https://img.shields.io/github/stars/AdguardTeam/AdGuardHome?style=flat-square) | | [algernon](https://github.com/xyproto/algernon) | Small self-contained pure-Go web server with Lua, Markdown, HTTP/2, QUIC, Redis and PostgreSQL support | ![GitHub Repo stars](https://img.shields.io/github/stars/xyproto/algernon?style=flat-square) | | [caddy](https://github.com/caddyserver/caddy/) | Fast, multi-platform web server with automatic HTTPS | ![GitHub Repo stars](https://img.shields.io/github/stars/caddyserver/caddy?style=flat-square) | | [cloudflared](https://github.com/cloudflare/cloudflared) | A tunneling daemon that proxies traffic from the Cloudflare network to your origins | ![GitHub Repo stars](https://img.shields.io/github/stars/cloudflare/cloudflared?style=flat-square) | -| [go-libp2p](https://github.com/libp2p/go-libp2p) | libp2p implementation in Go, powering [Kubo](https://github.com/ipfs/kubo) (IPFS) and [Lotus](https://github.com/filecoin-project/lotus) (Filecoin), among others | ![GitHub Repo stars](https://img.shields.io/github/stars/libp2p/go-libp2p?style=flat-square) | +| [go-libp2p](https://github.com/libp2p/go-libp2p) | libp2p implementation in Go, powering [Kubo](https://github.com/ipfs/kubo) (IPFS) and [Lotus](https://github.com/filecoin-project/lotus) (Filecoin), among others | ![GitHub Repo stars](https://img.shields.io/github/stars/libp2p/go-libp2p?style=flat-square) | +| [gost](https://github.com/go-gost/gost) | A simple security tunnel written in Go | ![GitHub Repo stars](https://img.shields.io/github/stars/go-gost/gost?style=flat-square) | | [Hysteria](https://github.com/apernet/hysteria) | A powerful, lightning fast and censorship resistant proxy | ![GitHub Repo stars](https://img.shields.io/github/stars/apernet/hysteria?style=flat-square) | | [Mercure](https://github.com/dunglas/mercure) | An open, easy, fast, reliable and battery-efficient solution for real-time communications | ![GitHub Repo stars](https://img.shields.io/github/stars/dunglas/mercure?style=flat-square) | | [OONI Probe](https://github.com/ooni/probe-cli) | Next generation OONI Probe. Library and CLI tool. | ![GitHub Repo stars](https://img.shields.io/github/stars/ooni/probe-cli?style=flat-square) | From d234d62d526e99d8a499b3287994c8a1c6597b31 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 9 Dec 2023 19:47:47 +0530 Subject: [PATCH 117/225] qtls: only attempt 0-RTT resumption for 0-RTT enabled session tickets (#4183) --- integrationtests/self/zero_rtt_oldgo_test.go | 43 ++++++++++++++++++++ integrationtests/self/zero_rtt_test.go | 43 ++++++++++++++++++++ internal/handshake/crypto_setup.go | 34 ++++++++++------ internal/qtls/client_session_cache.go | 13 +++--- internal/qtls/client_session_cache_test.go | 5 ++- internal/qtls/go120.go | 16 ++++++-- internal/qtls/go121.go | 6 ++- 7 files changed, 135 insertions(+), 25 deletions(-) diff --git a/integrationtests/self/zero_rtt_oldgo_test.go b/integrationtests/self/zero_rtt_oldgo_test.go index aea54271c62..af5400d1dd2 100644 --- a/integrationtests/self/zero_rtt_oldgo_test.go +++ b/integrationtests/self/zero_rtt_oldgo_test.go @@ -641,6 +641,49 @@ var _ = Describe("0-RTT", func() { Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) }) + It("doesn't use 0-RTT, if the server didn't enable it", func() { + server, err := quic.ListenAddr("localhost:0", getTLSConfig(), getQuicConfig(nil)) + Expect(err).ToNot(HaveOccurred()) + defer server.Close() + + gets := make(chan string, 100) + puts := make(chan string, 100) + cache := newClientSessionCache(tls.NewLRUClientSessionCache(10), gets, puts) + tlsConf := getTLSClientConfig() + tlsConf.ClientSessionCache = cache + conn1, err := quic.DialAddr( + context.Background(), + fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), + tlsConf, + getQuicConfig(nil), + ) + Expect(err).ToNot(HaveOccurred()) + defer conn1.CloseWithError(0, "") + var sessionKey string + Eventually(puts).Should(Receive(&sessionKey)) + Expect(conn1.ConnectionState().TLS.DidResume).To(BeFalse()) + + serverConn, err := server.Accept(context.Background()) + Expect(err).ToNot(HaveOccurred()) + Expect(serverConn.ConnectionState().TLS.DidResume).To(BeFalse()) + + conn2, err := quic.DialAddrEarly( + context.Background(), + fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), + tlsConf, + getQuicConfig(nil), + ) + Expect(err).ToNot(HaveOccurred()) + Expect(gets).To(Receive(Equal(sessionKey))) + Expect(conn2.ConnectionState().TLS.DidResume).To(BeTrue()) + + serverConn, err = server.Accept(context.Background()) + Expect(err).ToNot(HaveOccurred()) + Expect(serverConn.ConnectionState().TLS.DidResume).To(BeTrue()) + Expect(serverConn.ConnectionState().Used0RTT).To(BeFalse()) + conn2.CloseWithError(0, "") + }) + DescribeTable("flow control limits", func(addFlowControlLimit func(*quic.Config, uint64)) { counter, tracer := newPacketTracer() diff --git a/integrationtests/self/zero_rtt_test.go b/integrationtests/self/zero_rtt_test.go index c0fc5325ff0..7bfa66cef23 100644 --- a/integrationtests/self/zero_rtt_test.go +++ b/integrationtests/self/zero_rtt_test.go @@ -692,6 +692,49 @@ var _ = Describe("0-RTT", func() { Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) }) + It("doesn't use 0-RTT, if the server didn't enable it", func() { + server, err := quic.ListenAddr("localhost:0", getTLSConfig(), getQuicConfig(nil)) + Expect(err).ToNot(HaveOccurred()) + defer server.Close() + + gets := make(chan string, 100) + puts := make(chan string, 100) + cache := newClientSessionCache(tls.NewLRUClientSessionCache(10), gets, puts) + tlsConf := getTLSClientConfig() + tlsConf.ClientSessionCache = cache + conn1, err := quic.DialAddr( + context.Background(), + fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), + tlsConf, + getQuicConfig(nil), + ) + Expect(err).ToNot(HaveOccurred()) + defer conn1.CloseWithError(0, "") + var sessionKey string + Eventually(puts).Should(Receive(&sessionKey)) + Expect(conn1.ConnectionState().TLS.DidResume).To(BeFalse()) + + serverConn, err := server.Accept(context.Background()) + Expect(err).ToNot(HaveOccurred()) + Expect(serverConn.ConnectionState().TLS.DidResume).To(BeFalse()) + + conn2, err := quic.DialAddrEarly( + context.Background(), + fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), + tlsConf, + getQuicConfig(nil), + ) + Expect(err).ToNot(HaveOccurred()) + Expect(gets).To(Receive(Equal(sessionKey))) + Expect(conn2.ConnectionState().TLS.DidResume).To(BeTrue()) + + serverConn, err = server.Accept(context.Background()) + Expect(err).ToNot(HaveOccurred()) + Expect(serverConn.ConnectionState().TLS.DidResume).To(BeTrue()) + Expect(serverConn.ConnectionState().Used0RTT).To(BeFalse()) + conn2.CloseWithError(0, "") + }) + DescribeTable("flow control limits", func(addFlowControlLimit func(*quic.Config, uint64)) { counter, tracer := newPacketTracer() diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index c5787e86a6d..34f298871c1 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -25,7 +25,7 @@ type quicVersionContextKey struct{} var QUICVersionContextKey = &quicVersionContextKey{} -const clientSessionStateRevision = 3 +const clientSessionStateRevision = 4 type cryptoSetup struct { tlsConf *tls.Config @@ -313,19 +313,24 @@ func (h *cryptoSetup) handleTransportParameters(data []byte) error { } // must be called after receiving the transport parameters -func (h *cryptoSetup) marshalDataForSessionState() []byte { +func (h *cryptoSetup) marshalDataForSessionState(earlyData bool) []byte { b := make([]byte, 0, 256) b = quicvarint.Append(b, clientSessionStateRevision) b = quicvarint.Append(b, uint64(h.rttStats.SmoothedRTT().Microseconds())) - return h.peerParams.MarshalForSessionTicket(b) + if earlyData { + // only save the transport parameters for 0-RTT enabled session tickets + return h.peerParams.MarshalForSessionTicket(b) + } + return b } -func (h *cryptoSetup) handleDataFromSessionState(data []byte) (allowEarlyData bool) { - tp, err := h.handleDataFromSessionStateImpl(data) +func (h *cryptoSetup) handleDataFromSessionState(data []byte, earlyData bool) (allowEarlyData bool) { + rtt, tp, err := decodeDataFromSessionState(data, earlyData) if err != nil { h.logger.Debugf("Restoring of transport parameters from session ticket failed: %s", err.Error()) return } + h.rttStats.SetInitialRTT(rtt) // The session ticket might have been saved from a connection that allowed 0-RTT, // and therefore contain transport parameters. // Only use them if 0-RTT is actually used on the new connection. @@ -336,25 +341,28 @@ func (h *cryptoSetup) handleDataFromSessionState(data []byte) (allowEarlyData bo return false } -func (h *cryptoSetup) handleDataFromSessionStateImpl(data []byte) (*wire.TransportParameters, error) { +func decodeDataFromSessionState(data []byte, earlyData bool) (time.Duration, *wire.TransportParameters, error) { r := bytes.NewReader(data) ver, err := quicvarint.Read(r) if err != nil { - return nil, err + return 0, nil, err } if ver != clientSessionStateRevision { - return nil, fmt.Errorf("mismatching version. Got %d, expected %d", ver, clientSessionStateRevision) + return 0, nil, fmt.Errorf("mismatching version. Got %d, expected %d", ver, clientSessionStateRevision) } - rtt, err := quicvarint.Read(r) + rttEncoded, err := quicvarint.Read(r) if err != nil { - return nil, err + return 0, nil, err + } + rtt := time.Duration(rttEncoded) * time.Microsecond + if !earlyData { + return rtt, nil, nil } - h.rttStats.SetInitialRTT(time.Duration(rtt) * time.Microsecond) var tp wire.TransportParameters if err := tp.UnmarshalFromSessionTicket(r); err != nil { - return nil, err + return 0, nil, err } - return &tp, nil + return rtt, &tp, nil } func (h *cryptoSetup) getDataForSessionTicket() []byte { diff --git a/internal/qtls/client_session_cache.go b/internal/qtls/client_session_cache.go index 336d6035af9..d81eb8c3de4 100644 --- a/internal/qtls/client_session_cache.go +++ b/internal/qtls/client_session_cache.go @@ -7,8 +7,8 @@ import ( ) type clientSessionCache struct { - getData func() []byte - setData func([]byte) (allowEarlyData bool) + getData func(earlyData bool) []byte + setData func(data []byte, earlyData bool) (allowEarlyData bool) wrapped tls.ClientSessionCache } @@ -24,7 +24,7 @@ func (c clientSessionCache) Put(key string, cs *tls.ClientSessionState) { c.wrapped.Put(key, cs) return } - state.Extra = append(state.Extra, addExtraPrefix(c.getData())) + state.Extra = append(state.Extra, addExtraPrefix(c.getData(state.EarlyData))) newCS, err := tls.NewResumptionState(ticket, state) if err != nil { // It's not clear why this would error. Just save the original state. @@ -46,12 +46,13 @@ func (c clientSessionCache) Get(key string) (*tls.ClientSessionState, bool) { c.wrapped.Put(key, nil) return nil, false } - var earlyData bool // restore QUIC transport parameters and RTT stored in state.Extra if extra := findExtraData(state.Extra); extra != nil { - earlyData = c.setData(extra) + earlyData := c.setData(extra, state.EarlyData) + if state.EarlyData { + state.EarlyData = earlyData + } } - state.EarlyData = earlyData session, err := tls.NewResumptionState(ticket, state) if err != nil { // It's not clear why this would error. diff --git a/internal/qtls/client_session_cache_test.go b/internal/qtls/client_session_cache_test.go index 6af192935fa..fdb0aa06182 100644 --- a/internal/qtls/client_session_cache_test.go +++ b/internal/qtls/client_session_cache_test.go @@ -40,8 +40,9 @@ var _ = Describe("Client Session Cache", func() { RootCAs: testdata.GetRootCA(), ClientSessionCache: &clientSessionCache{ wrapped: tls.NewLRUClientSessionCache(10), - getData: func() []byte { return []byte("session") }, - setData: func(data []byte) bool { + getData: func(bool) []byte { return []byte("session") }, + setData: func(data []byte, earlyData bool) bool { + Expect(earlyData).To(BeFalse()) // running on top of TCP, we can only test non-0-RTT here restored <- data return true }, diff --git a/internal/qtls/go120.go b/internal/qtls/go120.go index 7e7eee1ea3a..554aeaf4d2b 100644 --- a/internal/qtls/go120.go +++ b/internal/qtls/go120.go @@ -52,10 +52,20 @@ func SetupConfigForServer(conf *QUICConfig, enable0RTT bool, getDataForSessionTi } } -func SetupConfigForClient(conf *QUICConfig, getDataForSessionState func() []byte, setDataFromSessionState func([]byte) bool) { +func SetupConfigForClient( + conf *QUICConfig, + getDataForSessionState func(earlyData bool) []byte, + setDataFromSessionState func(data []byte, earlyData bool) (allowEarlyData bool), +) { conf.ExtraConfig = &qtls.ExtraConfig{ - GetAppDataForSessionState: getDataForSessionState, - SetAppDataFromSessionState: setDataFromSessionState, + GetAppDataForSessionState: func() []byte { + // qtls only calls the GetAppDataForSessionState when doing 0-RTT + return getDataForSessionState(true) + }, + SetAppDataFromSessionState: func(data []byte) (allowEarlyData bool) { + // qtls only calls the SetAppDataFromSessionState for 0-RTT enabled tickets + return setDataFromSessionState(data, true) + }, } } diff --git a/internal/qtls/go121.go b/internal/qtls/go121.go index 35a52ce09b6..66e289b5afc 100644 --- a/internal/qtls/go121.go +++ b/internal/qtls/go121.go @@ -93,7 +93,11 @@ func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, hand } } -func SetupConfigForClient(qconf *QUICConfig, getData func() []byte, setData func([]byte) bool) { +func SetupConfigForClient( + qconf *QUICConfig, + getData func(earlyData bool) []byte, + setData func(data []byte, earlyData bool) (allowEarlyData bool), +) { conf := qconf.TLSConfig if conf.ClientSessionCache != nil { origCache := conf.ClientSessionCache From f162b948db500503d36572fffe9bb90ab3215e7a Mon Sep 17 00:00:00 2001 From: "fengyun.rui" Date: Sun, 10 Dec 2023 01:05:31 +0800 Subject: [PATCH 118/225] examples: close listener, connection and stream in echo client and server (#4188) * fix: add close func in example Signed-off-by: rfyiamcool * fix: add close func in example Signed-off-by: rfyiamcool * fix: add close func in example Signed-off-by: rfyiamcool --------- Signed-off-by: rfyiamcool --- example/echo/echo.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/example/echo/echo.go b/example/echo/echo.go index 011c70a3f40..7c81c826866 100644 --- a/example/echo/echo.go +++ b/example/echo/echo.go @@ -36,14 +36,19 @@ func echoServer() error { if err != nil { return err } + defer listener.Close() + conn, err := listener.Accept(context.Background()) if err != nil { return err } + stream, err := conn.AcceptStream(context.Background()) if err != nil { panic(err) } + defer stream.Close() + // Echo through the loggingWriter _, err = io.Copy(loggingWriter{stream}, stream) return err @@ -58,11 +63,13 @@ func clientMain() error { if err != nil { return err } + defer conn.CloseWithError(0, "") stream, err := conn.OpenStreamSync(context.Background()) if err != nil { return err } + defer stream.Close() fmt.Printf("Client: Sending '%s'\n", message) _, err = stream.Write([]byte(message)) From 659da8ca08995239a3a64e4bed89b40c31ffb3ac Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 9 Dec 2023 22:50:09 +0530 Subject: [PATCH 119/225] fuzzing: update Go version used on OSS-Fuzz to 1.21 (#4192) --- .clusterfuzzlite/Dockerfile | 2 +- oss-fuzz.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.clusterfuzzlite/Dockerfile b/.clusterfuzzlite/Dockerfile index b57da8caa99..d27db151840 100644 --- a/.clusterfuzzlite/Dockerfile +++ b/.clusterfuzzlite/Dockerfile @@ -3,7 +3,7 @@ FROM gcr.io/oss-fuzz-base/base-builder-go:v1 ARG TARGETPLATFORM RUN echo "TARGETPLATFORM: ${TARGETPLATFORM}" -ENV GOVERSION=1.20.7 +ENV GOVERSION=1.21.5 RUN platform=$(echo ${TARGETPLATFORM} | tr '/' '-') && \ filename="go${GOVERSION}.${platform}.tar.gz" && \ diff --git a/oss-fuzz.sh b/oss-fuzz.sh index 1efe6baa682..f72fb1b03f5 100644 --- a/oss-fuzz.sh +++ b/oss-fuzz.sh @@ -3,12 +3,12 @@ # Install Go manually, since oss-fuzz ships with an outdated Go version. # See https://github.com/google/oss-fuzz/pull/10643. export CXX="${CXX} -lresolv" # required by Go 1.20 -wget https://go.dev/dl/go1.20.5.linux-amd64.tar.gz \ +wget https://go.dev/dl/go1.21.5.linux-amd64.tar.gz \ && mkdir temp-go \ && rm -rf /root/.go/* \ - && tar -C temp-go/ -xzf go1.20.5.linux-amd64.tar.gz \ + && tar -C temp-go/ -xzf go1.21.5.linux-amd64.tar.gz \ && mv temp-go/go/* /root/.go/ \ - && rm -rf temp-go go1.20.5.linux-amd64.tar.gz + && rm -rf temp-go go1.21.5.linux-amd64.tar.gz ( # fuzz qpack From a7a66f64376746eb0acd095aa93e6852fc4b4631 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 10 Dec 2023 16:30:26 +0530 Subject: [PATCH 120/225] integrationtests: remove leftover code for Go 1.19 (#4193) --- integrationtests/self/go119_test.go | 21 -------- integrationtests/self/go120_test.go | 22 -------- integrationtests/self/http_test.go | 82 ++++++++++++++--------------- 3 files changed, 40 insertions(+), 85 deletions(-) delete mode 100644 integrationtests/self/go119_test.go delete mode 100644 integrationtests/self/go120_test.go diff --git a/integrationtests/self/go119_test.go b/integrationtests/self/go119_test.go deleted file mode 100644 index c676693daed..00000000000 --- a/integrationtests/self/go119_test.go +++ /dev/null @@ -1,21 +0,0 @@ -//go:build go1.19 && !go1.20 - -package self_test - -import ( - "errors" - "net/http" - "time" -) - -const go120 = false - -var errNotSupported = errors.New("not supported") - -func setReadDeadline(w http.ResponseWriter, deadline time.Time) error { - return errNotSupported -} - -func setWriteDeadline(w http.ResponseWriter, deadline time.Time) error { - return errNotSupported -} diff --git a/integrationtests/self/go120_test.go b/integrationtests/self/go120_test.go deleted file mode 100644 index 88eb4a7ed43..00000000000 --- a/integrationtests/self/go120_test.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build go1.20 - -package self_test - -import ( - "net/http" - "time" -) - -const go120 = true - -func setReadDeadline(w http.ResponseWriter, deadline time.Time) error { - rc := http.NewResponseController(w) - - return rc.SetReadDeadline(deadline) -} - -func setWriteDeadline(w http.ResponseWriter, deadline time.Time) error { - rc := http.NewResponseController(w) - - return rc.SetWriteDeadline(deadline) -} diff --git a/integrationtests/self/http_test.go b/integrationtests/self/http_test.go index ac16ffa5131..a7a20ad2c45 100644 --- a/integrationtests/self/http_test.go +++ b/integrationtests/self/http_test.go @@ -432,55 +432,53 @@ var _ = Describe("HTTP tests", func() { Eventually(done).Should(BeClosed()) }) - if go120 { - It("supports read deadlines", func() { - mux.HandleFunc("/read-deadline", func(w http.ResponseWriter, r *http.Request) { - defer GinkgoRecover() - err := setReadDeadline(w, time.Now().Add(deadlineDelay)) - Expect(err).ToNot(HaveOccurred()) + It("supports read deadlines", func() { + mux.HandleFunc("/read-deadline", func(w http.ResponseWriter, r *http.Request) { + defer GinkgoRecover() + rc := http.NewResponseController(w) + Expect(rc.SetReadDeadline(time.Now().Add(deadlineDelay))).To(Succeed()) - body, err := io.ReadAll(r.Body) - Expect(err).To(MatchError(os.ErrDeadlineExceeded)) - Expect(body).To(ContainSubstring("aa")) + body, err := io.ReadAll(r.Body) + Expect(err).To(MatchError(os.ErrDeadlineExceeded)) + Expect(body).To(ContainSubstring("aa")) - w.Write([]byte("ok")) - }) + w.Write([]byte("ok")) + }) - expectedEnd := time.Now().Add(deadlineDelay) - resp, err := client.Post( - fmt.Sprintf("https://localhost:%d/read-deadline", port), - "text/plain", - neverEnding('a'), - ) - Expect(err).ToNot(HaveOccurred()) - Expect(resp.StatusCode).To(Equal(200)) + expectedEnd := time.Now().Add(deadlineDelay) + resp, err := client.Post( + fmt.Sprintf("https://localhost:%d/read-deadline", port), + "text/plain", + neverEnding('a'), + ) + Expect(err).ToNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(200)) - body, err := io.ReadAll(gbytes.TimeoutReader(resp.Body, 2*deadlineDelay)) - Expect(err).ToNot(HaveOccurred()) - Expect(time.Now().After(expectedEnd)).To(BeTrue()) - Expect(string(body)).To(Equal("ok")) - }) + body, err := io.ReadAll(gbytes.TimeoutReader(resp.Body, 2*deadlineDelay)) + Expect(err).ToNot(HaveOccurred()) + Expect(time.Now().After(expectedEnd)).To(BeTrue()) + Expect(string(body)).To(Equal("ok")) + }) - It("supports write deadlines", func() { - mux.HandleFunc("/write-deadline", func(w http.ResponseWriter, r *http.Request) { - defer GinkgoRecover() - err := setWriteDeadline(w, time.Now().Add(deadlineDelay)) - Expect(err).ToNot(HaveOccurred()) + It("supports write deadlines", func() { + mux.HandleFunc("/write-deadline", func(w http.ResponseWriter, r *http.Request) { + defer GinkgoRecover() + rc := http.NewResponseController(w) + Expect(rc.SetWriteDeadline(time.Now().Add(deadlineDelay))).To(Succeed()) - _, err = io.Copy(w, neverEnding('a')) - Expect(err).To(MatchError(os.ErrDeadlineExceeded)) - }) + _, err := io.Copy(w, neverEnding('a')) + Expect(err).To(MatchError(os.ErrDeadlineExceeded)) + }) - expectedEnd := time.Now().Add(deadlineDelay) + expectedEnd := time.Now().Add(deadlineDelay) - resp, err := client.Get(fmt.Sprintf("https://localhost:%d/write-deadline", port)) - Expect(err).ToNot(HaveOccurred()) - Expect(resp.StatusCode).To(Equal(200)) + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/write-deadline", port)) + Expect(err).ToNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(200)) - body, err := io.ReadAll(gbytes.TimeoutReader(resp.Body, 2*deadlineDelay)) - Expect(err).ToNot(HaveOccurred()) - Expect(time.Now().After(expectedEnd)).To(BeTrue()) - Expect(string(body)).To(ContainSubstring("aa")) - }) - } + body, err := io.ReadAll(gbytes.TimeoutReader(resp.Body, 2*deadlineDelay)) + Expect(err).ToNot(HaveOccurred()) + Expect(time.Now().After(expectedEnd)).To(BeTrue()) + Expect(string(body)).To(ContainSubstring("aa")) + }) }) From 574dc84c0cd1be9369cea607760db94b51028f0f Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 13 Dec 2023 09:47:09 +0530 Subject: [PATCH 121/225] limit the number of queued PATH_RESPONSE frames to 256 (#4199) --- framer.go | 37 +++++++++++++++++++++++++++++------ framer_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 7 deletions(-) diff --git a/framer.go b/framer.go index 9409af4c2ee..d5c61bcf73e 100644 --- a/framer.go +++ b/framer.go @@ -23,6 +23,8 @@ type framer interface { Handle0RTTRejection() error } +const maxPathResponses = 256 + type framerI struct { mutex sync.Mutex @@ -33,6 +35,7 @@ type framerI struct { controlFrameMutex sync.Mutex controlFrames []wire.Frame + pathResponses []*wire.PathResponseFrame } var _ framer = &framerI{} @@ -52,20 +55,43 @@ func (f *framerI) HasData() bool { return true } f.controlFrameMutex.Lock() - hasData = len(f.controlFrames) > 0 - f.controlFrameMutex.Unlock() - return hasData + defer f.controlFrameMutex.Unlock() + return len(f.controlFrames) > 0 || len(f.pathResponses) > 0 } func (f *framerI) QueueControlFrame(frame wire.Frame) { f.controlFrameMutex.Lock() + defer f.controlFrameMutex.Unlock() + + if pr, ok := frame.(*wire.PathResponseFrame); ok { + // Only queue up to maxPathResponses PATH_RESPONSE frames. + // This limit should be high enough to never be hit in practice, + // unless the peer is doing something malicious. + if len(f.pathResponses) >= maxPathResponses { + return + } + f.pathResponses = append(f.pathResponses, pr) + return + } f.controlFrames = append(f.controlFrames, frame) - f.controlFrameMutex.Unlock() } func (f *framerI) AppendControlFrames(frames []ackhandler.Frame, maxLen protocol.ByteCount, v protocol.VersionNumber) ([]ackhandler.Frame, protocol.ByteCount) { - var length protocol.ByteCount f.controlFrameMutex.Lock() + defer f.controlFrameMutex.Unlock() + + var length protocol.ByteCount + // add a PATH_RESPONSE first, but only pack a single PATH_RESPONSE per packet + if len(f.pathResponses) > 0 { + frame := f.pathResponses[0] + frameLen := frame.Length(v) + if frameLen <= maxLen { + frames = append(frames, ackhandler.Frame{Frame: frame}) + length += frameLen + f.pathResponses = f.pathResponses[1:] + } + } + for len(f.controlFrames) > 0 { frame := f.controlFrames[len(f.controlFrames)-1] frameLen := frame.Length(v) @@ -76,7 +102,6 @@ func (f *framerI) AppendControlFrames(frames []ackhandler.Frame, maxLen protocol length += frameLen f.controlFrames = f.controlFrames[:len(f.controlFrames)-1] } - f.controlFrameMutex.Unlock() return frames, length } diff --git a/framer_test.go b/framer_test.go index add9da713c5..97cbd144bed 100644 --- a/framer_test.go +++ b/framer_test.go @@ -2,7 +2,8 @@ package quic import ( "bytes" - "math/rand" + + "golang.org/x/exp/rand" "github.com/quic-go/quic-go/internal/ackhandler" "github.com/quic-go/quic-go/internal/protocol" @@ -110,6 +111,55 @@ var _ = Describe("Framer", func() { }) }) + Context("handling PATH_RESPONSE frames", func() { + It("packs a single PATH_RESPONSE per packet", func() { + f1 := &wire.PathResponseFrame{Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}} + f2 := &wire.PathResponseFrame{Data: [8]byte{2, 3, 4, 5, 6, 7, 8, 9}} + cf1 := &wire.DataBlockedFrame{MaximumData: 1337} + cf2 := &wire.HandshakeDoneFrame{} + framer.QueueControlFrame(f1) + framer.QueueControlFrame(f2) + framer.QueueControlFrame(cf1) + framer.QueueControlFrame(cf2) + // the first packet should contain a single PATH_RESPONSE frame, but all the other control frames + Expect(framer.HasData()).To(BeTrue()) + frames, length := framer.AppendControlFrames(nil, protocol.MaxByteCount, protocol.Version1) + Expect(frames).To(HaveLen(3)) + Expect(frames[0].Frame).To(Equal(f1)) + Expect([]wire.Frame{frames[1].Frame, frames[2].Frame}).To(ContainElement(cf1)) + Expect([]wire.Frame{frames[1].Frame, frames[2].Frame}).To(ContainElement(cf2)) + Expect(length).To(Equal(f1.Length(protocol.Version1) + cf1.Length(protocol.Version1) + cf2.Length(protocol.Version1))) + // the second packet should contain the other PATH_RESPONSE frame + Expect(framer.HasData()).To(BeTrue()) + frames, length = framer.AppendControlFrames(nil, protocol.MaxByteCount, protocol.Version1) + Expect(frames).To(HaveLen(1)) + Expect(frames[0].Frame).To(Equal(f2)) + Expect(length).To(Equal(f2.Length(protocol.Version1))) + Expect(framer.HasData()).To(BeFalse()) + }) + + It("limits the number of queued PATH_RESPONSE frames", func() { + var pathResponses []*wire.PathResponseFrame + for i := 0; i < 2*maxPathResponses; i++ { + var f wire.PathResponseFrame + rand.Read(f.Data[:]) + pathResponses = append(pathResponses, &f) + framer.QueueControlFrame(&f) + } + for i := 0; i < maxPathResponses; i++ { + Expect(framer.HasData()).To(BeTrue()) + frames, length := framer.AppendControlFrames(nil, protocol.MaxByteCount, protocol.Version1) + Expect(frames).To(HaveLen(1)) + Expect(frames[0].Frame).To(Equal(pathResponses[i])) + Expect(length).To(Equal(pathResponses[i].Length(protocol.Version1))) + } + Expect(framer.HasData()).To(BeFalse()) + frames, length := framer.AppendControlFrames(nil, protocol.MaxByteCount, protocol.Version1) + Expect(frames).To(BeEmpty()) + Expect(length).To(BeZero()) + }) + }) + Context("popping STREAM frames", func() { It("returns nil when popping an empty framer", func() { Expect(framer.AppendStreamFrames(nil, 1000, protocol.Version1)).To(BeEmpty()) From ff6d575ee3eb3fe121a4c68fc05991bc603953ba Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 13 Dec 2023 09:52:13 +0530 Subject: [PATCH 122/225] don't retransmit PATH_CHALLENGE and PATH_RESPONSE frames (#4200) --- packet_packer.go | 8 +++++++- packet_packer_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/packet_packer.go b/packet_packer.go index 64081c6842b..a330632bee6 100644 --- a/packet_packer.go +++ b/packet_packer.go @@ -640,7 +640,13 @@ func (p *packetPacker) composeNextPacket(maxFrameSize protocol.ByteCount, onlyAc pl.length += lengthAdded // add handlers for the control frames that were added for i := startLen; i < len(pl.frames); i++ { - pl.frames[i].Handler = p.retransmissionQueue.AppDataAckHandler() + switch pl.frames[i].Frame.(type) { + case *wire.PathChallengeFrame, *wire.PathResponseFrame: + // Path probing is currently not supported, therefore we don't need to set the OnAcked callback yet. + // PATH_CHALLENGE and PATH_RESPONSE are never retransmitted. + default: + pl.frames[i].Handler = p.retransmissionQueue.AppDataAckHandler() + } } pl.streamFrames, lengthAdded = p.framer.AppendStreamFrames(pl.streamFrames, maxFrameSize-pl.length, v) diff --git a/packet_packer_test.go b/packet_packer_test.go index e68906f39f1..fe746e631c9 100644 --- a/packet_packer_test.go +++ b/packet_packer_test.go @@ -562,6 +562,37 @@ var _ = Describe("Packet packer", func() { Expect(buffer.Len()).ToNot(BeZero()) }) + It("packs PATH_CHALLENGE and PATH_RESPONSE frames", func() { + pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2) + pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42)) + sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil) + framer.EXPECT().HasData().Return(true) + ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT, false) + frames := []ackhandler.Frame{ + {Frame: &wire.PathChallengeFrame{}}, + {Frame: &wire.PathResponseFrame{}}, + {Frame: &wire.DataBlockedFrame{}}, + } + expectAppendControlFrames(frames...) + expectAppendStreamFrames() + buffer := getPacketBuffer() + p, err := packer.AppendPacket(buffer, maxPacketSize, protocol.Version1) + Expect(p).ToNot(BeNil()) + Expect(err).ToNot(HaveOccurred()) + Expect(p.Frames).To(HaveLen(3)) + for i, f := range p.Frames { + Expect(f).To(BeAssignableToTypeOf(frames[i])) + switch f.Frame.(type) { + case *wire.PathChallengeFrame, *wire.PathResponseFrame: + // This means that the frame won't be retransmitted. + Expect(f.Handler).To(BeNil()) + default: + Expect(f.Handler).ToNot(BeNil()) + } + } + Expect(buffer.Len()).ToNot(BeZero()) + }) + It("packs DATAGRAM frames", func() { ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT, true) pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2) From 048940927c73cfb6d82b8275084830a009d0bceb Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 13 Dec 2023 17:32:06 +0530 Subject: [PATCH 123/225] ci: update golangci-lint to v1.55.2 (#4204) --- .github/workflows/lint.yml | 10 +++++----- .golangci.yml | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index fd735c9b7ee..5b6478e59a5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -51,7 +51,7 @@ jobs: with: skip-pkg-cache: true args: --timeout=3m - version: v1.52.2 + version: v1.55.2 - name: golangci-lint (Windows) if: success() || failure() # run this step even if the previous one failed uses: golangci/golangci-lint-action@v3 @@ -60,7 +60,7 @@ jobs: with: skip-pkg-cache: true args: --timeout=3m - version: v1.52.2 + version: v1.55.2 - name: golangci-lint (OSX) if: success() || failure() # run this step even if the previous one failed uses: golangci/golangci-lint-action@v3 @@ -69,7 +69,7 @@ jobs: with: skip-pkg-cache: true args: --timeout=3m - version: v1.52.2 + version: v1.55.2 - name: golangci-lint (FreeBSD) if: success() || failure() # run this step even if the previous one failed uses: golangci/golangci-lint-action@v3 @@ -78,7 +78,7 @@ jobs: with: skip-pkg-cache: true args: --timeout=3m - version: v1.52.2 + version: v1.55.2 - name: golangci-lint (others) if: success() || failure() # run this step even if the previous one failed uses: golangci/golangci-lint-action@v3 @@ -87,4 +87,4 @@ jobs: with: skip-pkg-cache: true args: --timeout=3m - version: v1.52.2 + version: v1.55.2 diff --git a/.golangci.yml b/.golangci.yml index 1315759bc1f..f5e9b48bc01 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,15 +3,15 @@ run: - internal/handshake/cipher_suite.go linters-settings: depguard: - type: blacklist - packages: - - github.com/marten-seemann/qtls - - github.com/quic-go/qtls-go1-19 - - github.com/quic-go/qtls-go1-20 - packages-with-error-message: - - github.com/marten-seemann/qtls: "importing qtls only allowed in internal/qtls" - - github.com/quic-go/qtls-go1-19: "importing qtls only allowed in internal/qtls" - - github.com/quic-go/qtls-go1-20: "importing qtls only allowed in internal/qtls" + rules: + qtls: + list-mode: lax + files: + - "!internal/qtls/**" + - "$all" + deny: + - pkg: github.com/quic-go/qtls-go1-20 + desc: "importing qtls only allowed in internal/qtls" misspell: ignore-words: - ect From 6ffb9054a25953cd2d7bcee8a0a1e62bd7cb4585 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 14 Dec 2023 12:39:02 +0530 Subject: [PATCH 124/225] fuzzing: add frame validation logic (#4206) --- fuzzing/frames/fuzz.go | 56 ++++++++++++++++++++++++++++++++++++-- internal/wire/ack_frame.go | 4 +-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/fuzzing/frames/fuzz.go b/fuzzing/frames/fuzz.go index 44d2eee31b7..7229f488e8a 100644 --- a/fuzzing/frames/fuzz.go +++ b/fuzzing/frames/fuzz.go @@ -56,22 +56,23 @@ func Fuzz(data []byte) int { continue } } + validateFrame(f) startLen := len(b) parsedLen := initialLen - len(data) b, err = f.Append(b, version) if err != nil { - panic(fmt.Sprintf("Error writing frame %#v: %s", f, err)) + panic(fmt.Sprintf("error writing frame %#v: %s", f, err)) } frameLen := protocol.ByteCount(len(b) - startLen) if f.Length(version) != frameLen { - panic(fmt.Sprintf("Inconsistent frame length for %#v: expected %d, got %d", f, frameLen, f.Length(version))) + panic(fmt.Sprintf("inconsistent frame length for %#v: expected %d, got %d", f, frameLen, f.Length(version))) } if sf, ok := f.(*wire.StreamFrame); ok { sf.PutBack() } if frameLen > protocol.ByteCount(parsedLen) { - panic(fmt.Sprintf("Serialized length (%d) is longer than parsed length (%d)", len(b), parsedLen)) + panic(fmt.Sprintf("serialized length (%d) is longer than parsed length (%d)", len(b), parsedLen)) } } @@ -80,3 +81,52 @@ func Fuzz(data []byte) int { } return 1 } + +func validateFrame(frame wire.Frame) { + switch f := frame.(type) { + case *wire.StreamFrame: + if protocol.ByteCount(len(f.Data)) != f.DataLen() { + panic("STREAM frame: inconsistent data length") + } + case *wire.AckFrame: + if f.DelayTime < 0 { + panic(fmt.Sprintf("invalid ACK delay_time: %s", f.DelayTime)) + } + if f.LargestAcked() < f.LowestAcked() { + panic("ACK: largest acknowledged is smaller than lowest acknowledged") + } + for _, r := range f.AckRanges { + if r.Largest < 0 || r.Smallest < 0 { + panic("ACK range contains a negative packet number") + } + } + if !f.AcksPacket(f.LargestAcked()) { + panic("ACK frame claims that largest acknowledged is not acknowledged") + } + if !f.AcksPacket(f.LowestAcked()) { + panic("ACK frame claims that lowest acknowledged is not acknowledged") + } + _ = f.AcksPacket(100) + _ = f.AcksPacket((f.LargestAcked() + f.LowestAcked()) / 2) + case *wire.NewConnectionIDFrame: + if f.ConnectionID.Len() < 1 || f.ConnectionID.Len() > 20 { + panic(fmt.Sprintf("invalid NEW_CONNECTION_ID frame length: %s", f.ConnectionID)) + } + case *wire.NewTokenFrame: + if len(f.Token) == 0 { + panic("NEW_TOKEN frame with an empty token") + } + case *wire.MaxStreamsFrame: + if f.MaxStreamNum > protocol.MaxStreamCount { + panic("MAX_STREAMS frame with an invalid Maximum Streams value") + } + case *wire.StreamsBlockedFrame: + if f.StreamLimit > protocol.MaxStreamCount { + panic("STREAMS_BLOCKED frame with an invalid Maximum Streams value") + } + case *wire.ConnectionCloseFrame: + if f.IsApplicationError && f.FrameType != 0 { + panic("CONNECTION_CLOSE for an application error containing a frame type") + } + } +} diff --git a/internal/wire/ack_frame.go b/internal/wire/ack_frame.go index 9b23cc25f9c..9ce98aee50f 100644 --- a/internal/wire/ack_frame.go +++ b/internal/wire/ack_frame.go @@ -37,7 +37,7 @@ func parseAckFrame(frame *AckFrame, r *bytes.Reader, typ uint64, ackDelayExponen delayTime := time.Duration(delay*1< Date: Sat, 16 Dec 2023 04:29:41 +0100 Subject: [PATCH 125/225] http3: add remote address to request context (#4208) * http3: add remote address to request context Add the remote address of the underlying packet connection to the HTTP request context. This is useful for applications that need access to the actual remote address (wrapped in a net.Addr) rather than just its string representation. Fixes #4198 * add an integration test to the self test suite. I was not sure how deep we want to go to assure the right value is set. For now, it asserts that a net.Addr is present in the context. Due to the dynamic nature of the requests, it is a bit harder to know exactly how the remote address will look like. IPv4 vs IPv6, random high port. I think it is fine to only assert that the value is present. --- http3/server.go | 11 +++++++++++ integrationtests/self/http_test.go | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/http3/server.go b/http3/server.go index ac2e32a6e1c..5c70271d47b 100644 --- a/http3/server.go +++ b/http3/server.go @@ -115,6 +115,16 @@ func (k *contextKey) String() string { return "quic-go/http3 context value " + k // type *http3.Server. var ServerContextKey = &contextKey{"http3-server"} +// RemoteAddrContextKey is a context key. It can be used in +// HTTP handlers with Context.Value to access the remote +// address of the connection. The associated value will be of +// type net.Addr. +// +// Use this value instead of [http.Request.RemoteAddr] if you +// require access to the remote address of the connection rather +// than its string representation. +var RemoteAddrContextKey = &contextKey{"remote-addr"} + type requestError struct { err error streamErr ErrCode @@ -597,6 +607,7 @@ func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *q ctx := str.Context() ctx = context.WithValue(ctx, ServerContextKey, s) ctx = context.WithValue(ctx, http.LocalAddrContextKey, conn.LocalAddr()) + ctx = context.WithValue(ctx, RemoteAddrContextKey, conn.RemoteAddr()) req = req.WithContext(ctx) r := newResponseWriter(str, conn, s.logger) if req.Method == http.MethodHead { diff --git a/integrationtests/self/http_test.go b/integrationtests/self/http_test.go index a7a20ad2c45..b746816df0d 100644 --- a/integrationtests/self/http_test.go +++ b/integrationtests/self/http_test.go @@ -481,4 +481,16 @@ var _ = Describe("HTTP tests", func() { Expect(time.Now().After(expectedEnd)).To(BeTrue()) Expect(string(body)).To(ContainSubstring("aa")) }) + + It("sets remote address", func() { + mux.HandleFunc("/remote-addr", func(w http.ResponseWriter, r *http.Request) { + defer GinkgoRecover() + _, ok := r.Context().Value(http3.RemoteAddrContextKey).(net.Addr) + Expect(ok).To(BeTrue()) + }) + + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/remote-addr", port)) + Expect(err).ToNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(200)) + }) }) From e0bf13be01aaa715329d32da90d526671b5245ce Mon Sep 17 00:00:00 2001 From: WeidiDeng Date: Sat, 16 Dec 2023 11:39:49 +0800 Subject: [PATCH 126/225] http3: reset stream when a handler panics (#4181) * interrupt the stream when a panick happened * move the declaration of errPanicked * check what's read is a prefix of what's written * check errPanicked * use MatchError instead of Equal * use channel to notify the response has been received --- http3/server.go | 6 ++++++ http3/server_test.go | 4 ++-- integrationtests/self/http_test.go | 20 ++++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/http3/server.go b/http3/server.go index 5c70271d47b..a66a2711c88 100644 --- a/http3/server.go +++ b/http3/server.go @@ -30,6 +30,7 @@ var ( quicListenAddr = func(addr string, tlsConf *tls.Config, config *quic.Config) (QUICEarlyListener, error) { return quic.ListenAddrEarly(addr, tlsConf, config) } + errPanicked = errors.New("panicked") ) // NextProtoH3 is the ALPN protocol negotiated during the TLS handshake, for QUIC v1 and v2. @@ -652,6 +653,11 @@ func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *q } // If the EOF was read by the handler, CancelRead() is a no-op. str.CancelRead(quic.StreamErrorCode(ErrCodeNoError)) + + // abort the stream when there is a panic + if panicked { + return newStreamError(ErrCodeInternalError, errPanicked) + } return requestError{} } diff --git a/http3/server_test.go b/http3/server_test.go index 5ec58668f81..8da80611131 100644 --- a/http3/server_test.go +++ b/http3/server_test.go @@ -272,7 +272,7 @@ var _ = Describe("Server", func() { str.EXPECT().CancelRead(gomock.Any()) serr := s.handleRequest(conn, str, qpackDecoder, nil) - Expect(serr.err).ToNot(HaveOccurred()) + Expect(serr.err).To(MatchError(errPanicked)) Expect(responseBuf.Bytes()).To(HaveLen(0)) }) @@ -288,7 +288,7 @@ var _ = Describe("Server", func() { str.EXPECT().CancelRead(gomock.Any()) serr := s.handleRequest(conn, str, qpackDecoder, nil) - Expect(serr.err).ToNot(HaveOccurred()) + Expect(serr.err).To(MatchError(errPanicked)) Expect(responseBuf.Bytes()).To(HaveLen(0)) }) diff --git a/integrationtests/self/http_test.go b/integrationtests/self/http_test.go index b746816df0d..5ec17e2d942 100644 --- a/integrationtests/self/http_test.go +++ b/integrationtests/self/http_test.go @@ -140,6 +140,26 @@ var _ = Describe("HTTP tests", func() { Expect(resp.Header.Get("Content-Length")).To(Equal(strconv.Itoa(len("foobar")))) }) + It("detects stream errors when server panics when writing response", func() { + respChan := make(chan struct{}) + mux.HandleFunc("/writing_and_panicking", func(w http.ResponseWriter, r *http.Request) { + // no recover here as it will interfere with the handler + w.Write([]byte("foobar")) + w.(http.Flusher).Flush() + // wait for the client to receive the response + <-respChan + panic(http.ErrAbortHandler) + }) + + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/writing_and_panicking", port)) + close(respChan) + Expect(err).ToNot(HaveOccurred()) + body, err := io.ReadAll(resp.Body) + Expect(err).To(HaveOccurred()) + // the body will be a prefix of what's written + Expect(bytes.HasPrefix([]byte("foobar"), body)).To(BeTrue()) + }) + It("requests to different servers with the same udpconn", func() { resp, err := client.Get(fmt.Sprintf("https://localhost:%d/remoteAddr", port)) Expect(err).ToNot(HaveOccurred()) From 5d6bf7e206255a09e47f0c3f6623b84646d7a87a Mon Sep 17 00:00:00 2001 From: Constantine Shablia Date: Tue, 19 Dec 2023 05:27:07 +0200 Subject: [PATCH 127/225] http3: don't use error string as a format string in debug log message (#4211) Fixes: #4209 --- http3/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http3/server.go b/http3/server.go index a66a2711c88..d8848e69eca 100644 --- a/http3/server.go +++ b/http3/server.go @@ -284,7 +284,7 @@ func (s *Server) ServeListener(ln QUICEarlyListener) error { } go func() { if err := s.handleConn(conn); err != nil { - s.logger.Debugf(err.Error()) + s.logger.Debugf("handling connection failed: %s", err) } }() } From d3c5f389d44797108a1bee7e06d5b92434c26d6d Mon Sep 17 00:00:00 2001 From: Constantine Shablia Date: Tue, 19 Dec 2023 07:03:28 +0200 Subject: [PATCH 128/225] http3: improve debug message when determining the listener port fails (#4214) Fixes: #4212 --- http3/server.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/http3/server.go b/http3/server.go index d8848e69eca..2711394a7f8 100644 --- a/http3/server.go +++ b/http3/server.go @@ -418,10 +418,11 @@ func (s *Server) addListener(l *QUICEarlyListener) error { s.listeners = make(map[*QUICEarlyListener]listenerInfo) } - if port, err := extractPort((*l).Addr().String()); err == nil { + laddr := (*l).Addr() + if port, err := extractPort(laddr.String()); err == nil { s.listeners[l] = listenerInfo{port} } else { - s.logger.Errorf("Unable to extract port from listener %+v, will not be announced using SetQuicHeaders: %s", err) + s.logger.Errorf("Unable to extract port from listener %s, will not be announced using SetQuicHeaders: %s", laddr, err) s.listeners[l] = listenerInfo{} } s.generateAltSvcHeader() From 2243fdefbf9c156d0d4bde996473082433129bce Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 21 Dec 2023 11:16:30 +0700 Subject: [PATCH 129/225] http3: return the context cancellation error from RoundTrip (#4203) --- http3/client.go | 9 +++++++++ http3/client_test.go | 2 +- integrationtests/self/http_test.go | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/http3/client.go b/http3/client.go index 8aca4807868..9608f882404 100644 --- a/http3/client.go +++ b/http3/client.go @@ -254,6 +254,15 @@ func (c *client) maxHeaderBytes() uint64 { // RoundTripOpt executes a request and returns a response func (c *client) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { + rsp, err := c.roundTripOpt(req, opt) + if err != nil && req.Context().Err() != nil { + // if the context was canceled, return the context cancellation error + err = req.Context().Err() + } + return rsp, err +} + +func (c *client) roundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { if authorityAddr("https", hostnameFromRequest(req)) != c.hostname { return nil, fmt.Errorf("http3 client BUG: RoundTripOpt called for the wrong client (expected %s, got %s)", c.hostname, req.Host) } diff --git a/http3/client_test.go b/http3/client_test.go index 014c29a5b4f..00d01bcaac2 100644 --- a/http3/client_test.go +++ b/http3/client_test.go @@ -922,7 +922,7 @@ var _ = Describe("Client", func() { return 0, errors.New("test done") }) _, err := cl.RoundTripOpt(req, roundTripOpt) - Expect(err).To(MatchError("test done")) + Expect(err).To(MatchError(context.Canceled)) Eventually(done).Should(BeClosed()) }) }) diff --git a/integrationtests/self/http_test.go b/integrationtests/self/http_test.go index 5ec17e2d942..96e72dc7c26 100644 --- a/integrationtests/self/http_test.go +++ b/integrationtests/self/http_test.go @@ -319,6 +319,21 @@ var _ = Describe("HTTP tests", func() { Expect(string(body)).To(Equal("Hello, World!\n")) }) + It("handles context cancellations", func() { + mux.HandleFunc("/cancel", func(w http.ResponseWriter, r *http.Request) { + <-r.Context().Done() + }) + + ctx, cancel := context.WithCancel(context.Background()) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://localhost:%d/cancel", port), nil) + Expect(err).ToNot(HaveOccurred()) + time.AfterFunc(50*time.Millisecond, cancel) + + _, err = client.Do(req) + Expect(err).To(HaveOccurred()) + Expect(err).To(MatchError(context.Canceled)) + }) + It("cancels requests", func() { handlerCalled := make(chan struct{}) mux.HandleFunc("/cancel", func(w http.ResponseWriter, r *http.Request) { From 31a677cacd97b4e277f854f069fa9f2947ca7208 Mon Sep 17 00:00:00 2001 From: Benedikt Spies Date: Tue, 26 Dec 2023 06:02:47 +0100 Subject: [PATCH 130/225] qlog: add support for alpn_information event (#4216) * qlog chosen alpn * qlog chosen alpn * qlog: fix capitalization of ALPN --------- Co-authored-by: Marten Seemann --- connection.go | 4 +++ connection_test.go | 10 ++++++ internal/mocks/logging/connection_tracer.go | 3 ++ .../logging/internal/connection_tracer.go | 36 +++++++++++++++++++ internal/mocks/logging/mockgen.go | 1 + logging/connection_tracer.go | 8 +++++ qlog/event.go | 12 +++++++ qlog/qlog.go | 5 +++ 8 files changed, 79 insertions(+) diff --git a/connection.go b/connection.go index 75ede6cba9a..b28eb8c1b56 100644 --- a/connection.go +++ b/connection.go @@ -731,6 +731,10 @@ func (s *connection) handleHandshakeComplete() error { s.connIDManager.SetHandshakeComplete() s.connIDGenerator.SetHandshakeComplete() + if s.tracer != nil && s.tracer.ChoseALPN != nil { + s.tracer.ChoseALPN(s.cryptoStreamHandler.ConnectionState().NegotiatedProtocol) + } + // The server applies transport parameters right away, but the client side has to wait for handshake completion. // During a 0-RTT connection, the client is only allowed to use the new transport parameters for 1-RTT packets. if s.perspective == protocol.PerspectiveClient { diff --git a/connection_test.go b/connection_test.go index b5f786569ba..973f1b6f845 100644 --- a/connection_test.go +++ b/connection_test.go @@ -1946,6 +1946,7 @@ var _ = Describe("Connection", func() { sph := mockackhandler.NewMockSentPacketHandler(mockCtrl) conn.sentPacketHandler = sph tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionHandshake) + tracer.EXPECT().ChoseALPN(gomock.Any()) sph.EXPECT().GetLossDetectionTimeout().AnyTimes() sph.EXPECT().TimeUntilSend().AnyTimes() sph.EXPECT().SendMode(gomock.Any()).AnyTimes() @@ -1954,6 +1955,7 @@ var _ = Describe("Connection", func() { connRunner.EXPECT().Retire(clientDestConnID) cryptoSetup.EXPECT().SetHandshakeConfirmed() cryptoSetup.EXPECT().GetSessionTicket() + cryptoSetup.EXPECT().ConnectionState() handshakeCtx := conn.HandshakeComplete() Consistently(handshakeCtx).ShouldNot(BeClosed()) Expect(conn.handleHandshakeComplete()).To(Succeed()) @@ -1966,8 +1968,10 @@ var _ = Describe("Connection", func() { connRunner.EXPECT().Retire(clientDestConnID) conn.sentPacketHandler.DropPackets(protocol.EncryptionInitial) tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionHandshake) + tracer.EXPECT().ChoseALPN(gomock.Any()) cryptoSetup.EXPECT().SetHandshakeConfirmed() cryptoSetup.EXPECT().GetSessionTicket().Return(make([]byte, size), nil) + cryptoSetup.EXPECT().ConnectionState() handshakeCtx := conn.HandshakeComplete() Consistently(handshakeCtx).ShouldNot(BeClosed()) @@ -2021,6 +2025,7 @@ var _ = Describe("Connection", func() { 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()) + tracer.EXPECT().ChoseALPN(gomock.Any()) conn.sentPacketHandler = sph done := make(chan struct{}) connRunner.EXPECT().Retire(clientDestConnID) @@ -2041,6 +2046,7 @@ var _ = Describe("Connection", func() { cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}) cryptoSetup.EXPECT().SetHandshakeConfirmed() cryptoSetup.EXPECT().GetSessionTicket() + cryptoSetup.EXPECT().ConnectionState() mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any()) Expect(conn.handleHandshakeComplete()).To(Succeed()) conn.run() @@ -2351,6 +2357,7 @@ var _ = Describe("Connection", func() { ) cryptoSetup.EXPECT().Close() gomock.InOrder( + tracer.EXPECT().ChoseALPN(gomock.Any()), tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionHandshake), tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) { Expect(e).To(MatchError(&IdleTimeoutError{})) @@ -2366,6 +2373,7 @@ var _ = Describe("Connection", func() { cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}) cryptoSetup.EXPECT().GetSessionTicket().MaxTimes(1) cryptoSetup.EXPECT().SetHandshakeConfirmed().MaxTimes(1) + cryptoSetup.EXPECT().ConnectionState() Expect(conn.handleHandshakeComplete()).To(Succeed()) err := conn.run() nerr, ok := err.(net.Error) @@ -2896,6 +2904,8 @@ var _ = Describe("Client Connection", func() { defer GinkgoRecover() Expect(conn.handleHandshakeComplete()).To(Succeed()) }) + tracer.EXPECT().ChoseALPN(gomock.Any()).MaxTimes(1) + cryptoSetup.EXPECT().ConnectionState().MaxTimes(1) errChan <- conn.run() close(errChan) }() diff --git a/internal/mocks/logging/connection_tracer.go b/internal/mocks/logging/connection_tracer.go index 4c15dcd0870..8e8be8a5ba5 100644 --- a/internal/mocks/logging/connection_tracer.go +++ b/internal/mocks/logging/connection_tracer.go @@ -98,6 +98,9 @@ func NewMockConnectionTracer(ctrl *gomock.Controller) (*logging.ConnectionTracer ECNStateUpdated: func(state logging.ECNState, trigger logging.ECNStateTrigger) { t.ECNStateUpdated(state, trigger) }, + ChoseALPN: func(protocol string) { + t.ChoseALPN(protocol) + }, Close: func() { t.Close() }, diff --git a/internal/mocks/logging/internal/connection_tracer.go b/internal/mocks/logging/internal/connection_tracer.go index ab2a21820a7..1c2c26aed86 100644 --- a/internal/mocks/logging/internal/connection_tracer.go +++ b/internal/mocks/logging/internal/connection_tracer.go @@ -115,6 +115,42 @@ func (c *ConnectionTracerBufferedPacketCall) DoAndReturn(f func(logging.PacketTy return c } +// ChoseALPN mocks base method. +func (m *MockConnectionTracer) ChoseALPN(arg0 string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ChoseALPN", arg0) +} + +// ChoseALPN indicates an expected call of ChoseALPN. +func (mr *MockConnectionTracerMockRecorder) ChoseALPN(arg0 any) *ConnectionTracerChoseALPNCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChoseALPN", reflect.TypeOf((*MockConnectionTracer)(nil).ChoseALPN), arg0) + return &ConnectionTracerChoseALPNCall{Call: call} +} + +// ConnectionTracerChoseALPNCall wrap *gomock.Call +type ConnectionTracerChoseALPNCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ConnectionTracerChoseALPNCall) Return() *ConnectionTracerChoseALPNCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ConnectionTracerChoseALPNCall) Do(f func(string)) *ConnectionTracerChoseALPNCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ConnectionTracerChoseALPNCall) DoAndReturn(f func(string)) *ConnectionTracerChoseALPNCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + // Close mocks base method. func (m *MockConnectionTracer) Close() { m.ctrl.T.Helper() diff --git a/internal/mocks/logging/mockgen.go b/internal/mocks/logging/mockgen.go index 65aa5f3d966..a86be9b1a1d 100644 --- a/internal/mocks/logging/mockgen.go +++ b/internal/mocks/logging/mockgen.go @@ -45,6 +45,7 @@ type ConnectionTracer interface { LossTimerExpired(logging.TimerType, logging.EncryptionLevel) LossTimerCanceled() ECNStateUpdated(state logging.ECNState, trigger logging.ECNStateTrigger) + ChoseALPN(protocol string) // Close is called when the connection is closed. Close() Debug(name, msg string) diff --git a/logging/connection_tracer.go b/logging/connection_tracer.go index 218b0c6b826..0f2cbe0400a 100644 --- a/logging/connection_tracer.go +++ b/logging/connection_tracer.go @@ -34,6 +34,7 @@ type ConnectionTracer struct { LossTimerExpired func(TimerType, EncryptionLevel) LossTimerCanceled func() ECNStateUpdated func(state ECNState, trigger ECNStateTrigger) + ChoseALPN func(protocol string) // Close is called when the connection is closed. Close func() Debug func(name, msg string) @@ -237,6 +238,13 @@ func NewMultiplexedConnectionTracer(tracers ...*ConnectionTracer) *ConnectionTra } } }, + ChoseALPN: func(protocol string) { + for _, t := range tracers { + if t.ChoseALPN != nil { + t.ChoseALPN(protocol) + } + } + }, Close: func() { for _, t := range tracers { if t.Close != nil { diff --git a/qlog/event.go b/qlog/event.go index 0082c04b85d..f345d13923d 100644 --- a/qlog/event.go +++ b/qlog/event.go @@ -554,3 +554,15 @@ func (e eventGeneric) IsNil() bool { return false } func (e eventGeneric) MarshalJSONObject(enc *gojay.Encoder) { enc.StringKey("details", e.msg) } + +type eventALPNInformation struct { + chosenALPN string +} + +func (e eventALPNInformation) Category() category { return categoryTransport } +func (e eventALPNInformation) Name() string { return "alpn_information" } +func (e eventALPNInformation) IsNil() bool { return false } + +func (e eventALPNInformation) MarshalJSONObject(enc *gojay.Encoder) { + enc.StringKey("chosen_alpn", e.chosenALPN) +} diff --git a/qlog/qlog.go b/qlog/qlog.go index 90234b7dc59..0df77ce5e1b 100644 --- a/qlog/qlog.go +++ b/qlog/qlog.go @@ -145,6 +145,11 @@ func NewConnectionTracer(w io.WriteCloser, p protocol.Perspective, odcid protoco ECNStateUpdated: func(state logging.ECNState, trigger logging.ECNStateTrigger) { t.ECNStateUpdated(state, trigger) }, + ChoseALPN: func(protocol string) { + t.mutex.Lock() + t.recordEvent(time.Now(), eventALPNInformation{chosenALPN: protocol}) + t.mutex.Unlock() + }, Debug: func(name, msg string) { t.Debug(name, msg) }, From d795250479b831c1a770703bd8d0d8a748d70d5e Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 28 Dec 2023 11:31:58 +0700 Subject: [PATCH 131/225] drop support for Go 1.20, build on Go 1.22rc1 on CI (#4195) * drop support for Go 1.20 * ci: udpate CircleCI to Go 1.21 * qtls: remove unnecessary type aliases * ci: build using Go 1.22rc1 --- .circleci/config.yml | 10 +- .github/workflows/cross-compile.yml | 4 +- .github/workflows/integration.yml | 4 +- .github/workflows/lint.yml | 7 +- .github/workflows/unit.yml | 4 +- README.md | 5 - go.mod | 3 +- go.sum | 4 +- integrationtests/gomodvendor/go.mod | 17 +- integrationtests/gomodvendor/go.sum | 313 ------ integrationtests/self/zero_rtt_oldgo_test.go | 985 ------------------ integrationtests/self/zero_rtt_test.go | 2 - internal/handshake/crypto_setup.go | 52 +- internal/handshake/crypto_setup_test.go | 8 +- internal/qerr/error_codes.go | 5 +- ...{cipher_suite_go121.go => cipher_suite.go} | 2 - internal/qtls/cipher_suite_test.go | 2 - internal/qtls/client_session_cache_test.go | 2 - internal/qtls/go120.go | 157 --- internal/qtls/go120_test.go | 28 - internal/qtls/go_oldversion.go | 5 - internal/qtls/{go121.go => qtls.go} | 34 +- internal/qtls/{go121_test.go => qtls_test.go} | 8 +- 23 files changed, 70 insertions(+), 1591 deletions(-) delete mode 100644 integrationtests/self/zero_rtt_oldgo_test.go rename internal/qtls/{cipher_suite_go121.go => cipher_suite.go} (99%) delete mode 100644 internal/qtls/go120.go delete mode 100644 internal/qtls/go120_test.go delete mode 100644 internal/qtls/go_oldversion.go rename internal/qtls/{go121.go => qtls.go} (74%) rename internal/qtls/{go121_test.go => qtls_test.go} (92%) diff --git a/.circleci/config.yml b/.circleci/config.yml index e39fa12f527..95c258cfb03 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,15 +1,15 @@ version: 2.1 executors: - test-go120: + test-go121: docker: - - image: "cimg/go:1.20" + - image: "cimg/go:1.21" environment: runrace: true TIMESCALE_FACTOR: 3 jobs: "test": &test - executor: test-go120 + executor: test-go121 steps: - checkout - run: @@ -33,10 +33,10 @@ jobs: - run: name: "Run version negotiation tests with qlog" command: go run github.com/onsi/ginkgo/v2/ginkgo -v -randomize-all -trace integrationtests/versionnegotiation -- -qlog - go120: + go121: <<: *test workflows: workflow: jobs: - - go120 + - go121 diff --git a/.github/workflows/cross-compile.yml b/.github/workflows/cross-compile.yml index 1e8d16b9a2c..e4f28528901 100644 --- a/.github/workflows/cross-compile.yml +++ b/.github/workflows/cross-compile.yml @@ -4,12 +4,12 @@ jobs: strategy: fail-fast: false matrix: - go: [ "1.20.x", "1.21.x" ] + go: [ "1.21.x", "1.22.0-rc.1" ] runs-on: ${{ fromJSON(vars['CROSS_COMPILE_RUNNER_UBUNTU'] || '"ubuntu-latest"') }} name: "Cross Compilation (Go ${{matrix.go}})" steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: ${{ matrix.go }} - name: Install build utils diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 6f9b27fea54..1fd48f1b181 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -6,7 +6,7 @@ jobs: fail-fast: false matrix: os: [ "ubuntu" ] - go: [ "1.20.x", "1.21.x" ] + go: [ "1.21.x", "1.22.0-rc.1" ] include: - os: "windows" go: "1.21.x" @@ -22,7 +22,7 @@ jobs: name: Integration Tests (${{ matrix.os }}, Go ${{ matrix.go }}) steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: ${{ matrix.go }} - run: go version diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5b6478e59a5..8e5f744b1a4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -5,9 +5,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - skip-pkg-cache: true go-version: "1.21.x" - name: Check that no non-test files import Ginkgo or Gomega run: .github/workflows/no_ginkgo.sh @@ -39,11 +38,11 @@ jobs: strategy: fail-fast: false matrix: - go: [ "1.20.x", "1.21.x" ] + go: [ "1.21.x", "1.22.0-rc.1" ] name: golangci-lint (Go ${{ matrix.go }}) steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: ${{ matrix.go }} - name: golangci-lint (Linux) diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index 6dd625d2e6f..a790e81c9ba 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -7,12 +7,12 @@ jobs: fail-fast: false matrix: os: [ "ubuntu", "windows", "macos" ] - go: [ "1.20.x", "1.21.x" ] + go: [ "1.21.x", "1.22.0-rc.1" ] runs-on: ${{ fromJSON(vars[format('UNIT_RUNNER_{0}', matrix.os)] || format('"{0}-latest"', matrix.os)) }} name: Unit tests (${{ matrix.os}}, Go ${{ matrix.go }}) steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: ${{ matrix.go }} - run: go version diff --git a/README.md b/README.md index cc4f609f1d9..a43375e983a 100644 --- a/README.md +++ b/README.md @@ -248,11 +248,6 @@ If you'd like to see your project added to this list, please send us a PR. quic-go always aims to support the latest two Go releases. -### Dependency on forked crypto/tls - -Since the standard library didn't provide any QUIC APIs before the Go 1.21 release, we had to fork crypto/tls to add the required APIs ourselves: [qtls for Go 1.20](https://github.com/quic-go/qtls-go1-20). -This had led to a lot of pain in the Go ecosystem, and we're happy that we can rely on Go 1.21 going forward. - ## Contributing We are always happy to welcome new contributors! We have a number of self-contained issues that are suitable for first-time contributors, they are tagged with [help wanted](https://github.com/quic-go/quic-go/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). If you have any questions, please feel free to reach out by opening an issue or leaving a comment. diff --git a/go.mod b/go.mod index c2a45a2c02a..76087a2fc2b 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,12 @@ module github.com/quic-go/quic-go -go 1.20 +go 1.21 require ( github.com/francoispqt/gojay v1.2.13 github.com/onsi/ginkgo/v2 v2.9.5 github.com/onsi/gomega v1.27.6 github.com/quic-go/qpack v0.4.0 - github.com/quic-go/qtls-go1-20 v0.4.1 go.uber.org/mock v0.3.0 golang.org/x/crypto v0.4.0 golang.org/x/exp v0.0.0-20221205204356-47842c84f3db diff --git a/go.sum b/go.sum index 01249e3cecb..47e4bbee1e0 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,7 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 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= @@ -88,8 +89,6 @@ 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.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= -github.com/quic-go/qtls-go1-20 v0.4.1/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= @@ -199,6 +198,7 @@ google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9M 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.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 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/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/integrationtests/gomodvendor/go.mod b/integrationtests/gomodvendor/go.mod index c37e26d6a4b..a9ac6c32a87 100644 --- a/integrationtests/gomodvendor/go.mod +++ b/integrationtests/gomodvendor/go.mod @@ -1,8 +1,23 @@ module test -go 1.16 +go 1.21 // The version doesn't matter here, as we're replacing it with the currently checked out code anyway. require github.com/quic-go/quic-go v0.21.0 +require ( + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect + github.com/onsi/ginkgo/v2 v2.9.5 // indirect + github.com/quic-go/qpack v0.4.0 // indirect + go.uber.org/mock v0.3.0 // indirect + golang.org/x/crypto v0.4.0 // indirect + golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect + golang.org/x/mod v0.11.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/tools v0.9.1 // indirect +) + replace github.com/quic-go/quic-go => ../../ diff --git a/integrationtests/gomodvendor/go.sum b/integrationtests/gomodvendor/go.sum index d65b491abbd..b03fcbd1cbc 100644 --- a/integrationtests/gomodvendor/go.sum +++ b/integrationtests/gomodvendor/go.sum @@ -1,364 +1,51 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -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/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/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -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= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -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/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -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.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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-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/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-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -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= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -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/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -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/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= -github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= -github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= -github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= -github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= -github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= -github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= -github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= -github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= -github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= -github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= -github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= -github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= -github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= -github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= -github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= -github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= -github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= -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= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -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.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= -github.com/quic-go/qtls-go1-20 v0.4.1/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= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= -github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -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.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= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -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/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -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/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= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -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-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.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= -golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -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 v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/integrationtests/self/zero_rtt_oldgo_test.go b/integrationtests/self/zero_rtt_oldgo_test.go deleted file mode 100644 index af5400d1dd2..00000000000 --- a/integrationtests/self/zero_rtt_oldgo_test.go +++ /dev/null @@ -1,985 +0,0 @@ -//go:build !go1.21 - -package self_test - -import ( - "context" - "crypto/tls" - "fmt" - "io" - mrand "math/rand" - "net" - "sync" - "sync/atomic" - "time" - - "github.com/quic-go/quic-go" - quicproxy "github.com/quic-go/quic-go/integrationtests/tools/proxy" - "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/internal/wire" - "github.com/quic-go/quic-go/logging" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("0-RTT", func() { - rtt := scaleDuration(5 * time.Millisecond) - - runCountingProxy := func(serverPort int) (*quicproxy.QuicProxy, *atomic.Uint32) { - var num0RTTPackets atomic.Uint32 - proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{ - RemoteAddr: fmt.Sprintf("localhost:%d", serverPort), - DelayPacket: func(_ quicproxy.Direction, data []byte) time.Duration { - for len(data) > 0 { - if !wire.IsLongHeaderPacket(data[0]) { - break - } - hdr, _, rest, err := wire.ParsePacket(data) - Expect(err).ToNot(HaveOccurred()) - if hdr.Type == protocol.PacketType0RTT { - num0RTTPackets.Add(1) - break - } - data = rest - } - return rtt / 2 - }, - }) - Expect(err).ToNot(HaveOccurred()) - - return proxy, &num0RTTPackets - } - - dialAndReceiveSessionTicket := func(serverConf *quic.Config) (*tls.Config, *tls.Config) { - tlsConf := getTLSConfig() - if serverConf == nil { - serverConf = getQuicConfig(nil) - } - serverConf.Allow0RTT = true - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - serverConf, - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - - proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{ - RemoteAddr: fmt.Sprintf("localhost:%d", ln.Addr().(*net.UDPAddr).Port), - DelayPacket: func(_ quicproxy.Direction, data []byte) time.Duration { return rtt / 2 }, - }) - Expect(err).ToNot(HaveOccurred()) - defer proxy.Close() - - // dial the first connection in order to receive a session ticket - done := make(chan struct{}) - go func() { - defer GinkgoRecover() - defer close(done) - conn, err := ln.Accept(context.Background()) - Expect(err).ToNot(HaveOccurred()) - <-conn.Context().Done() - }() - - clientConf := getTLSClientConfig() - gets := make(chan string, 100) - puts := make(chan string, 100) - clientConf.ClientSessionCache = newClientSessionCache(tls.NewLRUClientSessionCache(100), gets, puts) - conn, err := quic.DialAddr( - context.Background(), - fmt.Sprintf("localhost:%d", proxy.LocalPort()), - clientConf, - getQuicConfig(nil), - ) - Expect(err).ToNot(HaveOccurred()) - Eventually(puts).Should(Receive()) - // received the session ticket. We're done here. - Expect(conn.CloseWithError(0, "")).To(Succeed()) - Eventually(done).Should(BeClosed()) - return tlsConf, clientConf - } - - transfer0RTTData := func( - ln *quic.EarlyListener, - proxyPort int, - connIDLen int, - clientTLSConf *tls.Config, - clientConf *quic.Config, - testdata []byte, // data to transfer - ) { - // accept the second connection, and receive the data sent in 0-RTT - done := make(chan struct{}) - go func() { - defer GinkgoRecover() - conn, err := ln.Accept(context.Background()) - Expect(err).ToNot(HaveOccurred()) - str, err := conn.AcceptStream(context.Background()) - Expect(err).ToNot(HaveOccurred()) - data, err := io.ReadAll(str) - Expect(err).ToNot(HaveOccurred()) - Expect(data).To(Equal(testdata)) - Expect(str.Close()).To(Succeed()) - Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) - <-conn.Context().Done() - close(done) - }() - - if clientConf == nil { - clientConf = getQuicConfig(nil) - } - var conn quic.EarlyConnection - if connIDLen == 0 { - var err error - conn, err = quic.DialAddrEarly( - context.Background(), - fmt.Sprintf("localhost:%d", proxyPort), - clientTLSConf, - clientConf, - ) - Expect(err).ToNot(HaveOccurred()) - } else { - addr, err := net.ResolveUDPAddr("udp", "localhost:0") - Expect(err).ToNot(HaveOccurred()) - udpConn, err := net.ListenUDP("udp", addr) - Expect(err).ToNot(HaveOccurred()) - defer udpConn.Close() - tr := &quic.Transport{ - Conn: udpConn, - ConnectionIDLength: connIDLen, - } - defer tr.Close() - conn, err = tr.DialEarly( - context.Background(), - &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: proxyPort}, - clientTLSConf, - clientConf, - ) - Expect(err).ToNot(HaveOccurred()) - } - defer conn.CloseWithError(0, "") - str, err := conn.OpenStream() - Expect(err).ToNot(HaveOccurred()) - _, err = str.Write(testdata) - Expect(err).ToNot(HaveOccurred()) - Expect(str.Close()).To(Succeed()) - <-conn.HandshakeComplete() - Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) - io.ReadAll(str) // wait for the EOF from the server to arrive before closing the conn - conn.CloseWithError(0, "") - Eventually(done).Should(BeClosed()) - Eventually(conn.Context().Done()).Should(BeClosed()) - } - - check0RTTRejected := func( - ln *quic.EarlyListener, - proxyPort int, - clientConf *tls.Config, - ) { - conn, err := quic.DialAddrEarly( - context.Background(), - fmt.Sprintf("localhost:%d", proxyPort), - clientConf, - getQuicConfig(nil), - ) - Expect(err).ToNot(HaveOccurred()) - str, err := conn.OpenUniStream() - Expect(err).ToNot(HaveOccurred()) - _, err = str.Write(make([]byte, 3000)) - Expect(err).ToNot(HaveOccurred()) - Expect(str.Close()).To(Succeed()) - Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) - - // make sure the server doesn't process the data - ctx, cancel := context.WithTimeout(context.Background(), scaleDuration(50*time.Millisecond)) - defer cancel() - serverConn, err := ln.Accept(ctx) - Expect(err).ToNot(HaveOccurred()) - Expect(serverConn.ConnectionState().Used0RTT).To(BeFalse()) - _, err = serverConn.AcceptUniStream(ctx) - Expect(err).To(Equal(context.DeadlineExceeded)) - Expect(serverConn.CloseWithError(0, "")).To(Succeed()) - Eventually(conn.Context().Done()).Should(BeClosed()) - } - - // can be used to extract 0-RTT from a packetCounter - get0RTTPackets := func(packets []packet) []protocol.PacketNumber { - var zeroRTTPackets []protocol.PacketNumber - for _, p := range packets { - if p.hdr.Type == protocol.PacketType0RTT { - zeroRTTPackets = append(zeroRTTPackets, p.hdr.PacketNumber) - } - } - return zeroRTTPackets - } - - for _, l := range []int{0, 15} { - connIDLen := l - - It(fmt.Sprintf("transfers 0-RTT data, with %d byte connection IDs", connIDLen), func() { - tlsConf, clientTLSConf := dialAndReceiveSessionTicket(nil) - - counter, tracer := newPacketTracer() - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - Allow0RTT: true, - Tracer: newTracer(tracer), - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - - proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) - defer proxy.Close() - - transfer0RTTData( - ln, - proxy.LocalPort(), - connIDLen, - clientTLSConf, - getQuicConfig(nil), - PRData, - ) - - var numNewConnIDs int - for _, p := range counter.getRcvdLongHeaderPackets() { - for _, f := range p.frames { - if _, ok := f.(*logging.NewConnectionIDFrame); ok { - numNewConnIDs++ - } - } - } - if connIDLen == 0 { - Expect(numNewConnIDs).To(BeZero()) - } else { - Expect(numNewConnIDs).ToNot(BeZero()) - } - - num0RTT := num0RTTPackets.Load() - fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) - Expect(num0RTT).ToNot(BeZero()) - zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets()) - Expect(len(zeroRTTPackets)).To(BeNumerically(">", 10)) - Expect(zeroRTTPackets).To(ContainElement(protocol.PacketNumber(0))) - }) - } - - // Test that data intended to be sent with 1-RTT protection is not sent in 0-RTT packets. - It("waits for a connection until the handshake is done", func() { - tlsConf, clientConf := dialAndReceiveSessionTicket(nil) - - zeroRTTData := GeneratePRData(5 << 10) - oneRTTData := PRData - - counter, tracer := newPacketTracer() - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - Allow0RTT: true, - Tracer: newTracer(tracer), - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - - // now accept the second connection, and receive the 0-RTT data - go func() { - defer GinkgoRecover() - conn, err := ln.Accept(context.Background()) - Expect(err).ToNot(HaveOccurred()) - str, err := conn.AcceptUniStream(context.Background()) - Expect(err).ToNot(HaveOccurred()) - data, err := io.ReadAll(str) - Expect(err).ToNot(HaveOccurred()) - Expect(data).To(Equal(zeroRTTData)) - str, err = conn.AcceptUniStream(context.Background()) - Expect(err).ToNot(HaveOccurred()) - data, err = io.ReadAll(str) - Expect(err).ToNot(HaveOccurred()) - Expect(data).To(Equal(oneRTTData)) - Expect(conn.CloseWithError(0, "")).To(Succeed()) - }() - - proxy, _ := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) - defer proxy.Close() - - conn, err := quic.DialAddrEarly( - context.Background(), - fmt.Sprintf("localhost:%d", proxy.LocalPort()), - clientConf, - getQuicConfig(nil), - ) - Expect(err).ToNot(HaveOccurred()) - firstStr, err := conn.OpenUniStream() - Expect(err).ToNot(HaveOccurred()) - _, err = firstStr.Write(zeroRTTData) - Expect(err).ToNot(HaveOccurred()) - Expect(firstStr.Close()).To(Succeed()) - - // wait for the handshake to complete - Eventually(conn.HandshakeComplete()).Should(BeClosed()) - str, err := conn.OpenUniStream() - Expect(err).ToNot(HaveOccurred()) - _, err = str.Write(PRData) - Expect(err).ToNot(HaveOccurred()) - Expect(str.Close()).To(Succeed()) - <-conn.Context().Done() - - // check that 0-RTT packets only contain STREAM frames for the first stream - var num0RTT int - for _, p := range counter.getRcvdLongHeaderPackets() { - if p.hdr.Header.Type != protocol.PacketType0RTT { - continue - } - for _, f := range p.frames { - sf, ok := f.(*logging.StreamFrame) - if !ok { - continue - } - num0RTT++ - Expect(sf.StreamID).To(Equal(firstStr.StreamID())) - } - } - fmt.Fprintf(GinkgoWriter, "received %d STREAM frames in 0-RTT packets\n", num0RTT) - Expect(num0RTT).ToNot(BeZero()) - }) - - It("transfers 0-RTT data, when 0-RTT packets are lost", func() { - var num0RTTPackets, num0RTTDropped atomic.Uint32 - - tlsConf, clientConf := dialAndReceiveSessionTicket(nil) - - counter, tracer := newPacketTracer() - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - Allow0RTT: true, - Tracer: newTracer(tracer), - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - - proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{ - RemoteAddr: fmt.Sprintf("localhost:%d", ln.Addr().(*net.UDPAddr).Port), - DelayPacket: func(_ quicproxy.Direction, data []byte) time.Duration { - if wire.IsLongHeaderPacket(data[0]) { - hdr, _, _, err := wire.ParsePacket(data) - Expect(err).ToNot(HaveOccurred()) - if hdr.Type == protocol.PacketType0RTT { - num0RTTPackets.Add(1) - } - } - return rtt / 2 - }, - DropPacket: func(_ quicproxy.Direction, data []byte) bool { - if !wire.IsLongHeaderPacket(data[0]) { - return false - } - hdr, _, _, err := wire.ParsePacket(data) - Expect(err).ToNot(HaveOccurred()) - if hdr.Type == protocol.PacketType0RTT { - // drop 25% of the 0-RTT packets - drop := mrand.Intn(4) == 0 - if drop { - num0RTTDropped.Add(1) - } - return drop - } - return false - }, - }) - Expect(err).ToNot(HaveOccurred()) - defer proxy.Close() - - transfer0RTTData(ln, proxy.LocalPort(), protocol.DefaultConnectionIDLength, clientConf, nil, PRData) - - num0RTT := num0RTTPackets.Load() - numDropped := num0RTTDropped.Load() - fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets. Dropped %d of those.", num0RTT, numDropped) - Expect(numDropped).ToNot(BeZero()) - Expect(num0RTT).ToNot(BeZero()) - Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).ToNot(BeEmpty()) - }) - - It("retransmits all 0-RTT data when the server performs a Retry", func() { - var mutex sync.Mutex - var firstConnID, secondConnID *protocol.ConnectionID - var firstCounter, secondCounter protocol.ByteCount - - tlsConf, clientConf := dialAndReceiveSessionTicket(nil) - - countZeroRTTBytes := func(data []byte) (n protocol.ByteCount) { - for len(data) > 0 { - hdr, _, rest, err := wire.ParsePacket(data) - if err != nil { - return - } - data = rest - if hdr.Type == protocol.PacketType0RTT { - n += hdr.Length - 16 /* AEAD tag */ - } - } - return - } - - counter, tracer := newPacketTracer() - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - RequireAddressValidation: func(net.Addr) bool { return true }, - Allow0RTT: true, - Tracer: newTracer(tracer), - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - - proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{ - RemoteAddr: fmt.Sprintf("localhost:%d", ln.Addr().(*net.UDPAddr).Port), - DelayPacket: func(dir quicproxy.Direction, data []byte) time.Duration { - connID, err := wire.ParseConnectionID(data, 0) - Expect(err).ToNot(HaveOccurred()) - - mutex.Lock() - defer mutex.Unlock() - - if zeroRTTBytes := countZeroRTTBytes(data); zeroRTTBytes > 0 { - if firstConnID == nil { - firstConnID = &connID - firstCounter += zeroRTTBytes - } else if firstConnID != nil && *firstConnID == connID { - Expect(secondConnID).To(BeNil()) - firstCounter += zeroRTTBytes - } else if secondConnID == nil { - secondConnID = &connID - secondCounter += zeroRTTBytes - } else if secondConnID != nil && *secondConnID == connID { - secondCounter += zeroRTTBytes - } else { - Fail("received 3 connection IDs on 0-RTT packets") - } - } - return rtt / 2 - }, - }) - Expect(err).ToNot(HaveOccurred()) - defer proxy.Close() - - transfer0RTTData(ln, proxy.LocalPort(), protocol.DefaultConnectionIDLength, clientConf, nil, GeneratePRData(5000)) // ~5 packets - - mutex.Lock() - 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(counter.getRcvdLongHeaderPackets()) - Expect(len(zeroRTTPackets)).To(BeNumerically(">=", 5)) - Expect(zeroRTTPackets[0]).To(BeNumerically(">=", protocol.PacketNumber(5))) - }) - - It("doesn't use 0-RTT when Dial is used for the resumed connection", func() { - tlsConf, clientConf := dialAndReceiveSessionTicket(nil) - - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{Allow0RTT: true}), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) - defer proxy.Close() - - conn, err := quic.DialAddr( - context.Background(), - fmt.Sprintf("localhost:%d", proxy.LocalPort()), - clientConf, - getQuicConfig(nil), - ) - Expect(err).ToNot(HaveOccurred()) - defer conn.CloseWithError(0, "") - Expect(conn.ConnectionState().TLS.DidResume).To(BeTrue()) - Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) - Expect(num0RTTPackets.Load()).To(BeZero()) - - serverConn, err := ln.Accept(context.Background()) - Expect(err).ToNot(HaveOccurred()) - Expect(serverConn.ConnectionState().TLS.DidResume).To(BeTrue()) - Expect(serverConn.ConnectionState().Used0RTT).To(BeFalse()) - }) - - It("doesn't reject 0-RTT when the server's transport stream limit increased", func() { - const maxStreams = 1 - tlsConf, clientConf := dialAndReceiveSessionTicket(getQuicConfig(&quic.Config{ - MaxIncomingUniStreams: maxStreams, - })) - - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - MaxIncomingUniStreams: maxStreams + 1, - Allow0RTT: true, - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - proxy, _ := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) - defer proxy.Close() - - conn, err := quic.DialAddrEarly( - context.Background(), - fmt.Sprintf("localhost:%d", proxy.LocalPort()), - clientConf, - getQuicConfig(nil), - ) - Expect(err).ToNot(HaveOccurred()) - str, err := conn.OpenUniStream() - Expect(err).ToNot(HaveOccurred()) - _, err = str.Write([]byte("foobar")) - Expect(err).ToNot(HaveOccurred()) - Expect(str.Close()).To(Succeed()) - // The client remembers the old limit and refuses to open a new stream. - _, err = conn.OpenUniStream() - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("too many open streams")) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - _, err = conn.OpenUniStreamSync(ctx) - Expect(err).ToNot(HaveOccurred()) - Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) - Expect(conn.CloseWithError(0, "")).To(Succeed()) - }) - - It("rejects 0-RTT when the server's stream limit decreased", func() { - const maxStreams = 42 - tlsConf, clientConf := dialAndReceiveSessionTicket(getQuicConfig(&quic.Config{ - MaxIncomingStreams: maxStreams, - })) - - counter, tracer := newPacketTracer() - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - MaxIncomingStreams: maxStreams - 1, - Allow0RTT: true, - Tracer: newTracer(tracer), - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) - defer proxy.Close() - check0RTTRejected(ln, proxy.LocalPort(), clientConf) - - // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := num0RTTPackets.Load() - fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) - Expect(num0RTT).ToNot(BeZero()) - Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) - }) - - It("rejects 0-RTT when the ALPN changed", func() { - tlsConf, clientConf := dialAndReceiveSessionTicket(nil) - - // now close the listener and dial new connection with a different ALPN - clientConf.NextProtos = []string{"new-alpn"} - tlsConf.NextProtos = []string{"new-alpn"} - counter, tracer := newPacketTracer() - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - Allow0RTT: true, - Tracer: newTracer(tracer), - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) - defer proxy.Close() - - check0RTTRejected(ln, proxy.LocalPort(), clientConf) - - // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := num0RTTPackets.Load() - fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) - Expect(num0RTT).ToNot(BeZero()) - 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 - counter, tracer := newPacketTracer() - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - Allow0RTT: false, // application rejects 0-RTT - Tracer: newTracer(tracer), - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) - defer proxy.Close() - - check0RTTRejected(ln, proxy.LocalPort(), clientConf) - - // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := num0RTTPackets.Load() - fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) - Expect(num0RTT).ToNot(BeZero()) - Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) - }) - - It("doesn't use 0-RTT, if the server didn't enable it", func() { - server, err := quic.ListenAddr("localhost:0", getTLSConfig(), getQuicConfig(nil)) - Expect(err).ToNot(HaveOccurred()) - defer server.Close() - - gets := make(chan string, 100) - puts := make(chan string, 100) - cache := newClientSessionCache(tls.NewLRUClientSessionCache(10), gets, puts) - tlsConf := getTLSClientConfig() - tlsConf.ClientSessionCache = cache - conn1, err := quic.DialAddr( - context.Background(), - fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), - tlsConf, - getQuicConfig(nil), - ) - Expect(err).ToNot(HaveOccurred()) - defer conn1.CloseWithError(0, "") - var sessionKey string - Eventually(puts).Should(Receive(&sessionKey)) - Expect(conn1.ConnectionState().TLS.DidResume).To(BeFalse()) - - serverConn, err := server.Accept(context.Background()) - Expect(err).ToNot(HaveOccurred()) - Expect(serverConn.ConnectionState().TLS.DidResume).To(BeFalse()) - - conn2, err := quic.DialAddrEarly( - context.Background(), - fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), - tlsConf, - getQuicConfig(nil), - ) - Expect(err).ToNot(HaveOccurred()) - Expect(gets).To(Receive(Equal(sessionKey))) - Expect(conn2.ConnectionState().TLS.DidResume).To(BeTrue()) - - serverConn, err = server.Accept(context.Background()) - Expect(err).ToNot(HaveOccurred()) - Expect(serverConn.ConnectionState().TLS.DidResume).To(BeTrue()) - Expect(serverConn.ConnectionState().Used0RTT).To(BeFalse()) - conn2.CloseWithError(0, "") - }) - - DescribeTable("flow control limits", - func(addFlowControlLimit func(*quic.Config, uint64)) { - counter, tracer := newPacketTracer() - firstConf := getQuicConfig(&quic.Config{Allow0RTT: true}) - addFlowControlLimit(firstConf, 3) - tlsConf, clientConf := dialAndReceiveSessionTicket(firstConf) - - secondConf := getQuicConfig(&quic.Config{ - Allow0RTT: true, - Tracer: newTracer(tracer), - }) - addFlowControlLimit(secondConf, 100) - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - secondConf, - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - proxy, _ := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) - defer proxy.Close() - - conn, err := quic.DialAddrEarly( - context.Background(), - fmt.Sprintf("localhost:%d", proxy.LocalPort()), - clientConf, - getQuicConfig(nil), - ) - Expect(err).ToNot(HaveOccurred()) - str, err := conn.OpenUniStream() - Expect(err).ToNot(HaveOccurred()) - written := make(chan struct{}) - go func() { - defer GinkgoRecover() - defer close(written) - _, err := str.Write([]byte("foobar")) - Expect(err).ToNot(HaveOccurred()) - Expect(str.Close()).To(Succeed()) - }() - - Eventually(written).Should(BeClosed()) - - serverConn, err := ln.Accept(context.Background()) - Expect(err).ToNot(HaveOccurred()) - rstr, err := serverConn.AcceptUniStream(context.Background()) - Expect(err).ToNot(HaveOccurred()) - data, err := io.ReadAll(rstr) - Expect(err).ToNot(HaveOccurred()) - Expect(data).To(Equal([]byte("foobar"))) - Expect(serverConn.ConnectionState().Used0RTT).To(BeTrue()) - Expect(serverConn.CloseWithError(0, "")).To(Succeed()) - Eventually(conn.Context().Done()).Should(BeClosed()) - - var processedFirst bool - for _, p := range counter.getRcvdLongHeaderPackets() { - for _, f := range p.frames { - if sf, ok := f.(*logging.StreamFrame); ok { - if !processedFirst { - // The first STREAM should have been sent in a 0-RTT packet. - // Due to the flow control limit, the STREAM frame was limit to the first 3 bytes. - Expect(p.hdr.Type).To(Equal(protocol.PacketType0RTT)) - Expect(sf.Length).To(BeEquivalentTo(3)) - processedFirst = true - } else { - Fail("STREAM was shouldn't have been sent in 0-RTT") - } - } - } - } - }, - Entry("doesn't reject 0-RTT when the server's transport stream flow control limit increased", func(c *quic.Config, limit uint64) { c.InitialStreamReceiveWindow = limit }), - Entry("doesn't reject 0-RTT when the server's transport connection flow control limit increased", func(c *quic.Config, limit uint64) { c.InitialConnectionReceiveWindow = limit }), - ) - - for _, l := range []int{0, 15} { - connIDLen := l - - 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 - counter, tracer := newPacketTracer() - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - MaxIncomingUniStreams: 1, - Tracer: newTracer(tracer), - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) - defer proxy.Close() - - conn, err := quic.DialAddrEarly( - context.Background(), - fmt.Sprintf("localhost:%d", proxy.LocalPort()), - clientConf, - getQuicConfig(nil), - ) - Expect(err).ToNot(HaveOccurred()) - // The client remembers that it was allowed to open 2 uni-directional streams. - firstStr, err := conn.OpenUniStream() - Expect(err).ToNot(HaveOccurred()) - written := make(chan struct{}, 2) - go func() { - defer GinkgoRecover() - defer func() { written <- struct{}{} }() - _, err := firstStr.Write([]byte("first flight")) - Expect(err).ToNot(HaveOccurred()) - }() - secondStr, err := conn.OpenUniStream() - Expect(err).ToNot(HaveOccurred()) - go func() { - defer GinkgoRecover() - defer func() { written <- struct{}{} }() - _, err := secondStr.Write([]byte("first flight")) - Expect(err).ToNot(HaveOccurred()) - }() - - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - _, err = conn.AcceptStream(ctx) - Expect(err).To(MatchError(quic.Err0RTTRejected)) - Eventually(written).Should(Receive()) - Eventually(written).Should(Receive()) - _, err = firstStr.Write([]byte("foobar")) - Expect(err).To(MatchError(quic.Err0RTTRejected)) - _, err = conn.OpenUniStream() - Expect(err).To(MatchError(quic.Err0RTTRejected)) - - _, err = conn.AcceptStream(ctx) - Expect(err).To(Equal(quic.Err0RTTRejected)) - - newConn := conn.NextConnection() - str, err := newConn.OpenUniStream() - Expect(err).ToNot(HaveOccurred()) - _, err = newConn.OpenUniStream() - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("too many open streams")) - _, err = str.Write([]byte("second flight")) - Expect(err).ToNot(HaveOccurred()) - Expect(str.Close()).To(Succeed()) - Expect(conn.CloseWithError(0, "")).To(Succeed()) - - // The client should send 0-RTT packets, but the server doesn't process them. - num0RTT := num0RTTPackets.Load() - fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) - Expect(num0RTT).ToNot(BeZero()) - Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) - }) - } - - It("queues 0-RTT packets, if the Initial is delayed", func() { - tlsConf, clientConf := dialAndReceiveSessionTicket(nil) - - counter, tracer := newPacketTracer() - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - Allow0RTT: true, - Tracer: newTracer(tracer), - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{ - RemoteAddr: ln.Addr().String(), - DelayPacket: func(dir quicproxy.Direction, data []byte) time.Duration { - if dir == quicproxy.DirectionIncoming && wire.IsLongHeaderPacket(data[0]) && data[0]&0x30>>4 == 0 { // Initial packet from client - return rtt/2 + rtt - } - return rtt / 2 - }, - }) - Expect(err).ToNot(HaveOccurred()) - defer proxy.Close() - - transfer0RTTData(ln, proxy.LocalPort(), protocol.DefaultConnectionIDLength, clientConf, nil, PRData) - - 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))) - }) - - It("sends 0-RTT datagrams", func() { - tlsConf, clientTLSConf := dialAndReceiveSessionTicket(getQuicConfig(&quic.Config{ - EnableDatagrams: true, - })) - - counter, tracer := newPacketTracer() - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - Allow0RTT: true, - EnableDatagrams: true, - Tracer: newTracer(tracer), - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - - proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) - defer proxy.Close() - - // second connection - sentMessage := GeneratePRData(100) - var receivedMessage []byte - received := make(chan struct{}) - go func() { - defer GinkgoRecover() - defer close(received) - conn, err := ln.Accept(context.Background()) - Expect(err).ToNot(HaveOccurred()) - receivedMessage, err = conn.ReceiveDatagram(context.Background()) - Expect(err).ToNot(HaveOccurred()) - Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) - }() - conn, err := quic.DialAddrEarly( - context.Background(), - fmt.Sprintf("localhost:%d", proxy.LocalPort()), - clientTLSConf, - getQuicConfig(&quic.Config{ - EnableDatagrams: true, - }), - ) - Expect(err).ToNot(HaveOccurred()) - Expect(conn.ConnectionState().SupportsDatagrams).To(BeTrue()) - Expect(conn.SendDatagram(sentMessage)).To(Succeed()) - <-conn.HandshakeComplete() - <-received - - Expect(conn.ConnectionState().Used0RTT).To(BeTrue()) - Expect(receivedMessage).To(Equal(sentMessage)) - Expect(conn.CloseWithError(0, "")).To(Succeed()) - num0RTT := num0RTTPackets.Load() - fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) - Expect(num0RTT).ToNot(BeZero()) - zeroRTTPackets := get0RTTPackets(counter.getRcvdLongHeaderPackets()) - Expect(zeroRTTPackets).To(HaveLen(1)) - }) - - It("rejects 0-RTT datagrams when the server doesn't support datagrams anymore", func() { - tlsConf, clientTLSConf := dialAndReceiveSessionTicket(getQuicConfig(&quic.Config{ - EnableDatagrams: true, - })) - - counter, tracer := newPacketTracer() - ln, err := quic.ListenAddrEarly( - "localhost:0", - tlsConf, - getQuicConfig(&quic.Config{ - Allow0RTT: true, - EnableDatagrams: false, - Tracer: newTracer(tracer), - }), - ) - Expect(err).ToNot(HaveOccurred()) - defer ln.Close() - - proxy, num0RTTPackets := runCountingProxy(ln.Addr().(*net.UDPAddr).Port) - defer proxy.Close() - - // second connection - go func() { - defer GinkgoRecover() - conn, err := ln.Accept(context.Background()) - Expect(err).ToNot(HaveOccurred()) - _, err = conn.ReceiveDatagram(context.Background()) - Expect(err.Error()).To(Equal("datagram support disabled")) - <-conn.HandshakeComplete() - Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) - }() - conn, err := quic.DialAddrEarly( - context.Background(), - fmt.Sprintf("localhost:%d", proxy.LocalPort()), - clientTLSConf, - getQuicConfig(&quic.Config{ - EnableDatagrams: true, - }), - ) - Expect(err).ToNot(HaveOccurred()) - // the client can temporarily send datagrams but the server doesn't process them. - Expect(conn.ConnectionState().SupportsDatagrams).To(BeTrue()) - Expect(conn.SendDatagram(make([]byte, 100))).To(Succeed()) - <-conn.HandshakeComplete() - - Expect(conn.ConnectionState().SupportsDatagrams).To(BeFalse()) - Expect(conn.ConnectionState().Used0RTT).To(BeFalse()) - Expect(conn.CloseWithError(0, "")).To(Succeed()) - num0RTT := num0RTTPackets.Load() - fmt.Fprintf(GinkgoWriter, "Sent %d 0-RTT packets.", num0RTT) - Expect(num0RTT).ToNot(BeZero()) - Expect(get0RTTPackets(counter.getRcvdLongHeaderPackets())).To(BeEmpty()) - }) -}) diff --git a/integrationtests/self/zero_rtt_test.go b/integrationtests/self/zero_rtt_test.go index 7bfa66cef23..6356e633751 100644 --- a/integrationtests/self/zero_rtt_test.go +++ b/integrationtests/self/zero_rtt_test.go @@ -1,5 +1,3 @@ -//go:build go1.21 - package self_test import ( diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index 34f298871c1..9223a6294b0 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -29,7 +29,7 @@ const clientSessionStateRevision = 4 type cryptoSetup struct { tlsConf *tls.Config - conn *qtls.QUICConn + conn *tls.QUICConn events []Event @@ -93,12 +93,12 @@ func NewCryptoSetupClient( tlsConf = tlsConf.Clone() tlsConf.MinVersion = tls.VersionTLS13 - quicConf := &qtls.QUICConfig{TLSConfig: tlsConf} + quicConf := &tls.QUICConfig{TLSConfig: tlsConf} qtls.SetupConfigForClient(quicConf, cs.marshalDataForSessionState, cs.handleDataFromSessionState) cs.tlsConf = tlsConf cs.allow0RTT = enable0RTT - cs.conn = qtls.QUICClient(quicConf) + cs.conn = tls.QUICClient(quicConf) cs.conn.SetTransportParameters(cs.ourParams.Marshal(protocol.PerspectiveClient)) return cs @@ -127,12 +127,12 @@ func NewCryptoSetupServer( ) cs.allow0RTT = allow0RTT - quicConf := &qtls.QUICConfig{TLSConfig: tlsConf} + quicConf := &tls.QUICConfig{TLSConfig: tlsConf} qtls.SetupConfigForServer(quicConf, cs.allow0RTT, cs.getDataForSessionTicket, cs.handleSessionTicket) addConnToClientHelloInfo(quicConf.TLSConfig, localAddr, remoteAddr) cs.tlsConf = quicConf.TLSConfig - cs.conn = qtls.QUICServer(quicConf) + cs.conn = tls.QUICServer(quicConf) return cs } @@ -264,28 +264,28 @@ func (h *cryptoSetup) handleMessage(data []byte, encLevel protocol.EncryptionLev } } -func (h *cryptoSetup) handleEvent(ev qtls.QUICEvent) (done bool, err error) { +func (h *cryptoSetup) handleEvent(ev tls.QUICEvent) (done bool, err error) { switch ev.Kind { - case qtls.QUICNoEvent: + case tls.QUICNoEvent: return true, nil - case qtls.QUICSetReadSecret: + case tls.QUICSetReadSecret: h.SetReadKey(ev.Level, ev.Suite, ev.Data) return false, nil - case qtls.QUICSetWriteSecret: + case tls.QUICSetWriteSecret: h.SetWriteKey(ev.Level, ev.Suite, ev.Data) return false, nil - case qtls.QUICTransportParameters: + case tls.QUICTransportParameters: return false, h.handleTransportParameters(ev.Data) - case qtls.QUICTransportParametersRequired: + case tls.QUICTransportParametersRequired: h.conn.SetTransportParameters(h.ourParams.Marshal(h.perspective)) return false, nil - case qtls.QUICRejectedEarlyData: + case tls.QUICRejectedEarlyData: h.rejected0RTT() return false, nil - case qtls.QUICWriteData: + case tls.QUICWriteData: h.WriteRecord(ev.Level, ev.Data) return false, nil - case qtls.QUICHandshakeDone: + case tls.QUICHandshakeDone: h.handshakeComplete() return false, nil default: @@ -379,7 +379,9 @@ func (h *cryptoSetup) getDataForSessionTicket() []byte { // Due to limitations in crypto/tls, it's only possible to generate a single session ticket per connection. // It is only valid for the server. func (h *cryptoSetup) GetSessionTicket() ([]byte, error) { - if err := qtls.SendSessionTicket(h.conn, h.allow0RTT); err != nil { + if err := h.conn.SendSessionTicket(tls.QUICSessionTicketOptions{ + EarlyData: h.allow0RTT, + }); err != nil { // Session tickets might be disabled by tls.Config.SessionTicketsDisabled. // We can't check h.tlsConfig here, since the actual config might have been obtained from // the GetConfigForClient callback. @@ -391,11 +393,11 @@ func (h *cryptoSetup) GetSessionTicket() ([]byte, error) { return nil, err } ev := h.conn.NextEvent() - if ev.Kind != qtls.QUICWriteData || ev.Level != qtls.QUICEncryptionLevelApplication { + if ev.Kind != tls.QUICWriteData || ev.Level != tls.QUICEncryptionLevelApplication { panic("crypto/tls bug: where's my session ticket?") } ticket := ev.Data - if ev := h.conn.NextEvent(); ev.Kind != qtls.QUICNoEvent { + if ev := h.conn.NextEvent(); ev.Kind != tls.QUICNoEvent { panic("crypto/tls bug: why more than one ticket?") } return ticket, nil @@ -442,12 +444,12 @@ func (h *cryptoSetup) rejected0RTT() { } } -func (h *cryptoSetup) SetReadKey(el qtls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) { +func (h *cryptoSetup) SetReadKey(el tls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) { suite := getCipherSuite(suiteID) h.mutex.Lock() //nolint:exhaustive // The TLS stack doesn't export Initial keys. switch el { - case qtls.QUICEncryptionLevelEarly: + case tls.QUICEncryptionLevelEarly: if h.perspective == protocol.PerspectiveClient { panic("Received 0-RTT read key for the client") } @@ -459,7 +461,7 @@ func (h *cryptoSetup) SetReadKey(el qtls.QUICEncryptionLevel, suiteID uint16, tr if h.logger.Debug() { h.logger.Debugf("Installed 0-RTT Read keys (using %s)", tls.CipherSuiteName(suite.ID)) } - case qtls.QUICEncryptionLevelHandshake: + case tls.QUICEncryptionLevelHandshake: h.handshakeOpener = newLongHeaderOpener( createAEAD(suite, trafficSecret, h.version), newHeaderProtector(suite, trafficSecret, true, h.version), @@ -467,7 +469,7 @@ func (h *cryptoSetup) SetReadKey(el qtls.QUICEncryptionLevel, suiteID uint16, tr if h.logger.Debug() { h.logger.Debugf("Installed Handshake Read keys (using %s)", tls.CipherSuiteName(suite.ID)) } - case qtls.QUICEncryptionLevelApplication: + case tls.QUICEncryptionLevelApplication: h.aead.SetReadKey(suite, trafficSecret) h.has1RTTOpener = true if h.logger.Debug() { @@ -483,7 +485,7 @@ func (h *cryptoSetup) SetReadKey(el qtls.QUICEncryptionLevel, suiteID uint16, tr } } -func (h *cryptoSetup) SetWriteKey(el qtls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) { +func (h *cryptoSetup) SetWriteKey(el tls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) { suite := getCipherSuite(suiteID) h.mutex.Lock() //nolint:exhaustive // The TLS stack doesn't export Initial keys. @@ -505,7 +507,7 @@ func (h *cryptoSetup) SetWriteKey(el qtls.QUICEncryptionLevel, suiteID uint16, t } // don't set used0RTT here. 0-RTT might still get rejected. return - case qtls.QUICEncryptionLevelHandshake: + case tls.QUICEncryptionLevelHandshake: h.handshakeSealer = newLongHeaderSealer( createAEAD(suite, trafficSecret, h.version), newHeaderProtector(suite, trafficSecret, true, h.version), @@ -513,7 +515,7 @@ func (h *cryptoSetup) SetWriteKey(el qtls.QUICEncryptionLevel, suiteID uint16, t if h.logger.Debug() { h.logger.Debugf("Installed Handshake Write keys (using %s)", tls.CipherSuiteName(suite.ID)) } - case qtls.QUICEncryptionLevelApplication: + case tls.QUICEncryptionLevelApplication: h.aead.SetWriteKey(suite, trafficSecret) h.has1RTTSealer = true if h.logger.Debug() { @@ -692,7 +694,7 @@ func (h *cryptoSetup) ConnectionState() ConnectionState { func wrapError(err error) error { // alert 80 is an internal error - if alertErr := qtls.AlertError(0); errors.As(err, &alertErr) && alertErr != 80 { + if alertErr := tls.AlertError(0); errors.As(err, &alertErr) && alertErr != 80 { return qerr.NewLocalCryptoError(uint8(alertErr), err) } return &qerr.TransportError{ErrorCode: qerr.InternalError, ErrorMessage: err.Error()} diff --git a/internal/handshake/crypto_setup_test.go b/internal/handshake/crypto_setup_test.go index 4e92118a13b..9dba7146d47 100644 --- a/internal/handshake/crypto_setup_test.go +++ b/internal/handshake/crypto_setup_test.go @@ -9,8 +9,6 @@ import ( "math/big" "net" "reflect" - "runtime" - "strings" "time" mocktls "github.com/quic-go/quic-go/internal/mocks/tls" @@ -462,10 +460,8 @@ var _ = Describe("Crypto Setup TLS", func() { Eventually(receivedSessionTicket).Should(BeClosed()) Expect(server.ConnectionState().DidResume).To(BeTrue()) Expect(client.ConnectionState().DidResume).To(BeTrue()) - if !strings.Contains(runtime.Version(), "go1.20") { - Expect(clientRTTStats.SmoothedRTT()).To(Equal(clientRTT)) - Expect(serverRTTStats.SmoothedRTT()).To(Equal(serverRTT)) - } + Expect(clientRTTStats.SmoothedRTT()).To(Equal(clientRTT)) + Expect(serverRTTStats.SmoothedRTT()).To(Equal(serverRTT)) }) It("doesn't use session resumption if the server disabled it", func() { diff --git a/internal/qerr/error_codes.go b/internal/qerr/error_codes.go index a037acd22e6..00361308e70 100644 --- a/internal/qerr/error_codes.go +++ b/internal/qerr/error_codes.go @@ -1,9 +1,8 @@ package qerr import ( + "crypto/tls" "fmt" - - "github.com/quic-go/quic-go/internal/qtls" ) // TransportErrorCode is a QUIC transport error. @@ -40,7 +39,7 @@ func (e TransportErrorCode) Message() string { if !e.IsCryptoError() { return "" } - return qtls.AlertError(e - 0x100).Error() + return tls.AlertError(e - 0x100).Error() } func (e TransportErrorCode) String() string { diff --git a/internal/qtls/cipher_suite_go121.go b/internal/qtls/cipher_suite.go similarity index 99% rename from internal/qtls/cipher_suite_go121.go rename to internal/qtls/cipher_suite.go index aa8c768fd25..16558f8bcd3 100644 --- a/internal/qtls/cipher_suite_go121.go +++ b/internal/qtls/cipher_suite.go @@ -1,5 +1,3 @@ -//go:build go1.21 - package qtls import ( diff --git a/internal/qtls/cipher_suite_test.go b/internal/qtls/cipher_suite_test.go index 57de9ad899f..716d82171bf 100644 --- a/internal/qtls/cipher_suite_test.go +++ b/internal/qtls/cipher_suite_test.go @@ -1,5 +1,3 @@ -//go:build go1.21 - package qtls import ( diff --git a/internal/qtls/client_session_cache_test.go b/internal/qtls/client_session_cache_test.go index fdb0aa06182..d3c747bfafb 100644 --- a/internal/qtls/client_session_cache_test.go +++ b/internal/qtls/client_session_cache_test.go @@ -1,5 +1,3 @@ -//go:build go1.21 - package qtls import ( diff --git a/internal/qtls/go120.go b/internal/qtls/go120.go deleted file mode 100644 index 554aeaf4d2b..00000000000 --- a/internal/qtls/go120.go +++ /dev/null @@ -1,157 +0,0 @@ -//go:build go1.20 && !go1.21 - -package qtls - -import ( - "crypto/tls" - "fmt" - "unsafe" - - "github.com/quic-go/quic-go/internal/protocol" - - "github.com/quic-go/qtls-go1-20" -) - -type ( - QUICConn = qtls.QUICConn - QUICConfig = qtls.QUICConfig - QUICEvent = qtls.QUICEvent - QUICEventKind = qtls.QUICEventKind - QUICEncryptionLevel = qtls.QUICEncryptionLevel - AlertError = qtls.AlertError -) - -const ( - QUICEncryptionLevelInitial = qtls.QUICEncryptionLevelInitial - QUICEncryptionLevelEarly = qtls.QUICEncryptionLevelEarly - QUICEncryptionLevelHandshake = qtls.QUICEncryptionLevelHandshake - QUICEncryptionLevelApplication = qtls.QUICEncryptionLevelApplication -) - -const ( - QUICNoEvent = qtls.QUICNoEvent - QUICSetReadSecret = qtls.QUICSetReadSecret - QUICSetWriteSecret = qtls.QUICSetWriteSecret - QUICWriteData = qtls.QUICWriteData - QUICTransportParameters = qtls.QUICTransportParameters - QUICTransportParametersRequired = qtls.QUICTransportParametersRequired - QUICRejectedEarlyData = qtls.QUICRejectedEarlyData - QUICHandshakeDone = qtls.QUICHandshakeDone -) - -func SetupConfigForServer(conf *QUICConfig, enable0RTT bool, getDataForSessionTicket func() []byte, handleSessionTicket func([]byte, bool) bool) { - qtls.InitSessionTicketKeys(conf.TLSConfig) - conf.TLSConfig = conf.TLSConfig.Clone() - conf.TLSConfig.MinVersion = tls.VersionTLS13 - conf.ExtraConfig = &qtls.ExtraConfig{ - Enable0RTT: enable0RTT, - Accept0RTT: func(data []byte) bool { - return handleSessionTicket(data, true) - }, - GetAppDataForSessionTicket: getDataForSessionTicket, - } -} - -func SetupConfigForClient( - conf *QUICConfig, - getDataForSessionState func(earlyData bool) []byte, - setDataFromSessionState func(data []byte, earlyData bool) (allowEarlyData bool), -) { - conf.ExtraConfig = &qtls.ExtraConfig{ - GetAppDataForSessionState: func() []byte { - // qtls only calls the GetAppDataForSessionState when doing 0-RTT - return getDataForSessionState(true) - }, - SetAppDataFromSessionState: func(data []byte) (allowEarlyData bool) { - // qtls only calls the SetAppDataFromSessionState for 0-RTT enabled tickets - return setDataFromSessionState(data, true) - }, - } -} - -func QUICServer(config *QUICConfig) *QUICConn { - return qtls.QUICServer(config) -} - -func QUICClient(config *QUICConfig) *QUICConn { - return qtls.QUICClient(config) -} - -func ToTLSEncryptionLevel(e protocol.EncryptionLevel) qtls.QUICEncryptionLevel { - switch e { - case protocol.EncryptionInitial: - return qtls.QUICEncryptionLevelInitial - case protocol.EncryptionHandshake: - return qtls.QUICEncryptionLevelHandshake - case protocol.Encryption1RTT: - return qtls.QUICEncryptionLevelApplication - case protocol.Encryption0RTT: - return qtls.QUICEncryptionLevelEarly - default: - panic(fmt.Sprintf("unexpected encryption level: %s", e)) - } -} - -func FromTLSEncryptionLevel(e qtls.QUICEncryptionLevel) protocol.EncryptionLevel { - switch e { - case qtls.QUICEncryptionLevelInitial: - return protocol.EncryptionInitial - case qtls.QUICEncryptionLevelHandshake: - return protocol.EncryptionHandshake - case qtls.QUICEncryptionLevelApplication: - return protocol.Encryption1RTT - case qtls.QUICEncryptionLevelEarly: - return protocol.Encryption0RTT - default: - panic(fmt.Sprintf("unexpect encryption level: %s", e)) - } -} - -//go:linkname cipherSuitesTLS13 github.com/quic-go/qtls-go1-20.cipherSuitesTLS13 -var cipherSuitesTLS13 []unsafe.Pointer - -//go:linkname defaultCipherSuitesTLS13 github.com/quic-go/qtls-go1-20.defaultCipherSuitesTLS13 -var defaultCipherSuitesTLS13 []uint16 - -//go:linkname defaultCipherSuitesTLS13NoAES github.com/quic-go/qtls-go1-20.defaultCipherSuitesTLS13NoAES -var defaultCipherSuitesTLS13NoAES []uint16 - -var cipherSuitesModified bool - -// SetCipherSuite modifies the cipherSuiteTLS13 slice of cipher suites inside qtls -// such that it only contains the cipher suite with the chosen id. -// The reset function returned resets them back to the original value. -func SetCipherSuite(id uint16) (reset func()) { - if cipherSuitesModified { - panic("cipher suites modified multiple times without resetting") - } - cipherSuitesModified = true - - origCipherSuitesTLS13 := append([]unsafe.Pointer{}, cipherSuitesTLS13...) - origDefaultCipherSuitesTLS13 := append([]uint16{}, defaultCipherSuitesTLS13...) - origDefaultCipherSuitesTLS13NoAES := append([]uint16{}, defaultCipherSuitesTLS13NoAES...) - // The order is given by the order of the slice elements in cipherSuitesTLS13 in qtls. - switch id { - case tls.TLS_AES_128_GCM_SHA256: - cipherSuitesTLS13 = cipherSuitesTLS13[:1] - case tls.TLS_CHACHA20_POLY1305_SHA256: - cipherSuitesTLS13 = cipherSuitesTLS13[1:2] - case tls.TLS_AES_256_GCM_SHA384: - cipherSuitesTLS13 = cipherSuitesTLS13[2:] - default: - panic(fmt.Sprintf("unexpected cipher suite: %d", id)) - } - defaultCipherSuitesTLS13 = []uint16{id} - defaultCipherSuitesTLS13NoAES = []uint16{id} - - return func() { - cipherSuitesTLS13 = origCipherSuitesTLS13 - defaultCipherSuitesTLS13 = origDefaultCipherSuitesTLS13 - defaultCipherSuitesTLS13NoAES = origDefaultCipherSuitesTLS13NoAES - cipherSuitesModified = false - } -} - -func SendSessionTicket(c *QUICConn, allow0RTT bool) error { - return c.SendSessionTicket(allow0RTT) -} diff --git a/internal/qtls/go120_test.go b/internal/qtls/go120_test.go deleted file mode 100644 index cbd1ab43622..00000000000 --- a/internal/qtls/go120_test.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build !go1.21 - -package qtls - -import ( - "github.com/quic-go/quic-go/internal/protocol" - - "github.com/quic-go/qtls-go1-20" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("Go 1.20", func() { - It("converts to qtls.EncryptionLevel", func() { - Expect(ToTLSEncryptionLevel(protocol.EncryptionInitial)).To(Equal(qtls.QUICEncryptionLevelInitial)) - Expect(ToTLSEncryptionLevel(protocol.EncryptionHandshake)).To(Equal(qtls.QUICEncryptionLevelHandshake)) - Expect(ToTLSEncryptionLevel(protocol.Encryption1RTT)).To(Equal(qtls.QUICEncryptionLevelApplication)) - Expect(ToTLSEncryptionLevel(protocol.Encryption0RTT)).To(Equal(qtls.QUICEncryptionLevelEarly)) - }) - - It("converts from qtls.EncryptionLevel", func() { - Expect(FromTLSEncryptionLevel(qtls.QUICEncryptionLevelInitial)).To(Equal(protocol.EncryptionInitial)) - Expect(FromTLSEncryptionLevel(qtls.QUICEncryptionLevelHandshake)).To(Equal(protocol.EncryptionHandshake)) - Expect(FromTLSEncryptionLevel(qtls.QUICEncryptionLevelApplication)).To(Equal(protocol.Encryption1RTT)) - Expect(FromTLSEncryptionLevel(qtls.QUICEncryptionLevelEarly)).To(Equal(protocol.Encryption0RTT)) - }) -}) diff --git a/internal/qtls/go_oldversion.go b/internal/qtls/go_oldversion.go deleted file mode 100644 index 0fca80a3881..00000000000 --- a/internal/qtls/go_oldversion.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !go1.20 - -package qtls - -var _ int = "The version of quic-go you're using can't be built using outdated Go versions. For more details, please see https://github.com/quic-go/quic-go/wiki/quic-go-and-Go-versions." diff --git a/internal/qtls/go121.go b/internal/qtls/qtls.go similarity index 74% rename from internal/qtls/go121.go rename to internal/qtls/qtls.go index 66e289b5afc..742dd3c9bb3 100644 --- a/internal/qtls/go121.go +++ b/internal/qtls/qtls.go @@ -1,5 +1,3 @@ -//go:build go1.21 - package qtls import ( @@ -11,13 +9,7 @@ import ( ) type ( - QUICConn = tls.QUICConn - QUICConfig = tls.QUICConfig - QUICEvent = tls.QUICEvent - QUICEventKind = tls.QUICEventKind - QUICEncryptionLevel = tls.QUICEncryptionLevel - QUICSessionTicketOptions = tls.QUICSessionTicketOptions - AlertError = tls.AlertError + QUICEncryptionLevel = tls.QUICEncryptionLevel ) const ( @@ -27,21 +19,7 @@ const ( QUICEncryptionLevelApplication = tls.QUICEncryptionLevelApplication ) -const ( - QUICNoEvent = tls.QUICNoEvent - QUICSetReadSecret = tls.QUICSetReadSecret - QUICSetWriteSecret = tls.QUICSetWriteSecret - QUICWriteData = tls.QUICWriteData - QUICTransportParameters = tls.QUICTransportParameters - QUICTransportParametersRequired = tls.QUICTransportParametersRequired - QUICRejectedEarlyData = tls.QUICRejectedEarlyData - QUICHandshakeDone = tls.QUICHandshakeDone -) - -func QUICServer(config *QUICConfig) *QUICConn { return tls.QUICServer(config) } -func QUICClient(config *QUICConfig) *QUICConn { return tls.QUICClient(config) } - -func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, handleSessionTicket func([]byte, bool) bool) { +func SetupConfigForServer(qconf *tls.QUICConfig, _ bool, getData func() []byte, handleSessionTicket func([]byte, bool) bool) { conf := qconf.TLSConfig // Workaround for https://github.com/golang/go/issues/60506. @@ -94,7 +72,7 @@ func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, hand } func SetupConfigForClient( - qconf *QUICConfig, + qconf *tls.QUICConfig, getData func(earlyData bool) []byte, setData func(data []byte, earlyData bool) (allowEarlyData bool), ) { @@ -155,9 +133,3 @@ func findExtraData(extras [][]byte) []byte { } return nil } - -func SendSessionTicket(c *QUICConn, allow0RTT bool) error { - return c.SendSessionTicket(tls.QUICSessionTicketOptions{ - EarlyData: allow0RTT, - }) -} diff --git a/internal/qtls/go121_test.go b/internal/qtls/qtls_test.go similarity index 92% rename from internal/qtls/go121_test.go rename to internal/qtls/qtls_test.go index 2aaafcee647..aadc118ccc7 100644 --- a/internal/qtls/go121_test.go +++ b/internal/qtls/qtls_test.go @@ -1,5 +1,3 @@ -//go:build go1.21 - package qtls import ( @@ -29,14 +27,14 @@ var _ = Describe("Go 1.21", func() { Context("setting up a tls.Config for the client", func() { It("sets up a session cache if there's one present on the config", func() { csc := tls.NewLRUClientSessionCache(1) - conf := &QUICConfig{TLSConfig: &tls.Config{ClientSessionCache: csc}} + conf := &tls.QUICConfig{TLSConfig: &tls.Config{ClientSessionCache: csc}} SetupConfigForClient(conf, nil, nil) Expect(conf.TLSConfig.ClientSessionCache).ToNot(BeNil()) Expect(conf.TLSConfig.ClientSessionCache).ToNot(Equal(csc)) }) It("doesn't set up a session cache if there's none present on the config", func() { - conf := &QUICConfig{TLSConfig: &tls.Config{}} + conf := &tls.QUICConfig{TLSConfig: &tls.Config{}} SetupConfigForClient(conf, nil, nil) Expect(conf.TLSConfig.ClientSessionCache).To(BeNil()) }) @@ -45,7 +43,7 @@ var _ = Describe("Go 1.21", func() { Context("setting up a tls.Config for the server", func() { It("sets the minimum TLS version to TLS 1.3", func() { orig := &tls.Config{MinVersion: tls.VersionTLS12} - conf := &QUICConfig{TLSConfig: orig} + conf := &tls.QUICConfig{TLSConfig: orig} SetupConfigForServer(conf, false, nil, nil) Expect(conf.TLSConfig.MinVersion).To(BeEquivalentTo(tls.VersionTLS13)) // check that the original config wasn't modified From 18c591c75a1022a3754dbbee9e9b40fa3a87e7a4 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 28 Dec 2023 11:49:47 +0700 Subject: [PATCH 132/225] utils: use time.Duration.Abs (#4217) This function was added in Go 1.19, and covers some corner cases that our custom implementation didn't. --- internal/utils/minmax.go | 8 -------- internal/utils/minmax_test.go | 5 ----- internal/utils/rtt_stats.go | 4 ++-- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/internal/utils/minmax.go b/internal/utils/minmax.go index d191f751583..28629c1ae82 100644 --- a/internal/utils/minmax.go +++ b/internal/utils/minmax.go @@ -35,14 +35,6 @@ func MinNonZeroDuration(a, b time.Duration) time.Duration { return Min(a, b) } -// AbsDuration returns the absolute value of a time duration -func AbsDuration(d time.Duration) time.Duration { - if d >= 0 { - return d - } - return -d -} - // MinTime returns the earlier time func MinTime(a, b time.Time) time.Time { if a.After(b) { diff --git a/internal/utils/minmax_test.go b/internal/utils/minmax_test.go index 163134ece41..0d301edb952 100644 --- a/internal/utils/minmax_test.go +++ b/internal/utils/minmax_test.go @@ -50,9 +50,4 @@ var _ = Describe("Min / Max", func() { Expect(MinNonZeroTime(b, b.Add(time.Second))).To(Equal(b)) Expect(MinNonZeroTime(b.Add(time.Second), b)).To(Equal(b)) }) - - It("returns the abs time", func() { - Expect(AbsDuration(time.Microsecond)).To(Equal(time.Microsecond)) - Expect(AbsDuration(-time.Microsecond)).To(Equal(time.Microsecond)) - }) }) diff --git a/internal/utils/rtt_stats.go b/internal/utils/rtt_stats.go index 2cd9a1919b1..89ff3b653c1 100644 --- a/internal/utils/rtt_stats.go +++ b/internal/utils/rtt_stats.go @@ -90,7 +90,7 @@ func (r *RTTStats) UpdateRTT(sendDelta, ackDelay time.Duration, now time.Time) { r.smoothedRTT = sample r.meanDeviation = sample / 2 } else { - r.meanDeviation = time.Duration(oneMinusBeta*float32(r.meanDeviation/time.Microsecond)+rttBeta*float32(AbsDuration(r.smoothedRTT-sample)/time.Microsecond)) * time.Microsecond + r.meanDeviation = time.Duration(oneMinusBeta*float32(r.meanDeviation/time.Microsecond)+rttBeta*float32((r.smoothedRTT-sample).Abs()/time.Microsecond)) * time.Microsecond r.smoothedRTT = time.Duration((float32(r.smoothedRTT/time.Microsecond)*oneMinusAlpha)+(float32(sample/time.Microsecond)*rttAlpha)) * time.Microsecond } } @@ -126,6 +126,6 @@ func (r *RTTStats) OnConnectionMigration() { // is larger. The mean deviation is increased to the most recent deviation if // it's larger. func (r *RTTStats) ExpireSmoothedMetrics() { - r.meanDeviation = Max(r.meanDeviation, AbsDuration(r.smoothedRTT-r.latestRTT)) + r.meanDeviation = Max(r.meanDeviation, (r.smoothedRTT - r.latestRTT).Abs()) r.smoothedRTT = Max(r.smoothedRTT, r.latestRTT) } From 22411e16d568d0213a0a727a87d195ab6e58b6f6 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 28 Dec 2023 12:19:13 +0700 Subject: [PATCH 133/225] utils: switch to standard library min and max functions (#4218) These functions were added in Go 1.21. --- conn_id_generator.go | 3 +-- conn_id_manager.go | 2 +- connection.go | 8 ++++---- crypto_stream.go | 5 ++--- http3/http_stream.go | 3 +-- internal/ackhandler/packet_number_generator.go | 2 +- internal/ackhandler/received_packet_tracker.go | 2 +- internal/ackhandler/sent_packet_handler.go | 14 +++++++------- internal/congestion/cubic.go | 3 +-- internal/congestion/cubic_sender.go | 4 ++-- internal/congestion/hybrid_slow_start.go | 5 ++--- internal/congestion/pacer.go | 7 +++---- internal/flowcontrol/base_flow_controller.go | 2 +- .../flowcontrol/connection_flow_controller.go | 2 +- internal/flowcontrol/stream_flow_controller.go | 2 +- internal/handshake/aead.go | 3 +-- internal/handshake/updatable_aead.go | 2 +- internal/utils/minmax.go | 18 +----------------- internal/utils/minmax_test.go | 10 ---------- internal/utils/rtt_stats.go | 6 +++--- internal/wire/transport_parameters.go | 2 +- mtu_discoverer_test.go | 8 ++++---- send_stream.go | 4 ++-- token_store.go | 5 ++--- 24 files changed, 44 insertions(+), 78 deletions(-) diff --git a/conn_id_generator.go b/conn_id_generator.go index 2d28dc619c3..9cf21d9ae2e 100644 --- a/conn_id_generator.go +++ b/conn_id_generator.go @@ -5,7 +5,6 @@ import ( "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" - "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" ) @@ -60,7 +59,7 @@ func (m *connIDGenerator) SetMaxActiveConnIDs(limit uint64) error { // transport parameter. // We currently don't send the preferred_address transport parameter, // so we can issue (limit - 1) connection IDs. - for i := uint64(len(m.activeSrcConnIDs)); i < utils.Min(limit, protocol.MaxIssuedConnectionIDs); i++ { + for i := uint64(len(m.activeSrcConnIDs)); i < min(limit, protocol.MaxIssuedConnectionIDs); i++ { if err := m.issueNewConnID(); err != nil { return err } diff --git a/conn_id_manager.go b/conn_id_manager.go index ba65aec0438..4aa3f749e0f 100644 --- a/conn_id_manager.go +++ b/conn_id_manager.go @@ -145,7 +145,7 @@ func (h *connIDManager) updateConnectionID() { h.queueControlFrame(&wire.RetireConnectionIDFrame{ SequenceNumber: h.activeSequenceNumber, }) - h.highestRetired = utils.Max(h.highestRetired, h.activeSequenceNumber) + h.highestRetired = max(h.highestRetired, h.activeSequenceNumber) if h.activeStatelessResetToken != nil { h.removeStatelessResetToken(*h.activeStatelessResetToken) } diff --git a/connection.go b/connection.go index b28eb8c1b56..b62f8be5879 100644 --- a/connection.go +++ b/connection.go @@ -681,7 +681,7 @@ func (s *connection) ConnectionState() ConnectionState { // Time when the connection should time out func (s *connection) nextIdleTimeoutTime() time.Time { - idleTimeout := utils.Max(s.idleTimeout, s.rttStats.PTO(true)*3) + idleTimeout := max(s.idleTimeout, s.rttStats.PTO(true)*3) return s.idleTimeoutStartTime().Add(idleTimeout) } @@ -691,7 +691,7 @@ func (s *connection) nextKeepAliveTime() time.Time { if s.config.KeepAlivePeriod == 0 || s.keepAlivePingSent || !s.firstAckElicitingPacketAfterIdleSentTime.IsZero() { return time.Time{} } - keepAliveInterval := utils.Max(s.keepAliveInterval, s.rttStats.PTO(true)*3/2) + keepAliveInterval := max(s.keepAliveInterval, s.rttStats.PTO(true)*3/2) return s.lastPacketReceivedTime.Add(keepAliveInterval) } @@ -780,7 +780,7 @@ func (s *connection) handleHandshakeConfirmed() error { if maxPacketSize == 0 { maxPacketSize = protocol.MaxByteCount } - s.mtuDiscoverer.Start(utils.Min(maxPacketSize, protocol.MaxPacketBufferSize)) + s.mtuDiscoverer.Start(min(maxPacketSize, protocol.MaxPacketBufferSize)) } return nil } @@ -1755,7 +1755,7 @@ func (s *connection) applyTransportParameters() { params := s.peerParams // Our local idle timeout will always be > 0. s.idleTimeout = utils.MinNonZeroDuration(s.config.MaxIdleTimeout, params.MaxIdleTimeout) - s.keepAliveInterval = utils.Min(s.config.KeepAlivePeriod, utils.Min(s.idleTimeout/2, protocol.MaxKeepAliveInterval)) + s.keepAliveInterval = min(s.config.KeepAlivePeriod, min(s.idleTimeout/2, protocol.MaxKeepAliveInterval)) s.streamsMap.UpdateLimits(params) s.frameParser.SetAckDelayExponent(params.AckDelayExponent) s.connFlowController.UpdateSendWindow(params.InitialMaxData) diff --git a/crypto_stream.go b/crypto_stream.go index 4be2a07ae1a..abc7ddcf86c 100644 --- a/crypto_stream.go +++ b/crypto_stream.go @@ -6,7 +6,6 @@ import ( "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" - "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" ) @@ -56,7 +55,7 @@ func (s *cryptoStreamImpl) HandleCryptoFrame(f *wire.CryptoFrame) error { // could e.g. be a retransmission return nil } - s.highestOffset = utils.Max(s.highestOffset, highestOffset) + s.highestOffset = max(s.highestOffset, highestOffset) if err := s.queue.Push(f.Data, f.Offset, nil); err != nil { return err } @@ -99,7 +98,7 @@ func (s *cryptoStreamImpl) HasData() bool { func (s *cryptoStreamImpl) PopCryptoFrame(maxLen protocol.ByteCount) *wire.CryptoFrame { f := &wire.CryptoFrame{Offset: s.writeOffset} - n := utils.Min(f.MaxDataLen(maxLen), protocol.ByteCount(len(s.writeBuf))) + n := min(f.MaxDataLen(maxLen), protocol.ByteCount(len(s.writeBuf))) f.Data = s.writeBuf[:n] s.writeBuf = s.writeBuf[n:] s.writeOffset += n diff --git a/http3/http_stream.go b/http3/http_stream.go index 1c0ec4f1898..bfaf4214d47 100644 --- a/http3/http_stream.go +++ b/http3/http_stream.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/quic-go/quic-go" - "github.com/quic-go/quic-go/internal/utils" ) // A Stream is a HTTP/3 stream. @@ -115,7 +114,7 @@ func (s *lengthLimitedStream) Read(b []byte) (int, error) { if err := s.checkContentLengthViolation(); err != nil { return 0, err } - n, err := s.stream.Read(b[:utils.Min(int64(len(b)), s.contentLength-s.read)]) + n, err := s.stream.Read(b[:min(int64(len(b)), s.contentLength-s.read)]) s.read += int64(n) if err := s.checkContentLengthViolation(); err != nil { return n, err diff --git a/internal/ackhandler/packet_number_generator.go b/internal/ackhandler/packet_number_generator.go index e84171e3cd5..4a9db86356b 100644 --- a/internal/ackhandler/packet_number_generator.go +++ b/internal/ackhandler/packet_number_generator.go @@ -80,5 +80,5 @@ func (p *skippingPacketNumberGenerator) Pop() (bool, protocol.PacketNumber) { func (p *skippingPacketNumberGenerator) generateNewSkip() { // make sure that there are never two consecutive packet numbers that are skipped p.nextToSkip = p.next + 3 + protocol.PacketNumber(p.rng.Int31n(int32(2*p.period))) - p.period = utils.Min(2*p.period, p.maxPeriod) + p.period = min(2*p.period, p.maxPeriod) } diff --git a/internal/ackhandler/received_packet_tracker.go b/internal/ackhandler/received_packet_tracker.go index 8d15d7c18d9..6d8eec4e735 100644 --- a/internal/ackhandler/received_packet_tracker.go +++ b/internal/ackhandler/received_packet_tracker.go @@ -179,7 +179,7 @@ func (h *receivedPacketTracker) GetAckFrame(onlyIfQueued bool) *wire.AckFrame { ack = &wire.AckFrame{} } ack.Reset() - ack.DelayTime = utils.Max(0, now.Sub(h.largestObservedRcvdTime)) + ack.DelayTime = max(0, now.Sub(h.largestObservedRcvdTime)) ack.ECT0 = h.ect0 ack.ECT1 = h.ect1 ack.ECNCE = h.ecnce diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index c8265a78d93..3cef89239c9 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -245,7 +245,7 @@ func (h *sentPacketHandler) SentPacket( pnSpace := h.getPacketNumberSpace(encLevel) if h.logger.Debug() && pnSpace.history.HasOutstandingPackets() { - for p := utils.Max(0, pnSpace.largestSent+1); p < pn; p++ { + for p := max(0, pnSpace.largestSent+1); p < pn; p++ { h.logger.Debugf("Skipping packet number %d", p) } } @@ -336,7 +336,7 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En // don't use the ack delay for Initial and Handshake packets var ackDelay time.Duration if encLevel == protocol.Encryption1RTT { - ackDelay = utils.Min(ack.DelayTime, h.rttStats.MaxAckDelay()) + ackDelay = min(ack.DelayTime, h.rttStats.MaxAckDelay()) } h.rttStats.UpdateRTT(rcvTime.Sub(p.SendTime), ackDelay, rcvTime) if h.logger.Debug() { @@ -354,7 +354,7 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En } } - pnSpace.largestAcked = utils.Max(pnSpace.largestAcked, largestAcked) + pnSpace.largestAcked = max(pnSpace.largestAcked, largestAcked) if err := h.detectLostPackets(rcvTime, encLevel); err != nil { return false, err @@ -446,7 +446,7 @@ func (h *sentPacketHandler) detectAndRemoveAckedPackets(ack *wire.AckFrame, encL for _, p := range h.ackedPackets { if p.LargestAcked != protocol.InvalidPacketNumber && encLevel == protocol.Encryption1RTT { - h.lowestNotConfirmedAcked = utils.Max(h.lowestNotConfirmedAcked, p.LargestAcked+1) + h.lowestNotConfirmedAcked = max(h.lowestNotConfirmedAcked, p.LargestAcked+1) } for _, f := range p.Frames { @@ -607,11 +607,11 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E pnSpace := h.getPacketNumberSpace(encLevel) pnSpace.lossTime = time.Time{} - maxRTT := float64(utils.Max(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT())) + maxRTT := float64(max(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT())) lossDelay := time.Duration(timeThreshold * maxRTT) // Minimum time of granularity before packets are deemed lost. - lossDelay = utils.Max(lossDelay, protocol.TimerGranularity) + lossDelay = max(lossDelay, protocol.TimerGranularity) // Packets sent before this time are deemed lost. lostSendTime := now.Add(-lossDelay) @@ -890,7 +890,7 @@ func (h *sentPacketHandler) ResetForRetry(now time.Time) error { // Otherwise, we don't know which Initial the Retry was sent in response to. if h.ptoCount == 0 { // Don't set the RTT to a value lower than 5ms here. - h.rttStats.UpdateRTT(utils.Max(minRTTAfterRetry, now.Sub(firstPacketSendTime)), 0, now) + h.rttStats.UpdateRTT(max(minRTTAfterRetry, now.Sub(firstPacketSendTime)), 0, now) if h.logger.Debug() { h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation()) } diff --git a/internal/congestion/cubic.go b/internal/congestion/cubic.go index a73cf82aa5e..4e30de650b5 100644 --- a/internal/congestion/cubic.go +++ b/internal/congestion/cubic.go @@ -5,7 +5,6 @@ import ( "time" "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/internal/utils" ) // This cubic implementation is based on the one found in Chromiums's QUIC @@ -187,7 +186,7 @@ func (c *Cubic) CongestionWindowAfterAck( targetCongestionWindow = c.originPointCongestionWindow - deltaCongestionWindow } // Limit the CWND increase to half the acked bytes. - targetCongestionWindow = utils.Min(targetCongestionWindow, currentCongestionWindow+c.ackedBytesCount/2) + targetCongestionWindow = min(targetCongestionWindow, currentCongestionWindow+c.ackedBytesCount/2) // Increase the window by approximately Alpha * 1 MSS of bytes every // time we ack an estimated tcp window of bytes. For small diff --git a/internal/congestion/cubic_sender.go b/internal/congestion/cubic_sender.go index ee558f2d5ab..a1b06ab34d2 100644 --- a/internal/congestion/cubic_sender.go +++ b/internal/congestion/cubic_sender.go @@ -178,7 +178,7 @@ func (c *cubicSender) OnPacketAcked( priorInFlight protocol.ByteCount, eventTime time.Time, ) { - c.largestAckedPacketNumber = utils.Max(ackedPacketNumber, c.largestAckedPacketNumber) + c.largestAckedPacketNumber = max(ackedPacketNumber, c.largestAckedPacketNumber) if c.InRecovery() { return } @@ -246,7 +246,7 @@ func (c *cubicSender) maybeIncreaseCwnd( c.numAckedPackets = 0 } } else { - c.congestionWindow = utils.Min(c.maxCongestionWindow(), c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime)) + c.congestionWindow = min(c.maxCongestionWindow(), c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime)) } } diff --git a/internal/congestion/hybrid_slow_start.go b/internal/congestion/hybrid_slow_start.go index b2f7c908ed1..9679d9e4668 100644 --- a/internal/congestion/hybrid_slow_start.go +++ b/internal/congestion/hybrid_slow_start.go @@ -4,7 +4,6 @@ import ( "time" "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/internal/utils" ) // Note(pwestin): the magic clamping numbers come from the original code in @@ -75,8 +74,8 @@ func (s *HybridSlowStart) ShouldExitSlowStart(latestRTT time.Duration, minRTT ti // Divide minRTT by 8 to get a rtt increase threshold for exiting. minRTTincreaseThresholdUs := int64(minRTT / time.Microsecond >> hybridStartDelayFactorExp) // Ensure the rtt threshold is never less than 2ms or more than 16ms. - minRTTincreaseThresholdUs = utils.Min(minRTTincreaseThresholdUs, hybridStartDelayMaxThresholdUs) - minRTTincreaseThreshold := time.Duration(utils.Max(minRTTincreaseThresholdUs, hybridStartDelayMinThresholdUs)) * time.Microsecond + minRTTincreaseThresholdUs = min(minRTTincreaseThresholdUs, hybridStartDelayMaxThresholdUs) + minRTTincreaseThreshold := time.Duration(max(minRTTincreaseThresholdUs, hybridStartDelayMinThresholdUs)) * time.Microsecond if s.currentMinRTT > (minRTT + minRTTincreaseThreshold) { s.hystartFound = true diff --git a/internal/congestion/pacer.go b/internal/congestion/pacer.go index 94eae8f8ddc..34d3d1d096a 100644 --- a/internal/congestion/pacer.go +++ b/internal/congestion/pacer.go @@ -4,7 +4,6 @@ import ( "time" "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/internal/utils" ) const maxBurstSizePackets = 10 @@ -52,11 +51,11 @@ func (p *pacer) Budget(now time.Time) protocol.ByteCount { if budget < 0 { // protect against overflows budget = protocol.MaxByteCount } - return utils.Min(p.maxBurstSize(), budget) + return min(p.maxBurstSize(), budget) } func (p *pacer) maxBurstSize() protocol.ByteCount { - return utils.Max( + return max( protocol.ByteCount(uint64((protocol.MinPacingDelay+protocol.TimerGranularity).Nanoseconds())*p.adjustedBandwidth())/1e9, maxBurstSizePackets*p.maxDatagramSize, ) @@ -77,7 +76,7 @@ func (p *pacer) TimeUntilSend() time.Time { if diff%bw > 0 { d++ } - return p.lastSentTime.Add(utils.Max(protocol.MinPacingDelay, time.Duration(d)*time.Nanosecond)) + return p.lastSentTime.Add(max(protocol.MinPacingDelay, time.Duration(d)*time.Nanosecond)) } func (p *pacer) SetMaxDatagramSize(s protocol.ByteCount) { diff --git a/internal/flowcontrol/base_flow_controller.go b/internal/flowcontrol/base_flow_controller.go index f3f24a60edd..184aad343b7 100644 --- a/internal/flowcontrol/base_flow_controller.go +++ b/internal/flowcontrol/base_flow_controller.go @@ -107,7 +107,7 @@ func (c *baseFlowController) maybeAdjustWindowSize() { now := time.Now() if now.Sub(c.epochStartTime) < time.Duration(4*fraction*float64(rtt)) { // window is consumed too fast, try to increase the window size - newSize := utils.Min(2*c.receiveWindowSize, c.maxReceiveWindowSize) + newSize := min(2*c.receiveWindowSize, c.maxReceiveWindowSize) if newSize > c.receiveWindowSize && (c.allowWindowIncrease == nil || c.allowWindowIncrease(newSize-c.receiveWindowSize)) { c.receiveWindowSize = newSize } diff --git a/internal/flowcontrol/connection_flow_controller.go b/internal/flowcontrol/connection_flow_controller.go index 13e69d6c437..8504cdcf529 100644 --- a/internal/flowcontrol/connection_flow_controller.go +++ b/internal/flowcontrol/connection_flow_controller.go @@ -87,7 +87,7 @@ func (c *connectionFlowController) EnsureMinimumWindowSize(inc protocol.ByteCoun c.mutex.Lock() if inc > c.receiveWindowSize { c.logger.Debugf("Increasing receive flow control window for the connection to %d kB, in response to stream flow control window increase", c.receiveWindowSize/(1<<10)) - newSize := utils.Min(inc, c.maxReceiveWindowSize) + newSize := min(inc, c.maxReceiveWindowSize) if delta := newSize - c.receiveWindowSize; delta > 0 && c.allowWindowIncrease(delta) { c.receiveWindowSize = newSize } diff --git a/internal/flowcontrol/stream_flow_controller.go b/internal/flowcontrol/stream_flow_controller.go index 1770a9c8487..1a69fb2b31c 100644 --- a/internal/flowcontrol/stream_flow_controller.go +++ b/internal/flowcontrol/stream_flow_controller.go @@ -123,7 +123,7 @@ func (c *streamFlowController) AddBytesSent(n protocol.ByteCount) { } func (c *streamFlowController) SendWindowSize() protocol.ByteCount { - return utils.Min(c.baseFlowController.sendWindowSize(), c.connection.SendWindowSize()) + return min(c.baseFlowController.sendWindowSize(), c.connection.SendWindowSize()) } func (c *streamFlowController) shouldQueueWindowUpdate() bool { diff --git a/internal/handshake/aead.go b/internal/handshake/aead.go index 6aa89fb3f3e..6ab267a30f9 100644 --- a/internal/handshake/aead.go +++ b/internal/handshake/aead.go @@ -5,7 +5,6 @@ import ( "encoding/binary" "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/internal/utils" ) func createAEAD(suite *cipherSuite, trafficSecret []byte, v protocol.VersionNumber) cipher.AEAD { @@ -82,7 +81,7 @@ func (o *longHeaderOpener) Open(dst, src []byte, pn protocol.PacketNumber, ad [] // It uses the nonce provided here and XOR it with the IV. dec, err := o.aead.Open(dst, o.nonceBuf, src, ad) if err == nil { - o.highestRcvdPN = utils.Max(o.highestRcvdPN, pn) + o.highestRcvdPN = max(o.highestRcvdPN, pn) } else { err = ErrDecryptionFailed } diff --git a/internal/handshake/updatable_aead.go b/internal/handshake/updatable_aead.go index a583f27732d..08b943f4af3 100644 --- a/internal/handshake/updatable_aead.go +++ b/internal/handshake/updatable_aead.go @@ -172,7 +172,7 @@ func (a *updatableAEAD) Open(dst, src []byte, rcvTime time.Time, pn protocol.Pac } } if err == nil { - a.highestRcvdPN = utils.Max(a.highestRcvdPN, pn) + a.highestRcvdPN = max(a.highestRcvdPN, pn) } return dec, err } diff --git a/internal/utils/minmax.go b/internal/utils/minmax.go index 28629c1ae82..6884ef40b31 100644 --- a/internal/utils/minmax.go +++ b/internal/utils/minmax.go @@ -3,27 +3,11 @@ package utils import ( "math" "time" - - "golang.org/x/exp/constraints" ) // InfDuration is a duration of infinite length const InfDuration = time.Duration(math.MaxInt64) -func Max[T constraints.Ordered](a, b T) T { - if a < b { - return b - } - return a -} - -func Min[T constraints.Ordered](a, b T) T { - if a < b { - return a - } - return b -} - // MinNonZeroDuration return the minimum duration that's not zero. func MinNonZeroDuration(a, b time.Duration) time.Duration { if a == 0 { @@ -32,7 +16,7 @@ func MinNonZeroDuration(a, b time.Duration) time.Duration { if b == 0 { return a } - return Min(a, b) + return min(a, b) } // MinTime returns the earlier time diff --git a/internal/utils/minmax_test.go b/internal/utils/minmax_test.go index 0d301edb952..c480219c051 100644 --- a/internal/utils/minmax_test.go +++ b/internal/utils/minmax_test.go @@ -8,16 +8,6 @@ import ( ) var _ = Describe("Min / Max", func() { - It("returns the maximum", func() { - Expect(Max(5, 7)).To(Equal(7)) - Expect(Max(5.5, 5.7)).To(Equal(5.7)) - }) - - It("returns the minimum", func() { - Expect(Min(5, 7)).To(Equal(5)) - Expect(Min(5.5, 5.7)).To(Equal(5.5)) - }) - It("returns the maximum time", func() { a := time.Now() b := a.Add(time.Second) diff --git a/internal/utils/rtt_stats.go b/internal/utils/rtt_stats.go index 89ff3b653c1..463b95424f5 100644 --- a/internal/utils/rtt_stats.go +++ b/internal/utils/rtt_stats.go @@ -55,7 +55,7 @@ func (r *RTTStats) PTO(includeMaxAckDelay bool) time.Duration { if r.SmoothedRTT() == 0 { return 2 * defaultInitialRTT } - pto := r.SmoothedRTT() + Max(4*r.MeanDeviation(), protocol.TimerGranularity) + pto := r.SmoothedRTT() + max(4*r.MeanDeviation(), protocol.TimerGranularity) if includeMaxAckDelay { pto += r.MaxAckDelay() } @@ -126,6 +126,6 @@ func (r *RTTStats) OnConnectionMigration() { // is larger. The mean deviation is increased to the most recent deviation if // it's larger. func (r *RTTStats) ExpireSmoothedMetrics() { - r.meanDeviation = Max(r.meanDeviation, (r.smoothedRTT - r.latestRTT).Abs()) - r.smoothedRTT = Max(r.smoothedRTT, r.latestRTT) + r.meanDeviation = max(r.meanDeviation, (r.smoothedRTT - r.latestRTT).Abs()) + r.smoothedRTT = max(r.smoothedRTT, r.latestRTT) } diff --git a/internal/wire/transport_parameters.go b/internal/wire/transport_parameters.go index 7226521b05a..104142a007c 100644 --- a/internal/wire/transport_parameters.go +++ b/internal/wire/transport_parameters.go @@ -294,7 +294,7 @@ func (p *TransportParameters) readNumericTransportParameter( return fmt.Errorf("initial_max_streams_uni too large: %d (maximum %d)", p.MaxUniStreamNum, protocol.MaxStreamCount) } case maxIdleTimeoutParameterID: - p.MaxIdleTimeout = utils.Max(protocol.MinRemoteIdleTimeout, time.Duration(val)*time.Millisecond) + p.MaxIdleTimeout = max(protocol.MinRemoteIdleTimeout, time.Duration(val)*time.Millisecond) case maxUDPPayloadSizeParameterID: if val < 1200 { return fmt.Errorf("invalid value for max_packet_size: %d (minimum 1200)", val) diff --git a/mtu_discoverer_test.go b/mtu_discoverer_test.go index 6e01f570b47..9e2e7c64913 100644 --- a/mtu_discoverer_test.go +++ b/mtu_discoverer_test.go @@ -88,12 +88,12 @@ var _ = Describe("MTU Discoverer", func() { const rep = 3000 var maxDiff protocol.ByteCount for i := 0; i < rep; i++ { - max := protocol.ByteCount(rand.Intn(int(3000-startMTU))) + startMTU + 1 + maxMTU := protocol.ByteCount(rand.Intn(int(3000-startMTU))) + startMTU + 1 currentMTU := startMTU d := newMTUDiscoverer(rttStats, startMTU, func(s protocol.ByteCount) { currentMTU = s }) - d.Start(max) + d.Start(maxMTU) now := time.Now() - realMTU := protocol.ByteCount(rand.Intn(int(max-startMTU))) + startMTU + realMTU := protocol.ByteCount(rand.Intn(int(maxMTU-startMTU))) + startMTU t := now.Add(mtuProbeDelay * rtt) var count int for d.ShouldSendProbe(t) { @@ -112,7 +112,7 @@ var _ = Describe("MTU Discoverer", func() { } diff := realMTU - currentMTU Expect(diff).To(BeNumerically(">=", 0)) - maxDiff = utils.Max(maxDiff, diff) + maxDiff = max(maxDiff, diff) } Expect(maxDiff).To(BeEquivalentTo(maxMTUDiff)) }) diff --git a/send_stream.go b/send_stream.go index 4113d9f0c15..070456b88e0 100644 --- a/send_stream.go +++ b/send_stream.go @@ -274,7 +274,7 @@ func (s *sendStream) popNewStreamFrame(maxBytes, sendWindow protocol.ByteCount, nextFrame := s.nextFrame s.nextFrame = nil - maxDataLen := utils.Min(sendWindow, nextFrame.MaxDataLen(maxBytes, v)) + maxDataLen := min(sendWindow, nextFrame.MaxDataLen(maxBytes, v)) if nextFrame.DataLen() > maxDataLen { s.nextFrame = wire.GetStreamFrame() s.nextFrame.StreamID = s.streamID @@ -309,7 +309,7 @@ func (s *sendStream) popNewStreamFrameWithoutBuffer(f *wire.StreamFrame, maxByte if maxDataLen == 0 { // a STREAM frame must have at least one byte of data return s.dataForWriting != nil || s.nextFrame != nil || s.finishedWriting } - s.getDataForWriting(f, utils.Min(maxDataLen, sendWindow)) + s.getDataForWriting(f, min(maxDataLen, sendWindow)) return s.dataForWriting != nil || s.nextFrame != nil || s.finishedWriting } diff --git a/token_store.go b/token_store.go index 00460e50285..a5c1c1852f3 100644 --- a/token_store.go +++ b/token_store.go @@ -3,7 +3,6 @@ package quic import ( "sync" - "github.com/quic-go/quic-go/internal/utils" list "github.com/quic-go/quic-go/internal/utils/linkedlist" ) @@ -20,14 +19,14 @@ func newSingleOriginTokenStore(size int) *singleOriginTokenStore { func (s *singleOriginTokenStore) Add(token *ClientToken) { s.tokens[s.p] = token s.p = s.index(s.p + 1) - s.len = utils.Min(s.len+1, len(s.tokens)) + s.len = min(s.len+1, len(s.tokens)) } func (s *singleOriginTokenStore) Pop() *ClientToken { s.p = s.index(s.p - 1) token := s.tokens[s.p] s.tokens[s.p] = nil - s.len = utils.Max(s.len-1, 0) + s.len = max(s.len-1, 0) return token } From a937959fbf67a2affa5b07f33c09f3894dd407aa Mon Sep 17 00:00:00 2001 From: Vladimir Varankin Date: Fri, 29 Dec 2023 03:35:46 +0100 Subject: [PATCH 134/225] http3: fix channel size in ListenAndServe (#4219) * http3: typo in ListenAndServe docs Also, partially prevent a goroutine leak on an error from one of the listeners. * http3: improve documentation for ListenAndServe --------- Co-authored-by: Marten Seemann --- http3/server.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/http3/server.go b/http3/server.go index 2711394a7f8..ca586f0dee3 100644 --- a/http3/server.go +++ b/http3/server.go @@ -723,7 +723,7 @@ func ListenAndServeQUIC(addr, certFile, keyFile string, handler http.Handler) er return server.ListenAndServeTLS(certFile, keyFile) } -// ListenAndServe listens on the given network address for both, TLS and QUIC +// ListenAndServe listens on the given network address for both TLS/TCP and QUIC // connections in parallel. It returns if one of the two returns an error. // http.DefaultServeMux is used when handler is nil. // The correct Alt-Svc headers for QUIC are set. @@ -765,8 +765,8 @@ func ListenAndServe(addr, certFile, keyFile string, handler http.Handler) error Handler: handler, } - hErr := make(chan error) - qErr := make(chan error) + hErr := make(chan error, 1) + qErr := make(chan error, 1) go func() { hErr <- http.ListenAndServeTLS(addr, certFile, keyFile, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { quicServer.SetQuicHeaders(w.Header()) From d6e3f3229fa6bb00a630bc3600fe49c7cb850770 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 29 Dec 2023 09:59:56 +0700 Subject: [PATCH 135/225] qtls: remove unneeded type alias for the tls.QUICEncryptionLevel (#4220) * qtls: remove unneeded type alias for the tls.QUICEncryptionLevel * handshake: make cryptoSetup.WriteRecord private --- internal/handshake/crypto_setup.go | 14 +++++++------- internal/qtls/qtls.go | 11 ----------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index 9223a6294b0..1e1874a57c9 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -283,7 +283,7 @@ func (h *cryptoSetup) handleEvent(ev tls.QUICEvent) (done bool, err error) { h.rejected0RTT() return false, nil case tls.QUICWriteData: - h.WriteRecord(ev.Level, ev.Data) + h.writeRecord(ev.Level, ev.Data) return false, nil case tls.QUICHandshakeDone: h.handshakeComplete() @@ -490,7 +490,7 @@ func (h *cryptoSetup) SetWriteKey(el tls.QUICEncryptionLevel, suiteID uint16, tr h.mutex.Lock() //nolint:exhaustive // The TLS stack doesn't export Initial keys. switch el { - case qtls.QUICEncryptionLevelEarly: + case tls.QUICEncryptionLevelEarly: if h.perspective == protocol.PerspectiveServer { panic("Received 0-RTT write key for the server") } @@ -539,15 +539,15 @@ func (h *cryptoSetup) SetWriteKey(el tls.QUICEncryptionLevel, suiteID uint16, tr } } -// WriteRecord is called when TLS writes data -func (h *cryptoSetup) WriteRecord(encLevel qtls.QUICEncryptionLevel, p []byte) { +// writeRecord is called when TLS writes data +func (h *cryptoSetup) writeRecord(encLevel tls.QUICEncryptionLevel, p []byte) { //nolint:exhaustive // handshake records can only be written for Initial and Handshake. switch encLevel { - case qtls.QUICEncryptionLevelInitial: + case tls.QUICEncryptionLevelInitial: h.events = append(h.events, Event{Kind: EventWriteInitialData, Data: p}) - case qtls.QUICEncryptionLevelHandshake: + case tls.QUICEncryptionLevelHandshake: h.events = append(h.events, Event{Kind: EventWriteHandshakeData, Data: p}) - case qtls.QUICEncryptionLevelApplication: + case tls.QUICEncryptionLevelApplication: panic("unexpected write") default: panic(fmt.Sprintf("unexpected write encryption level: %s", encLevel)) diff --git a/internal/qtls/qtls.go b/internal/qtls/qtls.go index 742dd3c9bb3..ebcd9d4dedf 100644 --- a/internal/qtls/qtls.go +++ b/internal/qtls/qtls.go @@ -8,17 +8,6 @@ import ( "github.com/quic-go/quic-go/internal/protocol" ) -type ( - QUICEncryptionLevel = tls.QUICEncryptionLevel -) - -const ( - QUICEncryptionLevelInitial = tls.QUICEncryptionLevelInitial - QUICEncryptionLevelEarly = tls.QUICEncryptionLevelEarly - QUICEncryptionLevelHandshake = tls.QUICEncryptionLevelHandshake - QUICEncryptionLevelApplication = tls.QUICEncryptionLevelApplication -) - func SetupConfigForServer(qconf *tls.QUICConfig, _ bool, getData func() []byte, handleSessionTicket func([]byte, bool) bool) { conf := qconf.TLSConfig From 7f080dd54bd94d7cb822dba722b3e59f3693d69c Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 1 Jan 2024 10:17:25 +0700 Subject: [PATCH 136/225] discard DATAGRAM frames that don't fit into packets without an ACK (#4221) If the packet doesn't contain an ACK (i.e. the payload is empty), there's no point retrying to pack it later. It's extremely unlikely that the available packet size will suddenly increase. --- interface.go | 8 ++++++-- packet_packer.go | 8 +++++++- packet_packer_test.go | 39 ++++++++++++++++++++++++++++----------- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/interface.go b/interface.go index da0e5e2b31b..b269d790ef0 100644 --- a/interface.go +++ b/interface.go @@ -187,8 +187,12 @@ type Connection interface { // Warning: This API should not be considered stable and might change soon. ConnectionState() ConnectionState - // SendDatagram sends a message as a datagram, as specified in RFC 9221. - SendDatagram([]byte) error + // SendDatagram sends a message using a QUIC datagram, as specified in RFC 9221. + // There is no delivery guarantee for DATAGRAM frames, they are not retransmitted if lost. + // The payload of the datagram needs to fit into a single QUIC packet. + // In addition, a datagram may be dropped before being sent out if the available packet size suddenly decreases. + // If the payload is too large to be sent at the current time, a DatagramTooLargeError is returned. + SendDatagram(payload []byte) error // ReceiveDatagram gets a message received in a datagram, as specified in RFC 9221. ReceiveDatagram(context.Context) ([]byte, error) } diff --git a/packet_packer.go b/packet_packer.go index a330632bee6..9a97295264e 100644 --- a/packet_packer.go +++ b/packet_packer.go @@ -606,11 +606,17 @@ func (p *packetPacker) composeNextPacket(maxFrameSize protocol.ByteCount, onlyAc if p.datagramQueue != nil { if f := p.datagramQueue.Peek(); f != nil { size := f.Length(v) - if size <= maxFrameSize-pl.length { + if size <= maxFrameSize-pl.length { // DATAGRAM frame fits pl.frames = append(pl.frames, ackhandler.Frame{Frame: f}) pl.length += size p.datagramQueue.Pop() + } else if !hasAck { + // The DATAGRAM frame doesn't fit, and the packet doesn't contain an ACK. + // Discard this frame. There's no point in retrying this in the next packet, + // as it's unlikely that the available packet size will increase. + p.datagramQueue.Pop() } + // If the DATAGRAM frame was too large and the packet contained an ACK, we'll try to send it out later. } } diff --git a/packet_packer_test.go b/packet_packer_test.go index fe746e631c9..677760adc77 100644 --- a/packet_packer_test.go +++ b/packet_packer_test.go @@ -516,7 +516,6 @@ var _ = Describe("Packet packer", func() { buffer.Data = append(buffer.Data, []byte("foobar")...) p, err := packer.AppendPacket(buffer, maxPacketSize, protocol.Version1) Expect(err).ToNot(HaveOccurred()) - Expect(p).ToNot(BeNil()) b, err := f.Append(nil, protocol.Version1) Expect(err).ToNot(HaveOccurred()) Expect(p.Frames).To(BeEmpty()) @@ -535,7 +534,6 @@ var _ = Describe("Packet packer", func() { sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil) p, err := packer.AppendPacket(getPacketBuffer(), maxPacketSize, protocol.Version1) Expect(err).NotTo(HaveOccurred()) - Expect(p).ToNot(BeNil()) Expect(p.Ack).To(Equal(ack)) }) @@ -553,7 +551,6 @@ var _ = Describe("Packet packer", func() { expectAppendStreamFrames() buffer := getPacketBuffer() p, err := packer.AppendPacket(buffer, maxPacketSize, protocol.Version1) - Expect(p).ToNot(BeNil()) Expect(err).ToNot(HaveOccurred()) Expect(p.Frames).To(HaveLen(2)) for i, f := range p.Frames { @@ -577,7 +574,6 @@ var _ = Describe("Packet packer", func() { expectAppendStreamFrames() buffer := getPacketBuffer() p, err := packer.AppendPacket(buffer, maxPacketSize, protocol.Version1) - Expect(p).ToNot(BeNil()) Expect(err).ToNot(HaveOccurred()) Expect(p.Frames).To(HaveLen(3)) for i, f := range p.Frames { @@ -614,7 +610,6 @@ var _ = Describe("Packet packer", func() { framer.EXPECT().HasData() buffer := getPacketBuffer() p, err := packer.AppendPacket(buffer, maxPacketSize, protocol.Version1) - Expect(p).ToNot(BeNil()) Expect(err).ToNot(HaveOccurred()) Expect(p.Frames).To(HaveLen(1)) Expect(p.Frames[0].Frame).To(Equal(f)) @@ -643,15 +638,42 @@ var _ = Describe("Packet packer", func() { framer.EXPECT().HasData() buffer := getPacketBuffer() p, err := packer.AppendPacket(buffer, maxPacketSize, protocol.Version1) - Expect(p).ToNot(BeNil()) Expect(err).ToNot(HaveOccurred()) Expect(p.Ack).ToNot(BeNil()) Expect(p.Frames).To(BeEmpty()) Expect(buffer.Data).ToNot(BeEmpty()) + Expect(datagramQueue.Peek()).To(Equal(f)) // make sure the frame is still there datagramQueue.CloseWithError(nil) Eventually(done).Should(BeClosed()) }) + It("discards a DATAGRAM frame if it doesn't fit into a packet that doesn't contain an ACK", func() { + ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT, true) + pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2) + sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil) + f := &wire.DatagramFrame{ + DataLenPresent: true, + Data: make([]byte, maxPacketSize+10), // won't fit + } + done := make(chan struct{}) + go func() { + defer GinkgoRecover() + defer close(done) + datagramQueue.AddAndWait(f) + }() + // make sure the DATAGRAM has actually been queued + time.Sleep(scaleDuration(20 * time.Millisecond)) + + framer.EXPECT().HasData() + buffer := getPacketBuffer() + p, err := packer.AppendPacket(buffer, maxPacketSize, protocol.Version1) + Expect(err).To(MatchError(errNothingToPack)) + Expect(p.Frames).To(BeEmpty()) + Expect(p.Ack).To(BeNil()) + Expect(datagramQueue.Peek()).To(BeNil()) + Eventually(done).Should(BeClosed()) + }) + It("accounts for the space consumed by control frames", func() { pnManager.EXPECT().PeekPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2) sealingManager.EXPECT().Get1RTTSealer().Return(getSealer(), nil) @@ -777,7 +799,6 @@ var _ = Describe("Packet packer", func() { expectAppendControlFrames() expectAppendStreamFrames(ackhandler.StreamFrame{Frame: f1}, ackhandler.StreamFrame{Frame: f2}, ackhandler.StreamFrame{Frame: f3}) p, err := packer.AppendPacket(getPacketBuffer(), maxPacketSize, protocol.Version1) - Expect(p).ToNot(BeNil()) Expect(err).ToNot(HaveOccurred()) Expect(p.Frames).To(BeEmpty()) Expect(p.StreamFrames).To(HaveLen(3)) @@ -797,7 +818,6 @@ var _ = Describe("Packet packer", func() { expectAppendControlFrames() expectAppendStreamFrames() p, err := packer.AppendPacket(getPacketBuffer(), maxPacketSize, protocol.Version1) - Expect(p).ToNot(BeNil()) Expect(err).ToNot(HaveOccurred()) Expect(p.Ack).ToNot(BeNil()) Expect(p.Frames).To(BeEmpty()) @@ -814,7 +834,6 @@ var _ = Describe("Packet packer", func() { expectAppendControlFrames() expectAppendStreamFrames() p, err := packer.AppendPacket(getPacketBuffer(), maxPacketSize, protocol.Version1) - Expect(p).ToNot(BeNil()) Expect(err).ToNot(HaveOccurred()) var hasPing bool for _, f := range p.Frames { @@ -833,7 +852,6 @@ var _ = Describe("Packet packer", func() { expectAppendControlFrames() expectAppendStreamFrames() p, err = packer.AppendPacket(getPacketBuffer(), maxPacketSize, protocol.Version1) - Expect(p).ToNot(BeNil()) Expect(err).ToNot(HaveOccurred()) Expect(p.Ack).ToNot(BeNil()) Expect(p.Frames).To(BeEmpty()) @@ -883,7 +901,6 @@ var _ = Describe("Packet packer", func() { expectAppendControlFrames(ackhandler.Frame{Frame: &wire.MaxDataFrame{}}) p, err := packer.AppendPacket(getPacketBuffer(), maxPacketSize, protocol.Version1) Expect(err).ToNot(HaveOccurred()) - Expect(p).ToNot(BeNil()) Expect(p.Frames).ToNot(ContainElement(&wire.PingFrame{})) }) }) From 1fce81f8bb79e573a4b3fa00b5fbf846f6842599 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 1 Jan 2024 10:58:41 +0700 Subject: [PATCH 137/225] queue up to 32 DATAGRAM frames to send (#4222) --- connection.go | 2 +- datagram_queue.go | 87 +++++++++++++++++++++---------------- datagram_queue_test.go | 59 +++++++++++++++---------- internal/protocol/params.go | 3 -- packet_packer_test.go | 6 +-- 5 files changed, 89 insertions(+), 68 deletions(-) diff --git a/connection.go b/connection.go index b62f8be5879..082e95d72b0 100644 --- a/connection.go +++ b/connection.go @@ -2359,7 +2359,7 @@ func (s *connection) SendDatagram(p []byte) error { } f.Data = make([]byte, len(p)) copy(f.Data, p) - return s.datagramQueue.AddAndWait(f) + return s.datagramQueue.Add(f) } func (s *connection) ReceiveDatagram(ctx context.Context) ([]byte, error) { diff --git a/datagram_queue.go b/datagram_queue.go index ca80d404cbf..43026b25022 100644 --- a/datagram_queue.go +++ b/datagram_queue.go @@ -4,14 +4,19 @@ import ( "context" "sync" - "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" ) +const ( + maxDatagramSendQueueLen = 32 + maxDatagramRcvQueueLen = 128 +) + type datagramQueue struct { - sendQueue chan *wire.DatagramFrame - nextFrame *wire.DatagramFrame + sendMx sync.Mutex + sendQueue []*wire.DatagramFrame // TODO: this could be a ring buffer + sent chan struct{} // used to notify Add that a datagram was dequeued rcvMx sync.Mutex rcvQueue [][]byte @@ -22,60 +27,68 @@ type datagramQueue struct { hasData func() - dequeued chan struct{} - logger utils.Logger } func newDatagramQueue(hasData func(), logger utils.Logger) *datagramQueue { return &datagramQueue{ - hasData: hasData, - sendQueue: make(chan *wire.DatagramFrame, 1), - rcvd: make(chan struct{}, 1), - dequeued: make(chan struct{}), - closed: make(chan struct{}), - logger: logger, + hasData: hasData, + rcvd: make(chan struct{}, 1), + sent: make(chan struct{}, 1), + closed: make(chan struct{}), + logger: logger, } } -// AddAndWait queues a new DATAGRAM frame for sending. -// It blocks until the frame has been dequeued. -func (h *datagramQueue) AddAndWait(f *wire.DatagramFrame) error { - select { - case h.sendQueue <- f: - h.hasData() - case <-h.closed: - return h.closeErr - } +// Add queues a new DATAGRAM frame for sending. +// Up to 32 DATAGRAM frames will be queued. +// Once that limit is reached, Add blocks until the queue size has reduced. +func (h *datagramQueue) Add(f *wire.DatagramFrame) error { + h.sendMx.Lock() - select { - case <-h.dequeued: - return nil - case <-h.closed: - return h.closeErr + for { + if len(h.sendQueue) < maxDatagramSendQueueLen { + h.sendQueue = append(h.sendQueue, f) + h.sendMx.Unlock() + h.hasData() + return nil + } + select { + case <-h.sent: // drain the queue so we don't loop immediately + default: + } + h.sendMx.Unlock() + select { + case <-h.closed: + return h.closeErr + case <-h.sent: + } + h.sendMx.Lock() } } // Peek gets the next DATAGRAM frame for sending. // If actually sent out, Pop needs to be called before the next call to Peek. func (h *datagramQueue) Peek() *wire.DatagramFrame { - if h.nextFrame != nil { - return h.nextFrame - } - select { - case h.nextFrame = <-h.sendQueue: - h.dequeued <- struct{}{} - default: + h.sendMx.Lock() + defer h.sendMx.Unlock() + if len(h.sendQueue) == 0 { return nil } - return h.nextFrame + return h.sendQueue[0] } func (h *datagramQueue) Pop() { - if h.nextFrame == nil { + h.sendMx.Lock() + defer h.sendMx.Unlock() + if len(h.sendQueue) == 0 { panic("datagramQueue BUG: Pop called for nil frame") } - h.nextFrame = nil + h.sendQueue = h.sendQueue[1:] + select { + case h.sent <- struct{}{}: + default: + } } // HandleDatagramFrame handles a received DATAGRAM frame. @@ -84,7 +97,7 @@ func (h *datagramQueue) HandleDatagramFrame(f *wire.DatagramFrame) { copy(data, f.Data) var queued bool h.rcvMx.Lock() - if len(h.rcvQueue) < protocol.DatagramRcvQueueLen { + if len(h.rcvQueue) < maxDatagramRcvQueueLen { h.rcvQueue = append(h.rcvQueue, data) queued = true select { @@ -94,7 +107,7 @@ func (h *datagramQueue) HandleDatagramFrame(f *wire.DatagramFrame) { } h.rcvMx.Unlock() if !queued && h.logger.Debug() { - h.logger.Debugf("Discarding DATAGRAM frame (%d bytes payload)", len(f.Data)) + h.logger.Debugf("Discarding received DATAGRAM frame (%d bytes payload)", len(f.Data)) } } diff --git a/datagram_queue_test.go b/datagram_queue_test.go index de3f8f57bf3..fe8db59fdae 100644 --- a/datagram_queue_test.go +++ b/datagram_queue_test.go @@ -3,6 +3,7 @@ package quic import ( "context" "errors" + "time" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" @@ -26,55 +27,65 @@ var _ = Describe("Datagram Queue", func() { }) It("queues a datagram", func() { - done := make(chan struct{}) frame := &wire.DatagramFrame{Data: []byte("foobar")} - go func() { - defer GinkgoRecover() - defer close(done) - Expect(queue.AddAndWait(frame)).To(Succeed()) - }() - - Eventually(queued).Should(HaveLen(1)) - Consistently(done).ShouldNot(BeClosed()) + Expect(queue.Add(frame)).To(Succeed()) + Expect(queued).To(HaveLen(1)) f := queue.Peek() Expect(f.Data).To(Equal([]byte("foobar"))) - Eventually(done).Should(BeClosed()) queue.Pop() Expect(queue.Peek()).To(BeNil()) }) - It("returns the same datagram multiple times, when Pop isn't called", func() { - sent := make(chan struct{}, 1) + It("blocks when the maximum number of datagrams have been queued", func() { + for i := 0; i < maxDatagramSendQueueLen; i++ { + Expect(queue.Add(&wire.DatagramFrame{Data: []byte{0}})).To(Succeed()) + } + errChan := make(chan error, 1) go func() { defer GinkgoRecover() - Expect(queue.AddAndWait(&wire.DatagramFrame{Data: []byte("foo")})).To(Succeed()) - sent <- struct{}{} - Expect(queue.AddAndWait(&wire.DatagramFrame{Data: []byte("bar")})).To(Succeed()) - sent <- struct{}{} + errChan <- queue.Add(&wire.DatagramFrame{Data: []byte("foobar")}) }() + Consistently(errChan, 50*time.Millisecond).ShouldNot(Receive()) + Expect(queue.Peek()).ToNot(BeNil()) + Consistently(errChan, 50*time.Millisecond).ShouldNot(Receive()) + queue.Pop() + Eventually(errChan).Should(Receive(BeNil())) + for i := 1; i < maxDatagramSendQueueLen; i++ { + queue.Pop() + } + f := queue.Peek() + Expect(f).ToNot(BeNil()) + Expect(f.Data).To(Equal([]byte("foobar"))) + }) + + It("returns the same datagram multiple times, when Pop isn't called", func() { + Expect(queue.Add(&wire.DatagramFrame{Data: []byte("foo")})).To(Succeed()) + Expect(queue.Add(&wire.DatagramFrame{Data: []byte("bar")})).To(Succeed()) - Eventually(queued).Should(HaveLen(1)) + Eventually(queued).Should(HaveLen(2)) f := queue.Peek() Expect(f.Data).To(Equal([]byte("foo"))) - Eventually(sent).Should(Receive()) Expect(queue.Peek()).To(Equal(f)) Expect(queue.Peek()).To(Equal(f)) queue.Pop() - Eventually(func() *wire.DatagramFrame { f = queue.Peek(); return f }).ShouldNot(BeNil()) f = queue.Peek() + Expect(f).ToNot(BeNil()) Expect(f.Data).To(Equal([]byte("bar"))) }) It("closes", func() { + for i := 0; i < maxDatagramSendQueueLen; i++ { + Expect(queue.Add(&wire.DatagramFrame{Data: []byte("foo")})).To(Succeed()) + } errChan := make(chan error, 1) go func() { defer GinkgoRecover() - errChan <- queue.AddAndWait(&wire.DatagramFrame{Data: []byte("foobar")}) + errChan <- queue.Add(&wire.DatagramFrame{Data: []byte("foo")}) }() - - Consistently(errChan).ShouldNot(Receive()) - queue.CloseWithError(errors.New("test error")) - Eventually(errChan).Should(Receive(MatchError("test error"))) + Consistently(errChan, 25*time.Millisecond).ShouldNot(Receive()) + testErr := errors.New("test error") + queue.CloseWithError(testErr) + Eventually(errChan).Should(Receive(MatchError(testErr))) }) }) diff --git a/internal/protocol/params.go b/internal/protocol/params.go index 28b6da7cdd4..487cbc06bff 100644 --- a/internal/protocol/params.go +++ b/internal/protocol/params.go @@ -129,9 +129,6 @@ const MaxPostHandshakeCryptoFrameSize = 1000 // but must ensure that a maximum size ACK frame fits into one packet. const MaxAckFrameSize ByteCount = 1000 -// DatagramRcvQueueLen is the length of the receive queue for DATAGRAM frames (RFC 9221) -const DatagramRcvQueueLen = 128 - // MaxNumAckRanges is the maximum number of ACK ranges that we send in an ACK frame. // It also serves as a limit for the packet history. // If at any point we keep track of more ranges, old ranges are discarded. diff --git a/packet_packer_test.go b/packet_packer_test.go index 677760adc77..5b227b7328d 100644 --- a/packet_packer_test.go +++ b/packet_packer_test.go @@ -602,7 +602,7 @@ var _ = Describe("Packet packer", func() { go func() { defer GinkgoRecover() defer close(done) - datagramQueue.AddAndWait(f) + datagramQueue.Add(f) }() // make sure the DATAGRAM has actually been queued time.Sleep(scaleDuration(20 * time.Millisecond)) @@ -630,7 +630,7 @@ var _ = Describe("Packet packer", func() { go func() { defer GinkgoRecover() defer close(done) - datagramQueue.AddAndWait(f) + datagramQueue.Add(f) }() // make sure the DATAGRAM has actually been queued time.Sleep(scaleDuration(20 * time.Millisecond)) @@ -659,7 +659,7 @@ var _ = Describe("Packet packer", func() { go func() { defer GinkgoRecover() defer close(done) - datagramQueue.AddAndWait(f) + datagramQueue.Add(f) }() // make sure the DATAGRAM has actually been queued time.Sleep(scaleDuration(20 * time.Millisecond)) From 22b7f7744eb6f3274390a1cb3fe85ca5387be759 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 1 Jan 2024 11:50:26 +0700 Subject: [PATCH 138/225] use a ring buffer for the datagram queue (#4223) --- datagram_queue.go | 18 ++++++++---------- internal/utils/ringbuffer/ringbuffer.go | 12 +++++++++++- internal/utils/ringbuffer/ringbuffer_test.go | 16 ++++++++++++++-- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/datagram_queue.go b/datagram_queue.go index 43026b25022..e26285b2615 100644 --- a/datagram_queue.go +++ b/datagram_queue.go @@ -5,6 +5,7 @@ import ( "sync" "github.com/quic-go/quic-go/internal/utils" + "github.com/quic-go/quic-go/internal/utils/ringbuffer" "github.com/quic-go/quic-go/internal/wire" ) @@ -15,8 +16,8 @@ const ( type datagramQueue struct { sendMx sync.Mutex - sendQueue []*wire.DatagramFrame // TODO: this could be a ring buffer - sent chan struct{} // used to notify Add that a datagram was dequeued + sendQueue ringbuffer.RingBuffer[*wire.DatagramFrame] + sent chan struct{} // used to notify Add that a datagram was dequeued rcvMx sync.Mutex rcvQueue [][]byte @@ -47,8 +48,8 @@ func (h *datagramQueue) Add(f *wire.DatagramFrame) error { h.sendMx.Lock() for { - if len(h.sendQueue) < maxDatagramSendQueueLen { - h.sendQueue = append(h.sendQueue, f) + if h.sendQueue.Len() < maxDatagramSendQueueLen { + h.sendQueue.PushBack(f) h.sendMx.Unlock() h.hasData() return nil @@ -72,19 +73,16 @@ func (h *datagramQueue) Add(f *wire.DatagramFrame) error { func (h *datagramQueue) Peek() *wire.DatagramFrame { h.sendMx.Lock() defer h.sendMx.Unlock() - if len(h.sendQueue) == 0 { + if h.sendQueue.Empty() { return nil } - return h.sendQueue[0] + return h.sendQueue.PeekFront() } func (h *datagramQueue) Pop() { h.sendMx.Lock() defer h.sendMx.Unlock() - if len(h.sendQueue) == 0 { - panic("datagramQueue BUG: Pop called for nil frame") - } - h.sendQueue = h.sendQueue[1:] + _ = h.sendQueue.PopFront() select { case h.sent <- struct{}{}: default: diff --git a/internal/utils/ringbuffer/ringbuffer.go b/internal/utils/ringbuffer/ringbuffer.go index 81a5ad44b8a..f9b2c797b68 100644 --- a/internal/utils/ringbuffer/ringbuffer.go +++ b/internal/utils/ringbuffer/ringbuffer.go @@ -8,7 +8,7 @@ type RingBuffer[T any] struct { full bool } -// Init preallocs a buffer with a certain size. +// Init preallocates a buffer with a certain size. func (r *RingBuffer[T]) Init(size int) { r.ring = make([]T, size) } @@ -62,6 +62,16 @@ func (r *RingBuffer[T]) PopFront() T { return t } +// PeekFront returns the next element. +// It must not be called when the buffer is empty, that means that +// callers might need to check if there are elements in the buffer first. +func (r *RingBuffer[T]) PeekFront() T { + if r.Empty() { + panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: peek from an empty queue") + } + return r.ring[r.headPos] +} + // Grow the maximum size of the queue. // This method assume the queue is full. func (r *RingBuffer[T]) grow() { diff --git a/internal/utils/ringbuffer/ringbuffer_test.go b/internal/utils/ringbuffer/ringbuffer_test.go index 13241a30849..68f1c7cc794 100644 --- a/internal/utils/ringbuffer/ringbuffer_test.go +++ b/internal/utils/ringbuffer/ringbuffer_test.go @@ -6,14 +6,17 @@ import ( ) var _ = Describe("RingBuffer", func() { - It("push and pop", func() { + It("push, peek and pop", func() { r := RingBuffer[int]{} Expect(len(r.ring)).To(Equal(0)) Expect(func() { r.PopFront() }).To(Panic()) r.PushBack(1) r.PushBack(2) r.PushBack(3) + Expect(r.PeekFront()).To(Equal(1)) + Expect(r.PeekFront()).To(Equal(1)) Expect(r.PopFront()).To(Equal(1)) + Expect(r.PeekFront()).To(Equal(2)) Expect(r.PopFront()).To(Equal(2)) r.PushBack(4) r.PushBack(5) @@ -25,7 +28,16 @@ var _ = Describe("RingBuffer", func() { Expect(r.PopFront()).To(Equal(5)) Expect(r.PopFront()).To(Equal(6)) }) - It("clear", func() { + + It("panics when Peek or Pop are called on an empty buffer", func() { + r := RingBuffer[string]{} + Expect(r.Empty()).To(BeTrue()) + Expect(r.Len()).To(BeZero()) + Expect(func() { r.PeekFront() }).To(Panic()) + Expect(func() { r.PopFront() }).To(Panic()) + }) + + It("clearing", func() { r := RingBuffer[int]{} r.Init(2) r.PushBack(1) From 1083d1fb8f98a9ba787fc33fdec405196e9d3108 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 2 Jan 2024 14:52:08 +0700 Subject: [PATCH 139/225] handshake: remove unneeded mutex in cryptoSetup (#4227) --- internal/handshake/crypto_setup.go | 38 ------------------------------ 1 file changed, 38 deletions(-) diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index 1e1874a57c9..70b62dc9ca2 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -8,7 +8,6 @@ import ( "fmt" "net" "strings" - "sync" "sync/atomic" "time" @@ -48,8 +47,6 @@ type cryptoSetup struct { perspective protocol.Perspective - mutex sync.Mutex // protects all members below - handshakeCompleteTime time.Time zeroRTTOpener LongHeaderOpener // only set for the server @@ -434,10 +431,8 @@ func (h *cryptoSetup) handleSessionTicket(sessionTicketData []byte, using0RTT bo func (h *cryptoSetup) rejected0RTT() { h.logger.Debugf("0-RTT was rejected. Dropping 0-RTT keys.") - h.mutex.Lock() had0RTTKeys := h.zeroRTTSealer != nil h.zeroRTTSealer = nil - h.mutex.Unlock() if had0RTTKeys { h.events = append(h.events, Event{Kind: EventDiscard0RTTKeys}) @@ -446,7 +441,6 @@ func (h *cryptoSetup) rejected0RTT() { func (h *cryptoSetup) SetReadKey(el tls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) { suite := getCipherSuite(suiteID) - h.mutex.Lock() //nolint:exhaustive // The TLS stack doesn't export Initial keys. switch el { case tls.QUICEncryptionLevelEarly: @@ -478,7 +472,6 @@ func (h *cryptoSetup) SetReadKey(el tls.QUICEncryptionLevel, suiteID uint16, tra default: panic("unexpected read encryption level") } - h.mutex.Unlock() h.events = append(h.events, Event{Kind: EventReceivedReadKeys}) if h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil { h.tracer.UpdatedKeyFromTLS(qtls.FromTLSEncryptionLevel(el), h.perspective.Opposite()) @@ -487,7 +480,6 @@ func (h *cryptoSetup) SetReadKey(el tls.QUICEncryptionLevel, suiteID uint16, tra func (h *cryptoSetup) SetWriteKey(el tls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) { suite := getCipherSuite(suiteID) - h.mutex.Lock() //nolint:exhaustive // The TLS stack doesn't export Initial keys. switch el { case tls.QUICEncryptionLevelEarly: @@ -498,7 +490,6 @@ func (h *cryptoSetup) SetWriteKey(el tls.QUICEncryptionLevel, suiteID uint16, tr createAEAD(suite, trafficSecret, h.version), newHeaderProtector(suite, trafficSecret, true, h.version), ) - h.mutex.Unlock() if h.logger.Debug() { h.logger.Debugf("Installed 0-RTT Write keys (using %s)", tls.CipherSuiteName(suite.ID)) } @@ -533,7 +524,6 @@ func (h *cryptoSetup) SetWriteKey(el tls.QUICEncryptionLevel, suiteID uint16, tr default: panic("unexpected write encryption level") } - h.mutex.Unlock() if h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil { h.tracer.UpdatedKeyFromTLS(qtls.FromTLSEncryptionLevel(el), h.perspective) } @@ -555,11 +545,9 @@ func (h *cryptoSetup) writeRecord(encLevel tls.QUICEncryptionLevel, p []byte) { } func (h *cryptoSetup) DiscardInitialKeys() { - h.mutex.Lock() dropped := h.initialOpener != nil h.initialOpener = nil h.initialSealer = nil - h.mutex.Unlock() if dropped { h.logger.Debugf("Dropping Initial keys.") } @@ -574,22 +562,17 @@ func (h *cryptoSetup) SetHandshakeConfirmed() { h.aead.SetHandshakeConfirmed() // drop Handshake keys var dropped bool - h.mutex.Lock() if h.handshakeOpener != nil { h.handshakeOpener = nil h.handshakeSealer = nil dropped = true } - h.mutex.Unlock() if dropped { h.logger.Debugf("Dropping Handshake keys.") } } func (h *cryptoSetup) GetInitialSealer() (LongHeaderSealer, error) { - h.mutex.Lock() - defer h.mutex.Unlock() - if h.initialSealer == nil { return nil, ErrKeysDropped } @@ -597,9 +580,6 @@ func (h *cryptoSetup) GetInitialSealer() (LongHeaderSealer, error) { } func (h *cryptoSetup) Get0RTTSealer() (LongHeaderSealer, error) { - h.mutex.Lock() - defer h.mutex.Unlock() - if h.zeroRTTSealer == nil { return nil, ErrKeysDropped } @@ -607,9 +587,6 @@ func (h *cryptoSetup) Get0RTTSealer() (LongHeaderSealer, error) { } func (h *cryptoSetup) GetHandshakeSealer() (LongHeaderSealer, error) { - h.mutex.Lock() - defer h.mutex.Unlock() - if h.handshakeSealer == nil { if h.initialSealer == nil { return nil, ErrKeysDropped @@ -620,9 +597,6 @@ func (h *cryptoSetup) GetHandshakeSealer() (LongHeaderSealer, error) { } func (h *cryptoSetup) Get1RTTSealer() (ShortHeaderSealer, error) { - h.mutex.Lock() - defer h.mutex.Unlock() - if !h.has1RTTSealer { return nil, ErrKeysNotYetAvailable } @@ -630,9 +604,6 @@ func (h *cryptoSetup) Get1RTTSealer() (ShortHeaderSealer, error) { } func (h *cryptoSetup) GetInitialOpener() (LongHeaderOpener, error) { - h.mutex.Lock() - defer h.mutex.Unlock() - if h.initialOpener == nil { return nil, ErrKeysDropped } @@ -640,9 +611,6 @@ func (h *cryptoSetup) GetInitialOpener() (LongHeaderOpener, error) { } func (h *cryptoSetup) Get0RTTOpener() (LongHeaderOpener, error) { - h.mutex.Lock() - defer h.mutex.Unlock() - if h.zeroRTTOpener == nil { if h.initialOpener != nil { return nil, ErrKeysNotYetAvailable @@ -654,9 +622,6 @@ func (h *cryptoSetup) Get0RTTOpener() (LongHeaderOpener, error) { } func (h *cryptoSetup) GetHandshakeOpener() (LongHeaderOpener, error) { - h.mutex.Lock() - defer h.mutex.Unlock() - if h.handshakeOpener == nil { if h.initialOpener != nil { return nil, ErrKeysNotYetAvailable @@ -668,9 +633,6 @@ func (h *cryptoSetup) GetHandshakeOpener() (LongHeaderOpener, error) { } func (h *cryptoSetup) Get1RTTOpener() (ShortHeaderOpener, error) { - h.mutex.Lock() - defer h.mutex.Unlock() - if h.zeroRTTOpener != nil && time.Since(h.handshakeCompleteTime) > 3*h.rttStats.PTO(true) { h.zeroRTTOpener = nil h.logger.Debugf("Dropping 0-RTT keys.") From 59ed51704a216d1c50a97a3fa40cb41e34c0b44d Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 3 Jan 2024 12:32:58 +0700 Subject: [PATCH 140/225] README: add RoadRunner to list of projects (#4226) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a43375e983a..d8b060f1dca 100644 --- a/README.md +++ b/README.md @@ -237,6 +237,7 @@ http.Client{ | [Hysteria](https://github.com/apernet/hysteria) | A powerful, lightning fast and censorship resistant proxy | ![GitHub Repo stars](https://img.shields.io/github/stars/apernet/hysteria?style=flat-square) | | [Mercure](https://github.com/dunglas/mercure) | An open, easy, fast, reliable and battery-efficient solution for real-time communications | ![GitHub Repo stars](https://img.shields.io/github/stars/dunglas/mercure?style=flat-square) | | [OONI Probe](https://github.com/ooni/probe-cli) | Next generation OONI Probe. Library and CLI tool. | ![GitHub Repo stars](https://img.shields.io/github/stars/ooni/probe-cli?style=flat-square) | +| [RoadRunner](https://github.com/roadrunner-server/roadrunner) | High-performance PHP application server, process manager written in Go and powered with plugins | ![GitHub Repo stars](https://img.shields.io/github/stars/roadrunner-server/roadrunner?style=flat-square) | | [syncthing](https://github.com/syncthing/syncthing/) | Open Source Continuous File Synchronization | ![GitHub Repo stars](https://img.shields.io/github/stars/syncthing/syncthing?style=flat-square) | | [traefik](https://github.com/traefik/traefik) | The Cloud Native Application Proxy | ![GitHub Repo stars](https://img.shields.io/github/stars/traefik/traefik?style=flat-square) | | [v2ray-core](https://github.com/v2fly/v2ray-core) | A platform for building proxies to bypass network restrictions | ![GitHub Repo stars](https://img.shields.io/github/stars/v2fly/v2ray-core?style=flat-square) | From 8cad3d2ea50cd98dde701bb942da0955db2710e4 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 3 Jan 2024 12:56:25 +0700 Subject: [PATCH 141/225] wire: use netip.AddrPort to encode the IPs in the Preferred Address (#4232) --- connection_test.go | 5 ++-- fuzzing/transportparameters/cmd/corpus.go | 12 ++++---- internal/wire/transport_parameter_test.go | 14 ++++------ internal/wire/transport_parameters.go | 34 ++++++++++------------- qlog/event.go | 12 ++++---- qlog/qlog.go | 2 -- qlog/qlog_test.go | 7 ++--- 7 files changed, 38 insertions(+), 48 deletions(-) diff --git a/connection_test.go b/connection_test.go index 973f1b6f845..15add18d54d 100644 --- a/connection_test.go +++ b/connection_test.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "net" + "net/netip" "runtime/pprof" "strings" "time" @@ -2940,8 +2941,8 @@ var _ = Describe("Client Connection", func() { OriginalDestinationConnectionID: destConnID, InitialSourceConnectionID: destConnID, PreferredAddress: &wire.PreferredAddress{ - IPv4: net.IPv4(127, 0, 0, 1), - IPv6: net.IP{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + IPv4: netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), 42), + IPv6: netip.AddrPortFrom(netip.AddrFrom16([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), 13), ConnectionID: protocol.ParseConnectionID([]byte{1, 2, 3, 4}), StatelessResetToken: protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, }, diff --git a/fuzzing/transportparameters/cmd/corpus.go b/fuzzing/transportparameters/cmd/corpus.go index 9e59cfba798..282e7d338ab 100644 --- a/fuzzing/transportparameters/cmd/corpus.go +++ b/fuzzing/transportparameters/cmd/corpus.go @@ -3,7 +3,7 @@ package main import ( "log" "math" - "net" + "net/netip" "time" "golang.org/x/exp/rand" @@ -59,11 +59,13 @@ func main() { if rand.Int()%2 == 0 { var token protocol.StatelessResetToken rand.Read(token[:]) + var ip4 [4]byte + rand.Read(ip4[:]) + var ip6 [16]byte + rand.Read(ip6[:]) tp.PreferredAddress = &wire.PreferredAddress{ - IPv4: net.IPv4(uint8(rand.Int()), uint8(rand.Int()), uint8(rand.Int()), uint8(rand.Int())), - IPv4Port: uint16(rand.Int()), - IPv6: net.IP(getRandomData(16)), - IPv6Port: uint16(rand.Int()), + IPv4: netip.AddrPortFrom(netip.AddrFrom4(ip4), uint16(rand.Int())), + IPv6: netip.AddrPortFrom(netip.AddrFrom16(ip6), uint16(rand.Int())), ConnectionID: protocol.ParseConnectionID(getRandomData(rand.Intn(21))), StatelessResetToken: token, } diff --git a/internal/wire/transport_parameter_test.go b/internal/wire/transport_parameter_test.go index a82b6dcf522..04e31f85f8b 100644 --- a/internal/wire/transport_parameter_test.go +++ b/internal/wire/transport_parameter_test.go @@ -4,7 +4,7 @@ import ( "bytes" "fmt" "math" - "net" + "net/netip" "time" "golang.org/x/exp/rand" @@ -425,10 +425,8 @@ var _ = Describe("Transport Parameters", func() { BeforeEach(func() { pa = &PreferredAddress{ - IPv4: net.IPv4(127, 0, 0, 1), - IPv4Port: 42, - IPv6: net.IP{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - IPv6Port: 13, + IPv4: netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), 42), + IPv6: netip.AddrPortFrom(netip.AddrFrom16([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), 13), ConnectionID: protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}), StatelessResetToken: protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, } @@ -442,10 +440,8 @@ var _ = Describe("Transport Parameters", func() { }).Marshal(protocol.PerspectiveServer) p := &TransportParameters{} Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(Succeed()) - Expect(p.PreferredAddress.IPv4.String()).To(Equal(pa.IPv4.String())) - Expect(p.PreferredAddress.IPv4Port).To(Equal(pa.IPv4Port)) - Expect(p.PreferredAddress.IPv6.String()).To(Equal(pa.IPv6.String())) - Expect(p.PreferredAddress.IPv6Port).To(Equal(pa.IPv6Port)) + Expect(p.PreferredAddress.IPv4).To(Equal(pa.IPv4)) + Expect(p.PreferredAddress.IPv6).To(Equal(pa.IPv6)) Expect(p.PreferredAddress.ConnectionID).To(Equal(pa.ConnectionID)) Expect(p.PreferredAddress.StatelessResetToken).To(Equal(pa.StatelessResetToken)) }) diff --git a/internal/wire/transport_parameters.go b/internal/wire/transport_parameters.go index 104142a007c..c03be3cd739 100644 --- a/internal/wire/transport_parameters.go +++ b/internal/wire/transport_parameters.go @@ -7,7 +7,7 @@ import ( "errors" "fmt" "io" - "net" + "net/netip" "sort" "time" @@ -51,10 +51,7 @@ const ( // PreferredAddress is the value encoding in the preferred_address transport parameter type PreferredAddress struct { - IPv4 net.IP - IPv4Port uint16 - IPv6 net.IP - IPv6Port uint16 + IPv4, IPv6 netip.AddrPort ConnectionID protocol.ConnectionID StatelessResetToken protocol.StatelessResetToken } @@ -218,26 +215,24 @@ func (p *TransportParameters) unmarshal(r *bytes.Reader, sentBy protocol.Perspec func (p *TransportParameters) readPreferredAddress(r *bytes.Reader, expectedLen int) error { remainingLen := r.Len() pa := &PreferredAddress{} - ipv4 := make([]byte, 4) - if _, err := io.ReadFull(r, ipv4); err != nil { + var ipv4 [4]byte + if _, err := io.ReadFull(r, ipv4[:]); err != nil { return err } - pa.IPv4 = net.IP(ipv4) port, err := utils.BigEndian.ReadUint16(r) if err != nil { return err } - pa.IPv4Port = port - ipv6 := make([]byte, 16) - if _, err := io.ReadFull(r, ipv6); err != nil { + pa.IPv4 = netip.AddrPortFrom(netip.AddrFrom4(ipv4), port) + var ipv6 [16]byte + if _, err := io.ReadFull(r, ipv6[:]); err != nil { return err } - pa.IPv6 = net.IP(ipv6) port, err = utils.BigEndian.ReadUint16(r) if err != nil { return err } - pa.IPv6Port = port + pa.IPv6 = netip.AddrPortFrom(netip.AddrFrom16(ipv6), port) connIDLen, err := r.ReadByte() if err != nil { return err @@ -384,13 +379,12 @@ func (p *TransportParameters) Marshal(pers protocol.Perspective) []byte { if p.PreferredAddress != nil { b = quicvarint.Append(b, uint64(preferredAddressParameterID)) b = quicvarint.Append(b, 4+2+16+2+1+uint64(p.PreferredAddress.ConnectionID.Len())+16) - ipv4 := p.PreferredAddress.IPv4 - b = append(b, ipv4[len(ipv4)-4:]...) - b = append(b, []byte{0, 0}...) - binary.BigEndian.PutUint16(b[len(b)-2:], p.PreferredAddress.IPv4Port) - b = append(b, p.PreferredAddress.IPv6...) - b = append(b, []byte{0, 0}...) - binary.BigEndian.PutUint16(b[len(b)-2:], p.PreferredAddress.IPv6Port) + ip4 := p.PreferredAddress.IPv4.Addr().As4() + b = append(b, ip4[:]...) + b = binary.BigEndian.AppendUint16(b, p.PreferredAddress.IPv4.Port()) + ip6 := p.PreferredAddress.IPv6.Addr().As16() + b = append(b, ip6[:]...) + b = binary.BigEndian.AppendUint16(b, p.PreferredAddress.IPv6.Port()) b = append(b, uint8(p.PreferredAddress.ConnectionID.Len())) b = append(b, p.PreferredAddress.ConnectionID.Bytes()...) b = append(b, p.PreferredAddress.StatelessResetToken[:]...) diff --git a/qlog/event.go b/qlog/event.go index f345d13923d..e2ceca9f4b8 100644 --- a/qlog/event.go +++ b/qlog/event.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "net" + "net/netip" "time" "github.com/quic-go/quic-go" @@ -456,8 +457,7 @@ func (e eventTransportParameters) MarshalJSONObject(enc *gojay.Encoder) { } type preferredAddress struct { - IPv4, IPv6 net.IP - PortV4, PortV6 uint16 + IPv4, IPv6 netip.AddrPort ConnectionID protocol.ConnectionID StatelessResetToken protocol.StatelessResetToken } @@ -466,10 +466,10 @@ var _ gojay.MarshalerJSONObject = &preferredAddress{} func (a preferredAddress) IsNil() bool { return false } func (a preferredAddress) MarshalJSONObject(enc *gojay.Encoder) { - enc.StringKey("ip_v4", a.IPv4.String()) - enc.Uint16Key("port_v4", a.PortV4) - enc.StringKey("ip_v6", a.IPv6.String()) - enc.Uint16Key("port_v6", a.PortV6) + enc.StringKey("ip_v4", a.IPv4.Addr().String()) + enc.Uint16Key("port_v4", a.IPv4.Port()) + enc.StringKey("ip_v6", a.IPv6.Addr().String()) + enc.Uint16Key("port_v6", a.IPv6.Port()) enc.StringKey("connection_id", a.ConnectionID.String()) enc.StringKey("stateless_reset_token", fmt.Sprintf("%x", a.StatelessResetToken)) } diff --git a/qlog/qlog.go b/qlog/qlog.go index 0df77ce5e1b..1bc1259c1fd 100644 --- a/qlog/qlog.go +++ b/qlog/qlog.go @@ -304,9 +304,7 @@ func (t *connectionTracer) toTransportParameters(tp *wire.TransportParameters) * if tp.PreferredAddress != nil { pa = &preferredAddress{ IPv4: tp.PreferredAddress.IPv4, - PortV4: tp.PreferredAddress.IPv4Port, IPv6: tp.PreferredAddress.IPv6, - PortV6: tp.PreferredAddress.IPv6Port, ConnectionID: tp.PreferredAddress.ConnectionID, StatelessResetToken: tp.PreferredAddress.StatelessResetToken, } diff --git a/qlog/qlog_test.go b/qlog/qlog_test.go index 11a49d88789..7684fcc5291 100644 --- a/qlog/qlog_test.go +++ b/qlog/qlog_test.go @@ -7,6 +7,7 @@ import ( "io" "log" "net" + "net/netip" "os" "time" @@ -338,10 +339,8 @@ var _ = Describe("Tracing", func() { It("records transport parameters with a preferred address", func() { tracer.SentTransportParameters(&logging.TransportParameters{ PreferredAddress: &logging.PreferredAddress{ - IPv4: net.IPv4(12, 34, 56, 78), - IPv4Port: 123, - IPv6: net.IP{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - IPv6Port: 456, + IPv4: netip.AddrPortFrom(netip.AddrFrom4([4]byte{12, 34, 56, 78}), 123), + IPv6: netip.AddrPortFrom(netip.AddrFrom16([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), 456), ConnectionID: protocol.ParseConnectionID([]byte{8, 7, 6, 5, 4, 3, 2, 1}), StatelessResetToken: protocol.StatelessResetToken{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, }, From 54d6f7dc5170fbdc4d277cce111261c0e2823b2c Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 4 Jan 2024 09:39:09 +0700 Subject: [PATCH 142/225] ackhandler: refactor ACK queueing logic (#4225) Once an ACK has been queued, there's no need to check futher conditions that would lead to queueing of an ACK. --- connection_test.go | 1 - .../ackhandler/received_packet_tracker.go | 57 +++++++++---------- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/connection_test.go b/connection_test.go index 15add18d54d..c4ea0657329 100644 --- a/connection_test.go +++ b/connection_test.go @@ -1270,7 +1270,6 @@ var _ = Describe("Connection", func() { 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) conn.scheduleSending() time.Sleep(50 * time.Millisecond) // make sure there are no calls to mconn.Write() }) diff --git a/internal/ackhandler/received_packet_tracker.go b/internal/ackhandler/received_packet_tracker.go index 6d8eec4e735..fec863e4645 100644 --- a/internal/ackhandler/received_packet_tracker.go +++ b/internal/ackhandler/received_packet_tracker.go @@ -56,10 +56,6 @@ func (h *receivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn pro h.largestObservedRcvdTime = rcvTime } - if ackEliciting { - h.hasNewAck = true - h.maybeQueueACK(pn, rcvTime, ecn, isMissing) - } //nolint:exhaustive // Only need to count ECT(0), ECT(1) and ECN-CE. switch ecn { case protocol.ECT0: @@ -69,6 +65,24 @@ func (h *receivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn pro case protocol.ECNCE: h.ecnce++ } + + if !ackEliciting { + return nil + } + + h.hasNewAck = true + h.ackElicitingPacketsReceivedSinceLastAck++ + if !h.ackQueued && h.shouldQueueACK(pn, ecn, isMissing) { + h.ackQueued = true + h.ackAlarm = time.Time{} // cancel the ack alarm + } + if !h.ackQueued { + // No ACK queued, but we'll need to acknowledge the packet after max_ack_delay. + h.ackAlarm = rcvTime.Add(h.maxAckDelay) + if h.logger.Debug() { + h.logger.Debugf("\tSetting ACK timer to max ack delay: %s", h.maxAckDelay) + } + } return nil } @@ -101,23 +115,13 @@ 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, ecn protocol.ECN, wasMissing bool) { +func (h *receivedPacketTracker) shouldQueueACK(pn protocol.PacketNumber, ecn protocol.ECN, wasMissing bool) bool { // always acknowledge the first packet if h.lastAck == nil { - if !h.ackQueued { - h.logger.Debugf("\tQueueing ACK because the first packet should be acknowledged.") - } - h.ackQueued = true - return + h.logger.Debugf("\tQueueing ACK because the first packet should be acknowledged.") + return true } - if h.ackQueued { - return - } - - h.ackElicitingPacketsReceivedSinceLastAck++ - // Send an ACK if this packet was reported missing in an ACK sent before. // Ack decimation with reordering relies on the timer to send an ACK, but if // missing packets we reported in the previous ack, send an ACK immediately. @@ -125,7 +129,7 @@ func (h *receivedPacketTracker) maybeQueueACK(pn protocol.PacketNumber, rcvTime if h.logger.Debug() { h.logger.Debugf("\tQueueing ACK because packet %d was missing before.", pn) } - h.ackQueued = true + return true } // send an ACK every 2 ack-eliciting packets @@ -133,30 +137,21 @@ func (h *receivedPacketTracker) maybeQueueACK(pn protocol.PacketNumber, rcvTime if h.logger.Debug() { h.logger.Debugf("\tQueueing ACK because packet %d packets were received after the last ACK (using initial threshold: %d).", h.ackElicitingPacketsReceivedSinceLastAck, packetsBeforeAck) } - h.ackQueued = true - } else if h.ackAlarm.IsZero() { - if h.logger.Debug() { - h.logger.Debugf("\tSetting ACK timer to max ack delay: %s", h.maxAckDelay) - } - h.ackAlarm = rcvTime.Add(h.maxAckDelay) + return true } // queue an ACK if there are new missing packets to report if h.hasNewMissingPackets() { h.logger.Debugf("\tQueuing ACK because there's a new missing packet to report.") - h.ackQueued = true + return true } // queue an ACK if the packet was ECN-CE marked if ecn == protocol.ECNCE { h.logger.Debugf("\tQueuing ACK because the packet was ECN-CE marked.") - h.ackQueued = true - } - - if h.ackQueued { - // cancel the ack alarm - h.ackAlarm = time.Time{} + return true } + return false } func (h *receivedPacketTracker) GetAckFrame(onlyIfQueued bool) *wire.AckFrame { From f1b3bdbcb046b51c05a09154d5d420298f6a398d Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 5 Jan 2024 09:59:39 +0700 Subject: [PATCH 143/225] fix race condition when dropping Initial packet with short connection ID (#4236) --- server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.go b/server.go index 124e30be6f6..f509ae14385 100644 --- a/server.go +++ b/server.go @@ -542,10 +542,10 @@ func (s *baseServer) validateToken(token *handshake.Token, addr net.Addr) bool { func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error { if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial { - p.buffer.Release() if s.tracer != nil && s.tracer.DroppedPacket != nil { s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropUnexpectedPacket) } + p.buffer.Release() return errors.New("too short connection ID") } From 3ff50295ce73c4b6efcf58330d53798e94528097 Mon Sep 17 00:00:00 2001 From: Robin Thellend Date: Thu, 4 Jan 2024 19:13:53 -0800 Subject: [PATCH 144/225] http3: add ConnContext to the server (#4230) * Add ConnContext to http3.Server ConnContext can be used to modify the context used by a new http Request. * Make linter happy * Add nil check and integration test * Add the ServerContextKey check to the ConnContext func * Update integrationtests/self/http_test.go Co-authored-by: Marten Seemann * Update http3/server.go Co-authored-by: Marten Seemann --------- Co-authored-by: Marten Seemann --- http3/server.go | 11 +++++++++++ http3/server_test.go | 5 +++++ integrationtests/self/http_test.go | 31 ++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/http3/server.go b/http3/server.go index ca586f0dee3..769942c1637 100644 --- a/http3/server.go +++ b/http3/server.go @@ -211,6 +211,11 @@ type Server struct { // In that case, the stream type will not be set. UniStreamHijacker func(StreamType, quic.Connection, quic.ReceiveStream, error) (hijacked bool) + // ConnContext optionally specifies a function that modifies + // the context used for a new connection c. The provided ctx + // has a ServerContextKey value. + ConnContext func(ctx context.Context, c quic.Connection) context.Context + mutex sync.RWMutex listeners map[*QUICEarlyListener]listenerInfo @@ -610,6 +615,12 @@ func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *q ctx = context.WithValue(ctx, ServerContextKey, s) ctx = context.WithValue(ctx, http.LocalAddrContextKey, conn.LocalAddr()) ctx = context.WithValue(ctx, RemoteAddrContextKey, conn.RemoteAddr()) + if s.ConnContext != nil { + ctx = s.ConnContext(ctx, conn) + if ctx == nil { + panic("http3: ConnContext returned nil") + } + } req = req.WithContext(ctx) r := newResponseWriter(str, conn, s.logger) if req.Method == http.MethodHead { diff --git a/http3/server_test.go b/http3/server_test.go index 8da80611131..ab702c421bc 100644 --- a/http3/server_test.go +++ b/http3/server_test.go @@ -67,11 +67,15 @@ var _ = Describe("Server", func() { s *Server origQuicListenAddr = quicListenAddr ) + type testConnContextKey string BeforeEach(func() { s = &Server{ TLSConfig: testdata.GetTLSConfig(), logger: utils.DefaultLogger, + ConnContext: func(ctx context.Context, c quic.Connection) context.Context { + return context.WithValue(ctx, testConnContextKey("test"), c) + }, } origQuicListenAddr = quicListenAddr }) @@ -163,6 +167,7 @@ var _ = Describe("Server", func() { Expect(req.Host).To(Equal("www.example.com")) Expect(req.RemoteAddr).To(Equal("127.0.0.1:1337")) Expect(req.Context().Value(ServerContextKey)).To(Equal(s)) + Expect(req.Context().Value(testConnContextKey("test"))).ToNot(Equal(nil)) }) It("returns 200 with an empty handler", func() { diff --git a/integrationtests/self/http_test.go b/integrationtests/self/http_test.go index 96e72dc7c26..cf9f683e4a6 100644 --- a/integrationtests/self/http_test.go +++ b/integrationtests/self/http_test.go @@ -528,4 +528,35 @@ var _ = Describe("HTTP tests", func() { Expect(err).ToNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(200)) }) + + It("sets conn context", func() { + type ctxKey int + server.ConnContext = func(ctx context.Context, c quic.Connection) context.Context { + serv, ok := ctx.Value(http3.ServerContextKey).(*http3.Server) + Expect(ok).To(BeTrue()) + Expect(serv).To(Equal(server)) + + ctx = context.WithValue(ctx, ctxKey(0), "Hello") + ctx = context.WithValue(ctx, ctxKey(1), c) + return ctx + } + mux.HandleFunc("/conn-context", func(w http.ResponseWriter, r *http.Request) { + defer GinkgoRecover() + v, ok := r.Context().Value(ctxKey(0)).(string) + Expect(ok).To(BeTrue()) + Expect(v).To(Equal("Hello")) + + c, ok := r.Context().Value(ctxKey(1)).(quic.Connection) + Expect(ok).To(BeTrue()) + Expect(c).ToNot(BeNil()) + + serv, ok := r.Context().Value(http3.ServerContextKey).(*http3.Server) + Expect(ok).To(BeTrue()) + Expect(serv).To(Equal(server)) + }) + + resp, err := client.Get(fmt.Sprintf("https://localhost:%d/conn-context", port)) + Expect(err).ToNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(200)) + }) }) From 0a922b4e7d1357f8f79eba307e1a1bfcf9ca35d7 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 5 Jan 2024 17:21:42 +0700 Subject: [PATCH 145/225] example: add config flag for TLS key and cert for the server (#4237) --- example/main.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/example/main.go b/example/main.go index cd476e44ecf..014003f6b71 100644 --- a/example/main.go +++ b/example/main.go @@ -144,6 +144,8 @@ func main() { flag.Var(&bs, "bind", "bind to") www := flag.String("www", "", "www data") tcp := flag.Bool("tcp", false, "also listen on TCP") + key := flag.String("key", "", "TLS key (requires -cert option)") + cert := flag.String("cert", "", "TLS certificate (requires -key option)") enableQlog := flag.Bool("qlog", false, "output a qlog (in the same directory)") flag.Parse() @@ -176,12 +178,18 @@ func main() { var wg sync.WaitGroup wg.Add(len(bs)) + var certFile, keyFile string + if *key != "" && *cert != "" { + keyFile = *key + certFile = *cert + } else { + certFile, keyFile = testdata.GetCertificatePaths() + } for _, b := range bs { bCap := b go func() { var err error if *tcp { - certFile, keyFile := testdata.GetCertificatePaths() err = http3.ListenAndServe(bCap, certFile, keyFile, handler) } else { server := http3.Server{ @@ -189,7 +197,7 @@ func main() { Addr: bCap, QuicConfig: quicConf, } - err = server.ListenAndServeTLS(testdata.GetCertificatePaths()) + err = server.ListenAndServeTLS(certFile, keyFile) } if err != nil { fmt.Println(err) From 1e874896cd39adc02663be4d77ade701b333df5a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 11 Jan 2024 12:53:25 +0700 Subject: [PATCH 146/225] wire: improve logging of connection ID retirements (#4241) --- internal/wire/log.go | 4 +++- internal/wire/log_test.go | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/internal/wire/log.go b/internal/wire/log.go index ec7d45d861c..c8b28d924c2 100644 --- a/internal/wire/log.go +++ b/internal/wire/log.go @@ -63,7 +63,9 @@ func LogFrame(logger utils.Logger, frame Frame, sent bool) { logger.Debugf("\t%s &wire.StreamsBlockedFrame{Type: bidi, MaxStreams: %d}", dir, f.StreamLimit) } case *NewConnectionIDFrame: - logger.Debugf("\t%s &wire.NewConnectionIDFrame{SequenceNumber: %d, ConnectionID: %s, StatelessResetToken: %#x}", dir, f.SequenceNumber, f.ConnectionID, f.StatelessResetToken) + logger.Debugf("\t%s &wire.NewConnectionIDFrame{SequenceNumber: %d, RetirePriorTo: %d, ConnectionID: %s, StatelessResetToken: %#x}", dir, f.SequenceNumber, f.RetirePriorTo, f.ConnectionID, f.StatelessResetToken) + case *RetireConnectionIDFrame: + logger.Debugf("\t%s &wire.RetireConnectionIDFrame{SequenceNumber: %d}", dir, f.SequenceNumber) case *NewTokenFrame: logger.Debugf("\t%s &wire.NewTokenFrame{Token: %#x}", dir, f.Token) default: diff --git a/internal/wire/log_test.go b/internal/wire/log_test.go index 8675cb715e9..f71b6256f67 100644 --- a/internal/wire/log_test.go +++ b/internal/wire/log_test.go @@ -153,10 +153,16 @@ var _ = Describe("Frame logging", func() { It("logs NEW_CONNECTION_ID frames", func() { LogFrame(logger, &NewConnectionIDFrame{ SequenceNumber: 42, + RetirePriorTo: 24, ConnectionID: protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}), StatelessResetToken: protocol.StatelessResetToken{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10}, }, false) - Expect(buf.String()).To(ContainSubstring("\t<- &wire.NewConnectionIDFrame{SequenceNumber: 42, ConnectionID: deadbeef, StatelessResetToken: 0x0102030405060708090a0b0c0d0e0f10}")) + Expect(buf.String()).To(ContainSubstring("\t<- &wire.NewConnectionIDFrame{SequenceNumber: 42, RetirePriorTo: 24, ConnectionID: deadbeef, StatelessResetToken: 0x0102030405060708090a0b0c0d0e0f10}")) + }) + + It("logs RETIRE_CONNECTION_ID frames", func() { + LogFrame(logger, &RetireConnectionIDFrame{SequenceNumber: 42}, false) + Expect(buf.String()).To(ContainSubstring("\t<- &wire.RetireConnectionIDFrame{SequenceNumber: 42}")) }) It("logs NEW_TOKEN frames", func() { From 2cd9ed38f178cd7d7ee6db960ad4ae9a45875535 Mon Sep 17 00:00:00 2001 From: Benedikt Spies Date: Fri, 12 Jan 2024 12:11:53 +0100 Subject: [PATCH 147/225] qlog: add a default tracer that writes to QLOGDIR (#4233) * add qlog default tracer which writes to QLOGDIR * gofumpt * add qlog default tracer which writes to QLOGDIR * fix flaky tests * Update README.md Co-authored-by: Marten Seemann * Update README.md Co-authored-by: Marten Seemann * Update README.md Co-authored-by: Marten Seemann * Update README.md Co-authored-by: Marten Seemann --------- Co-authored-by: Marten Seemann --- README.md | 20 ++---- integrationtests/self/qlog_dir_test.go | 90 ++++++++++++++++++++++++++ qlog/qlog_dir.go | 49 ++++++++++++++ qlog/qlog_dir_test.go | 56 ++++++++++++++++ 4 files changed, 202 insertions(+), 13 deletions(-) create mode 100644 integrationtests/self/qlog_dir_test.go create mode 100644 qlog/qlog_dir.go create mode 100644 qlog/qlog_dir_test.go diff --git a/README.md b/README.md index d8b060f1dca..93f14dd993e 100644 --- a/README.md +++ b/README.md @@ -183,25 +183,19 @@ quic-go logs a wide range of events defined in [draft-ietf-quic-qlog-quic-events qlog files can be processed by a number of 3rd-party tools. [qviz](https://qvis.quictools.info/) has proven very useful for debugging all kinds of QUIC connection failures. -qlog is activated by setting a `Tracer` callback on the `Config`. It is called as soon as quic-go decides to starts the QUIC handshake on a new connection. -A useful implementation of this callback could look like this: +qlog can be activated by setting the `Tracer` callback on the `Config`. It is called as soon as quic-go decides to start the QUIC handshake on a new connection. +`qlog.DefaultTracer` provides a tracer implementation which writes qlog files to a directory specified by the `QLOGDIR` environment variable, if set. +The default qlog tracer can be used like this: ```go quic.Config{ - Tracer: func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) *logging.ConnectionTracer { - role := "server" - if p == logging.PerspectiveClient { - role = "client" - } - filename := fmt.Sprintf("./log_%s_%s.qlog", connID, role) - f, err := os.Create(filename) - // handle the error - return qlog.NewConnectionTracer(f, p, connID) - } + Tracer: qlog.DefaultTracer, } ``` -This implementation of the callback creates a new qlog file in the current directory named `log__.qlog`. +This example creates a new qlog file under `/_.qlog`, e.g. `qlogs/2e0407da_client.qlog`. + +For custom qlog behavior, `qlog.NewConnectionTracer` can be used. ## Using HTTP/3 diff --git a/integrationtests/self/qlog_dir_test.go b/integrationtests/self/qlog_dir_test.go new file mode 100644 index 00000000000..1af5a619ad5 --- /dev/null +++ b/integrationtests/self/qlog_dir_test.go @@ -0,0 +1,90 @@ +package self_test + +import ( + "context" + "os" + "path" + "regexp" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/quic-go/quic-go" + "github.com/quic-go/quic-go/qlog" +) + +var _ = Describe("qlog dir tests", Serial, func() { + var originalQlogDirValue string + var tempTestDirPath string + + BeforeEach(func() { + originalQlogDirValue = os.Getenv("QLOGDIR") + var err error + tempTestDirPath, err = os.MkdirTemp("", "temp_test_dir") + Expect(err).ToNot(HaveOccurred()) + }) + + AfterEach(func() { + err := os.Setenv("QLOGDIR", originalQlogDirValue) + Expect(err).ToNot(HaveOccurred()) + err = os.RemoveAll(tempTestDirPath) + Expect(err).ToNot(HaveOccurred()) + }) + + handshake := func() { + serverStopped := make(chan struct{}) + server, err := quic.ListenAddr( + "localhost:0", + getTLSConfig(), + &quic.Config{ + Tracer: qlog.DefaultTracer, + }, + ) + Expect(err).ToNot(HaveOccurred()) + + go func() { + defer GinkgoRecover() + defer close(serverStopped) + for { + if _, err := server.Accept(context.Background()); err != nil { + return + } + } + }() + + conn, err := quic.DialAddr( + context.Background(), + server.Addr().String(), + getTLSClientConfig(), + &quic.Config{ + Tracer: qlog.DefaultTracer, + }, + ) + Expect(err).ToNot(HaveOccurred()) + conn.CloseWithError(0, "") + server.Close() + <-serverStopped + } + + It("environment variable is set", func() { + qlogDir := path.Join(tempTestDirPath, "qlogs") + err := os.Setenv("QLOGDIR", qlogDir) + Expect(err).ToNot(HaveOccurred()) + handshake() + _, err = os.Stat(tempTestDirPath) + qlogDirCreated := !os.IsNotExist(err) + Expect(qlogDirCreated).To(BeTrue()) + childs, err := os.ReadDir(qlogDir) + Expect(err).ToNot(HaveOccurred()) + Expect(len(childs)).To(Equal(2)) + odcids := make([]string, 0) + vantagePoints := make([]string, 0) + qlogFileNameRegexp := regexp.MustCompile(`^([0-f]+)_(client|server).qlog$`) + for _, child := range childs { + matches := qlogFileNameRegexp.FindStringSubmatch(child.Name()) + odcids = append(odcids, matches[1]) + vantagePoints = append(vantagePoints, matches[2]) + } + Expect(odcids[0]).To(Equal(odcids[1])) + Expect(vantagePoints).To(ContainElements("client", "server")) + }) +}) diff --git a/qlog/qlog_dir.go b/qlog/qlog_dir.go new file mode 100644 index 00000000000..e7acef4f035 --- /dev/null +++ b/qlog/qlog_dir.go @@ -0,0 +1,49 @@ +package qlog + +import ( + "bufio" + "context" + "fmt" + "log" + "os" + "strings" + + "github.com/quic-go/quic-go/internal/utils" + "github.com/quic-go/quic-go/logging" +) + +// DefaultTracer creates a qlog file in the qlog directory specified by the QLOGDIR environment variable. +// File names are _.qlog. +// Returns nil if QLOGDIR is not set. +func DefaultTracer(_ context.Context, p logging.Perspective, connID logging.ConnectionID) *logging.ConnectionTracer { + var label string + switch p { + case logging.PerspectiveClient: + label = "client" + case logging.PerspectiveServer: + label = "server" + } + return qlogDirTracer(p, connID, label) +} + +// qlogDirTracer creates a qlog file in the qlog directory specified by the QLOGDIR environment variable. +// File names are _