github.com/TugasAkhir-QUIC/quic-go@v0.0.2-0.20240215011318-d20e25a9054c/connection_test.go (about)

     1  package quic
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"crypto/rand"
     7  	"crypto/tls"
     8  	"errors"
     9  	"fmt"
    10  	"io"
    11  	"net"
    12  	"net/netip"
    13  	"runtime/pprof"
    14  	"strings"
    15  	"time"
    16  
    17  	"github.com/TugasAkhir-QUIC/quic-go/internal/ackhandler"
    18  	"github.com/TugasAkhir-QUIC/quic-go/internal/handshake"
    19  	"github.com/TugasAkhir-QUIC/quic-go/internal/mocks"
    20  	mockackhandler "github.com/TugasAkhir-QUIC/quic-go/internal/mocks/ackhandler"
    21  	mocklogging "github.com/TugasAkhir-QUIC/quic-go/internal/mocks/logging"
    22  	"github.com/TugasAkhir-QUIC/quic-go/internal/protocol"
    23  	"github.com/TugasAkhir-QUIC/quic-go/internal/qerr"
    24  	"github.com/TugasAkhir-QUIC/quic-go/internal/utils"
    25  	"github.com/TugasAkhir-QUIC/quic-go/internal/wire"
    26  	"github.com/TugasAkhir-QUIC/quic-go/logging"
    27  	"github.com/TugasAkhir-QUIC/quic-go/testutils"
    28  
    29  	. "github.com/onsi/ginkgo/v2"
    30  	. "github.com/onsi/gomega"
    31  	"go.uber.org/mock/gomock"
    32  )
    33  
    34  func areConnsRunning() bool {
    35  	var b bytes.Buffer
    36  	pprof.Lookup("goroutine").WriteTo(&b, 1)
    37  	return strings.Contains(b.String(), "quic-go.(*connection).run")
    38  }
    39  
    40  var _ = Describe("Connection", func() {
    41  	var (
    42  		conn          *connection
    43  		connRunner    *MockConnRunner
    44  		mconn         *MockSendConn
    45  		streamManager *MockStreamManager
    46  		packer        *MockPacker
    47  		cryptoSetup   *mocks.MockCryptoSetup
    48  		tracer        *mocklogging.MockConnectionTracer
    49  		capabilities  connCapabilities
    50  	)
    51  	remoteAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337}
    52  	localAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 7331}
    53  	srcConnID := protocol.ParseConnectionID([]byte{1, 2, 3, 4, 5, 6, 7, 8})
    54  	destConnID := protocol.ParseConnectionID([]byte{8, 7, 6, 5, 4, 3, 2, 1})
    55  	clientDestConnID := protocol.ParseConnectionID([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
    56  
    57  	getCoalescedPacket := func(pn protocol.PacketNumber, isLongHeader bool) *coalescedPacket {
    58  		buffer := getPacketBuffer()
    59  		buffer.Data = append(buffer.Data, []byte("foobar")...)
    60  		packet := &coalescedPacket{buffer: buffer}
    61  		if isLongHeader {
    62  			packet.longHdrPackets = []*longHeaderPacket{{
    63  				header: &wire.ExtendedHeader{
    64  					Header:       wire.Header{},
    65  					PacketNumber: pn,
    66  				},
    67  				length: 6, // foobar
    68  			}}
    69  		} else {
    70  			packet.shortHdrPacket = &shortHeaderPacket{
    71  				PacketNumber: pn,
    72  				Length:       6,
    73  			}
    74  		}
    75  		return packet
    76  	}
    77  
    78  	expectReplaceWithClosed := func() {
    79  		connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(connIDs []protocol.ConnectionID, _ protocol.Perspective, _ []byte) {
    80  			Expect(connIDs).To(ContainElement(srcConnID))
    81  			if len(connIDs) > 1 {
    82  				Expect(connIDs).To(ContainElement(clientDestConnID))
    83  			}
    84  		})
    85  	}
    86  
    87  	expectAppendPacket := func(packer *MockPacker, p shortHeaderPacket, b []byte) *PackerAppendPacketCall {
    88  		return packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), Version1).DoAndReturn(func(buf *packetBuffer, _ protocol.ByteCount, _ protocol.Version) (shortHeaderPacket, error) {
    89  			buf.Data = append(buf.Data, b...)
    90  			return p, nil
    91  		})
    92  	}
    93  
    94  	enableGSO := func() { capabilities = connCapabilities{GSO: true} }
    95  
    96  	BeforeEach(func() {
    97  		Eventually(areConnsRunning).Should(BeFalse())
    98  
    99  		connRunner = NewMockConnRunner(mockCtrl)
   100  		mconn = NewMockSendConn(mockCtrl)
   101  		mconn.EXPECT().capabilities().DoAndReturn(func() connCapabilities { return capabilities }).AnyTimes()
   102  		mconn.EXPECT().RemoteAddr().Return(remoteAddr).AnyTimes()
   103  		mconn.EXPECT().LocalAddr().Return(localAddr).AnyTimes()
   104  		tokenGenerator := handshake.NewTokenGenerator([32]byte{0xa, 0xb, 0xc})
   105  		var tr *logging.ConnectionTracer
   106  		tr, tracer = mocklogging.NewMockConnectionTracer(mockCtrl)
   107  		tracer.EXPECT().NegotiatedVersion(gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1)
   108  		tracer.EXPECT().SentTransportParameters(gomock.Any())
   109  		tracer.EXPECT().UpdatedKeyFromTLS(gomock.Any(), gomock.Any()).AnyTimes()
   110  		tracer.EXPECT().UpdatedCongestionState(gomock.Any())
   111  		conn = newConnection(
   112  			mconn,
   113  			connRunner,
   114  			protocol.ConnectionID{},
   115  			nil,
   116  			clientDestConnID,
   117  			destConnID,
   118  			srcConnID,
   119  			&protocol.DefaultConnectionIDGenerator{},
   120  			protocol.StatelessResetToken{},
   121  			populateConfig(&Config{DisablePathMTUDiscovery: true}),
   122  			&tls.Config{},
   123  			tokenGenerator,
   124  			false,
   125  			tr,
   126  			1234,
   127  			utils.DefaultLogger,
   128  			protocol.Version1,
   129  		).(*connection)
   130  		streamManager = NewMockStreamManager(mockCtrl)
   131  		conn.streamsMap = streamManager
   132  		packer = NewMockPacker(mockCtrl)
   133  		conn.packer = packer
   134  		cryptoSetup = mocks.NewMockCryptoSetup(mockCtrl)
   135  		conn.cryptoStreamHandler = cryptoSetup
   136  		conn.handshakeComplete = true
   137  		conn.idleTimeout = time.Hour
   138  	})
   139  
   140  	AfterEach(func() {
   141  		Eventually(areConnsRunning).Should(BeFalse())
   142  		capabilities = connCapabilities{}
   143  	})
   144  
   145  	Context("frame handling", func() {
   146  		Context("handling STREAM frames", func() {
   147  			It("passes STREAM frames to the stream", func() {
   148  				f := &wire.StreamFrame{
   149  					StreamID: 5,
   150  					Data:     []byte{0xde, 0xca, 0xfb, 0xad},
   151  				}
   152  				str := NewMockReceiveStreamI(mockCtrl)
   153  				str.EXPECT().handleStreamFrame(f)
   154  				streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(5)).Return(str, nil)
   155  				Expect(conn.handleStreamFrame(f)).To(Succeed())
   156  			})
   157  
   158  			It("returns errors", func() {
   159  				testErr := errors.New("test err")
   160  				f := &wire.StreamFrame{
   161  					StreamID: 5,
   162  					Data:     []byte{0xde, 0xca, 0xfb, 0xad},
   163  				}
   164  				str := NewMockReceiveStreamI(mockCtrl)
   165  				str.EXPECT().handleStreamFrame(f).Return(testErr)
   166  				streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(5)).Return(str, nil)
   167  				Expect(conn.handleStreamFrame(f)).To(MatchError(testErr))
   168  			})
   169  
   170  			It("ignores STREAM frames for closed streams", func() {
   171  				streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(5)).Return(nil, nil) // for closed streams, the streamManager returns nil
   172  				Expect(conn.handleStreamFrame(&wire.StreamFrame{
   173  					StreamID: 5,
   174  					Data:     []byte("foobar"),
   175  				})).To(Succeed())
   176  			})
   177  		})
   178  
   179  		Context("handling ACK frames", func() {
   180  			It("informs the SentPacketHandler about ACKs", func() {
   181  				f := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 3}}}
   182  				sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
   183  				sph.EXPECT().ReceivedAck(f, protocol.EncryptionHandshake, gomock.Any())
   184  				conn.sentPacketHandler = sph
   185  				err := conn.handleAckFrame(f, protocol.EncryptionHandshake)
   186  				Expect(err).ToNot(HaveOccurred())
   187  			})
   188  		})
   189  
   190  		Context("handling RESET_STREAM frames", func() {
   191  			It("closes the streams for writing", func() {
   192  				f := &wire.ResetStreamFrame{
   193  					StreamID:  555,
   194  					ErrorCode: 42,
   195  					FinalSize: 0x1337,
   196  				}
   197  				str := NewMockReceiveStreamI(mockCtrl)
   198  				streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(555)).Return(str, nil)
   199  				str.EXPECT().handleResetStreamFrame(f)
   200  				err := conn.handleResetStreamFrame(f)
   201  				Expect(err).ToNot(HaveOccurred())
   202  			})
   203  
   204  			It("returns errors", func() {
   205  				f := &wire.ResetStreamFrame{
   206  					StreamID:  7,
   207  					FinalSize: 0x1337,
   208  				}
   209  				testErr := errors.New("flow control violation")
   210  				str := NewMockReceiveStreamI(mockCtrl)
   211  				streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(7)).Return(str, nil)
   212  				str.EXPECT().handleResetStreamFrame(f).Return(testErr)
   213  				err := conn.handleResetStreamFrame(f)
   214  				Expect(err).To(MatchError(testErr))
   215  			})
   216  
   217  			It("ignores RESET_STREAM frames for closed streams", func() {
   218  				streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(3)).Return(nil, nil)
   219  				Expect(conn.handleFrame(&wire.ResetStreamFrame{
   220  					StreamID:  3,
   221  					ErrorCode: 42,
   222  				}, protocol.Encryption1RTT, protocol.ConnectionID{})).To(Succeed())
   223  			})
   224  		})
   225  
   226  		Context("handling MAX_DATA and MAX_STREAM_DATA frames", func() {
   227  			var connFC *mocks.MockConnectionFlowController
   228  
   229  			BeforeEach(func() {
   230  				connFC = mocks.NewMockConnectionFlowController(mockCtrl)
   231  				conn.connFlowController = connFC
   232  			})
   233  
   234  			It("updates the flow control window of a stream", func() {
   235  				f := &wire.MaxStreamDataFrame{
   236  					StreamID:          12345,
   237  					MaximumStreamData: 0x1337,
   238  				}
   239  				str := NewMockSendStreamI(mockCtrl)
   240  				streamManager.EXPECT().GetOrOpenSendStream(protocol.StreamID(12345)).Return(str, nil)
   241  				str.EXPECT().updateSendWindow(protocol.ByteCount(0x1337))
   242  				Expect(conn.handleMaxStreamDataFrame(f)).To(Succeed())
   243  			})
   244  
   245  			It("updates the flow control window of the connection", func() {
   246  				offset := protocol.ByteCount(0x800000)
   247  				connFC.EXPECT().UpdateSendWindow(offset)
   248  				conn.handleMaxDataFrame(&wire.MaxDataFrame{MaximumData: offset})
   249  			})
   250  
   251  			It("ignores MAX_STREAM_DATA frames for a closed stream", func() {
   252  				streamManager.EXPECT().GetOrOpenSendStream(protocol.StreamID(10)).Return(nil, nil)
   253  				Expect(conn.handleFrame(&wire.MaxStreamDataFrame{
   254  					StreamID:          10,
   255  					MaximumStreamData: 1337,
   256  				}, protocol.Encryption1RTT, protocol.ConnectionID{})).To(Succeed())
   257  			})
   258  		})
   259  
   260  		Context("handling MAX_STREAM_ID frames", func() {
   261  			It("passes the frame to the streamsMap", func() {
   262  				f := &wire.MaxStreamsFrame{
   263  					Type:         protocol.StreamTypeUni,
   264  					MaxStreamNum: 10,
   265  				}
   266  				streamManager.EXPECT().HandleMaxStreamsFrame(f)
   267  				conn.handleMaxStreamsFrame(f)
   268  			})
   269  		})
   270  
   271  		Context("handling STOP_SENDING frames", func() {
   272  			It("passes the frame to the stream", func() {
   273  				f := &wire.StopSendingFrame{
   274  					StreamID:  5,
   275  					ErrorCode: 10,
   276  				}
   277  				str := NewMockSendStreamI(mockCtrl)
   278  				streamManager.EXPECT().GetOrOpenSendStream(protocol.StreamID(5)).Return(str, nil)
   279  				str.EXPECT().handleStopSendingFrame(f)
   280  				err := conn.handleStopSendingFrame(f)
   281  				Expect(err).ToNot(HaveOccurred())
   282  			})
   283  
   284  			It("ignores STOP_SENDING frames for a closed stream", func() {
   285  				streamManager.EXPECT().GetOrOpenSendStream(protocol.StreamID(3)).Return(nil, nil)
   286  				Expect(conn.handleFrame(&wire.StopSendingFrame{
   287  					StreamID:  3,
   288  					ErrorCode: 1337,
   289  				}, protocol.Encryption1RTT, protocol.ConnectionID{})).To(Succeed())
   290  			})
   291  		})
   292  
   293  		It("handles NEW_CONNECTION_ID frames", func() {
   294  			connID := protocol.ParseConnectionID([]byte{1, 2, 3, 4})
   295  			Expect(conn.handleFrame(&wire.NewConnectionIDFrame{
   296  				SequenceNumber: 10,
   297  				ConnectionID:   connID,
   298  			}, protocol.Encryption1RTT, protocol.ConnectionID{})).To(Succeed())
   299  			Expect(conn.connIDManager.queue.Back().Value.ConnectionID).To(Equal(connID))
   300  		})
   301  
   302  		It("handles PING frames", func() {
   303  			err := conn.handleFrame(&wire.PingFrame{}, protocol.Encryption1RTT, protocol.ConnectionID{})
   304  			Expect(err).NotTo(HaveOccurred())
   305  		})
   306  
   307  		It("rejects PATH_RESPONSE frames", func() {
   308  			err := conn.handleFrame(&wire.PathResponseFrame{Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}}, protocol.Encryption1RTT, protocol.ConnectionID{})
   309  			Expect(err).To(MatchError("unexpected PATH_RESPONSE frame"))
   310  		})
   311  
   312  		It("handles PATH_CHALLENGE frames", func() {
   313  			data := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
   314  			err := conn.handleFrame(&wire.PathChallengeFrame{Data: data}, protocol.Encryption1RTT, protocol.ConnectionID{})
   315  			Expect(err).ToNot(HaveOccurred())
   316  			frames, _ := conn.framer.AppendControlFrames(nil, 1000, protocol.Version1)
   317  			Expect(frames).To(Equal([]ackhandler.Frame{{Frame: &wire.PathResponseFrame{Data: data}}}))
   318  		})
   319  
   320  		It("rejects NEW_TOKEN frames", func() {
   321  			err := conn.handleNewTokenFrame(&wire.NewTokenFrame{})
   322  			Expect(err).To(HaveOccurred())
   323  			Expect(err).To(BeAssignableToTypeOf(&qerr.TransportError{}))
   324  			Expect(err.(*qerr.TransportError).ErrorCode).To(Equal(qerr.ProtocolViolation))
   325  		})
   326  
   327  		It("handles BLOCKED frames", func() {
   328  			err := conn.handleFrame(&wire.DataBlockedFrame{}, protocol.Encryption1RTT, protocol.ConnectionID{})
   329  			Expect(err).NotTo(HaveOccurred())
   330  		})
   331  
   332  		It("handles STREAM_BLOCKED frames", func() {
   333  			err := conn.handleFrame(&wire.StreamDataBlockedFrame{}, protocol.Encryption1RTT, protocol.ConnectionID{})
   334  			Expect(err).NotTo(HaveOccurred())
   335  		})
   336  
   337  		It("handles STREAMS_BLOCKED frames", func() {
   338  			err := conn.handleFrame(&wire.StreamsBlockedFrame{}, protocol.Encryption1RTT, protocol.ConnectionID{})
   339  			Expect(err).NotTo(HaveOccurred())
   340  		})
   341  
   342  		It("handles CONNECTION_CLOSE frames, with a transport error code", func() {
   343  			expectedErr := &qerr.TransportError{
   344  				Remote:       true,
   345  				ErrorCode:    qerr.StreamLimitError,
   346  				ErrorMessage: "foobar",
   347  			}
   348  			streamManager.EXPECT().CloseWithError(expectedErr)
   349  			connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(connIDs []protocol.ConnectionID, _ protocol.Perspective, _ []byte) {
   350  				Expect(connIDs).To(ConsistOf(clientDestConnID, srcConnID))
   351  			})
   352  			cryptoSetup.EXPECT().Close()
   353  			gomock.InOrder(
   354  				tracer.EXPECT().ClosedConnection(expectedErr),
   355  				tracer.EXPECT().Close(),
   356  			)
   357  
   358  			go func() {
   359  				defer GinkgoRecover()
   360  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
   361  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
   362  				Expect(conn.run()).To(MatchError(expectedErr))
   363  			}()
   364  			Expect(conn.handleFrame(&wire.ConnectionCloseFrame{
   365  				ErrorCode:    uint64(qerr.StreamLimitError),
   366  				ReasonPhrase: "foobar",
   367  			}, protocol.Encryption1RTT, protocol.ConnectionID{})).To(Succeed())
   368  			Eventually(conn.Context().Done()).Should(BeClosed())
   369  		})
   370  
   371  		It("handles CONNECTION_CLOSE frames, with an application error code", func() {
   372  			testErr := &qerr.ApplicationError{
   373  				Remote:       true,
   374  				ErrorCode:    0x1337,
   375  				ErrorMessage: "foobar",
   376  			}
   377  			streamManager.EXPECT().CloseWithError(testErr)
   378  			connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(connIDs []protocol.ConnectionID, _ protocol.Perspective, _ []byte) {
   379  				Expect(connIDs).To(ConsistOf(clientDestConnID, srcConnID))
   380  			})
   381  			cryptoSetup.EXPECT().Close()
   382  			gomock.InOrder(
   383  				tracer.EXPECT().ClosedConnection(testErr),
   384  				tracer.EXPECT().Close(),
   385  			)
   386  
   387  			go func() {
   388  				defer GinkgoRecover()
   389  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
   390  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
   391  				Expect(conn.run()).To(MatchError(testErr))
   392  			}()
   393  			ccf := &wire.ConnectionCloseFrame{
   394  				ErrorCode:          0x1337,
   395  				ReasonPhrase:       "foobar",
   396  				IsApplicationError: true,
   397  			}
   398  			Expect(conn.handleFrame(ccf, protocol.Encryption1RTT, protocol.ConnectionID{})).To(Succeed())
   399  			Eventually(conn.Context().Done()).Should(BeClosed())
   400  			Expect(context.Cause(conn.Context())).To(MatchError(testErr))
   401  		})
   402  
   403  		It("errors on HANDSHAKE_DONE frames", func() {
   404  			Expect(conn.handleHandshakeDoneFrame()).To(MatchError(&qerr.TransportError{
   405  				ErrorCode:    qerr.ProtocolViolation,
   406  				ErrorMessage: "received a HANDSHAKE_DONE frame",
   407  			}))
   408  		})
   409  	})
   410  
   411  	It("tells its versions", func() {
   412  		conn.version = 4242
   413  		Expect(conn.GetVersion()).To(Equal(protocol.Version(4242)))
   414  	})
   415  
   416  	Context("closing", func() {
   417  		var (
   418  			runErr         chan error
   419  			expectedRunErr error
   420  		)
   421  
   422  		BeforeEach(func() {
   423  			runErr = make(chan error, 1)
   424  			expectedRunErr = nil
   425  		})
   426  
   427  		AfterEach(func() {
   428  			if expectedRunErr != nil {
   429  				Eventually(runErr).Should(Receive(MatchError(expectedRunErr)))
   430  			} else {
   431  				Eventually(runErr).Should(Receive())
   432  			}
   433  		})
   434  
   435  		runConn := func() {
   436  			go func() {
   437  				defer GinkgoRecover()
   438  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
   439  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
   440  				runErr <- conn.run()
   441  			}()
   442  			Eventually(areConnsRunning).Should(BeTrue())
   443  		}
   444  
   445  		It("shuts down without error", func() {
   446  			conn.handshakeComplete = true
   447  			runConn()
   448  			streamManager.EXPECT().CloseWithError(&qerr.ApplicationError{})
   449  			expectReplaceWithClosed()
   450  			cryptoSetup.EXPECT().Close()
   451  			buffer := getPacketBuffer()
   452  			buffer.Data = append(buffer.Data, []byte("connection close")...)
   453  			packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).DoAndReturn(func(e *qerr.ApplicationError, _ protocol.ByteCount, _ protocol.Version) (*coalescedPacket, error) {
   454  				Expect(e.ErrorCode).To(BeEquivalentTo(qerr.NoError))
   455  				Expect(e.ErrorMessage).To(BeEmpty())
   456  				return &coalescedPacket{buffer: buffer}, nil
   457  			})
   458  			mconn.EXPECT().Write([]byte("connection close"), gomock.Any(), gomock.Any())
   459  			gomock.InOrder(
   460  				tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) {
   461  					var appErr *ApplicationError
   462  					Expect(errors.As(e, &appErr)).To(BeTrue())
   463  					Expect(appErr.Remote).To(BeFalse())
   464  					Expect(appErr.ErrorCode).To(BeZero())
   465  				}),
   466  				tracer.EXPECT().Close(),
   467  			)
   468  			conn.CloseWithError(0, "")
   469  			Eventually(areConnsRunning).Should(BeFalse())
   470  			Expect(conn.Context().Done()).To(BeClosed())
   471  		})
   472  
   473  		It("only closes once", func() {
   474  			runConn()
   475  			streamManager.EXPECT().CloseWithError(gomock.Any())
   476  			expectReplaceWithClosed()
   477  			cryptoSetup.EXPECT().Close()
   478  			packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
   479  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
   480  			tracer.EXPECT().ClosedConnection(gomock.Any())
   481  			tracer.EXPECT().Close()
   482  			conn.CloseWithError(0, "")
   483  			conn.CloseWithError(0, "")
   484  			Eventually(areConnsRunning).Should(BeFalse())
   485  			Expect(conn.Context().Done()).To(BeClosed())
   486  		})
   487  
   488  		It("closes with an error", func() {
   489  			runConn()
   490  			expectedErr := &qerr.ApplicationError{
   491  				ErrorCode:    0x1337,
   492  				ErrorMessage: "test error",
   493  			}
   494  			streamManager.EXPECT().CloseWithError(expectedErr)
   495  			expectReplaceWithClosed()
   496  			cryptoSetup.EXPECT().Close()
   497  			packer.EXPECT().PackApplicationClose(expectedErr, gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
   498  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
   499  			gomock.InOrder(
   500  				tracer.EXPECT().ClosedConnection(expectedErr),
   501  				tracer.EXPECT().Close(),
   502  			)
   503  			conn.CloseWithError(0x1337, "test error")
   504  			Eventually(areConnsRunning).Should(BeFalse())
   505  			Expect(conn.Context().Done()).To(BeClosed())
   506  			Expect(context.Cause(conn.Context())).To(MatchError(expectedErr))
   507  		})
   508  
   509  		It("includes the frame type in transport-level close frames", func() {
   510  			runConn()
   511  			expectedErr := &qerr.TransportError{
   512  				ErrorCode:    0x1337,
   513  				FrameType:    0x42,
   514  				ErrorMessage: "test error",
   515  			}
   516  			streamManager.EXPECT().CloseWithError(expectedErr)
   517  			expectReplaceWithClosed()
   518  			cryptoSetup.EXPECT().Close()
   519  			packer.EXPECT().PackConnectionClose(expectedErr, gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
   520  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
   521  			gomock.InOrder(
   522  				tracer.EXPECT().ClosedConnection(expectedErr),
   523  				tracer.EXPECT().Close(),
   524  			)
   525  			conn.closeLocal(expectedErr)
   526  			Eventually(areConnsRunning).Should(BeFalse())
   527  			Expect(conn.Context().Done()).To(BeClosed())
   528  		})
   529  
   530  		It("destroys the connection", func() {
   531  			runConn()
   532  			testErr := errors.New("close")
   533  			streamManager.EXPECT().CloseWithError(gomock.Any())
   534  			connRunner.EXPECT().Remove(gomock.Any()).AnyTimes()
   535  			cryptoSetup.EXPECT().Close()
   536  			// don't EXPECT any calls to mconn.Write()
   537  			gomock.InOrder(
   538  				tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) {
   539  					var transportErr *TransportError
   540  					Expect(errors.As(e, &transportErr)).To(BeTrue())
   541  					Expect(transportErr.Remote).To(BeFalse())
   542  					Expect(transportErr.ErrorCode).To(Equal(qerr.InternalError))
   543  				}),
   544  				tracer.EXPECT().Close(),
   545  			)
   546  			conn.destroy(testErr)
   547  			Eventually(areConnsRunning).Should(BeFalse())
   548  			expectedRunErr = &qerr.TransportError{
   549  				ErrorCode:    qerr.InternalError,
   550  				ErrorMessage: testErr.Error(),
   551  			}
   552  		})
   553  
   554  		It("doesn't send any more packets after receiving a CONNECTION_CLOSE", func() {
   555  			unpacker := NewMockUnpacker(mockCtrl)
   556  			conn.handshakeConfirmed = true
   557  			conn.unpacker = unpacker
   558  			runConn()
   559  			cryptoSetup.EXPECT().Close()
   560  			streamManager.EXPECT().CloseWithError(gomock.Any())
   561  			connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
   562  			b, err := wire.AppendShortHeader(nil, srcConnID, 42, protocol.PacketNumberLen2, protocol.KeyPhaseOne)
   563  			Expect(err).ToNot(HaveOccurred())
   564  
   565  			unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).DoAndReturn(func(time.Time, []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
   566  				b, err := (&wire.ConnectionCloseFrame{ErrorCode: uint64(qerr.StreamLimitError)}).Append(nil, conn.version)
   567  				Expect(err).ToNot(HaveOccurred())
   568  				return 3, protocol.PacketNumberLen2, protocol.KeyPhaseOne, b, nil
   569  			})
   570  			gomock.InOrder(
   571  				tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()),
   572  				tracer.EXPECT().ClosedConnection(gomock.Any()),
   573  				tracer.EXPECT().Close(),
   574  			)
   575  			// don't EXPECT any calls to packer.PackPacket()
   576  			conn.handlePacket(receivedPacket{
   577  				rcvTime:    time.Now(),
   578  				remoteAddr: &net.UDPAddr{},
   579  				buffer:     getPacketBuffer(),
   580  				data:       b,
   581  			})
   582  			// Consistently(pack).ShouldNot(Receive())
   583  			Eventually(conn.Context().Done()).Should(BeClosed())
   584  		})
   585  
   586  		It("closes when the sendQueue encounters an error", func() {
   587  			conn.handshakeConfirmed = true
   588  			sconn := NewMockSendConn(mockCtrl)
   589  			sconn.EXPECT().capabilities().AnyTimes()
   590  			sconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any()).Return(io.ErrClosedPipe).AnyTimes()
   591  			conn.sendQueue = newSendQueue(sconn)
   592  			sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
   593  			sph.EXPECT().GetLossDetectionTimeout().Return(time.Now().Add(time.Hour)).AnyTimes()
   594  			sph.EXPECT().ECNMode(true).Return(protocol.ECT1).AnyTimes()
   595  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
   596  			// only expect a single SentPacket() call
   597  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
   598  			tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
   599  			tracer.EXPECT().ClosedConnection(gomock.Any())
   600  			tracer.EXPECT().Close()
   601  			streamManager.EXPECT().CloseWithError(gomock.Any())
   602  			connRunner.EXPECT().Remove(gomock.Any()).AnyTimes()
   603  			cryptoSetup.EXPECT().Close()
   604  			conn.sentPacketHandler = sph
   605  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 1}, []byte("foobar"))
   606  			packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack).AnyTimes()
   607  			runConn()
   608  			conn.queueControlFrame(&wire.PingFrame{})
   609  			conn.scheduleSending()
   610  			Eventually(conn.Context().Done()).Should(BeClosed())
   611  		})
   612  
   613  		It("closes due to a stateless reset", func() {
   614  			token := protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   615  			runConn()
   616  			gomock.InOrder(
   617  				tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) {
   618  					var srErr *StatelessResetError
   619  					Expect(errors.As(e, &srErr)).To(BeTrue())
   620  					Expect(srErr.Token).To(Equal(token))
   621  				}),
   622  				tracer.EXPECT().Close(),
   623  			)
   624  			streamManager.EXPECT().CloseWithError(gomock.Any())
   625  			connRunner.EXPECT().Remove(gomock.Any()).AnyTimes()
   626  			cryptoSetup.EXPECT().Close()
   627  			conn.destroy(&StatelessResetError{Token: token})
   628  		})
   629  	})
   630  
   631  	Context("receiving packets", func() {
   632  		var unpacker *MockUnpacker
   633  
   634  		BeforeEach(func() {
   635  			unpacker = NewMockUnpacker(mockCtrl)
   636  			conn.unpacker = unpacker
   637  		})
   638  
   639  		getShortHeaderPacket := func(connID protocol.ConnectionID, pn protocol.PacketNumber, data []byte) receivedPacket {
   640  			b, err := wire.AppendShortHeader(nil, connID, pn, protocol.PacketNumberLen2, protocol.KeyPhaseOne)
   641  			Expect(err).ToNot(HaveOccurred())
   642  			return receivedPacket{
   643  				data:    append(b, data...),
   644  				buffer:  getPacketBuffer(),
   645  				rcvTime: time.Now(),
   646  			}
   647  		}
   648  
   649  		getLongHeaderPacket := func(extHdr *wire.ExtendedHeader, data []byte) receivedPacket {
   650  			b, err := extHdr.Append(nil, conn.version)
   651  			Expect(err).ToNot(HaveOccurred())
   652  			return receivedPacket{
   653  				data:    append(b, data...),
   654  				buffer:  getPacketBuffer(),
   655  				rcvTime: time.Now(),
   656  			}
   657  		}
   658  
   659  		It("drops Retry packets", func() {
   660  			p := getLongHeaderPacket(&wire.ExtendedHeader{Header: wire.Header{
   661  				Type:             protocol.PacketTypeRetry,
   662  				DestConnectionID: destConnID,
   663  				SrcConnectionID:  srcConnID,
   664  				Version:          conn.version,
   665  				Token:            []byte("foobar"),
   666  			}}, make([]byte, 16) /* Retry integrity tag */)
   667  			tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket)
   668  			Expect(conn.handlePacketImpl(p)).To(BeFalse())
   669  		})
   670  
   671  		It("drops Version Negotiation packets", func() {
   672  			b := wire.ComposeVersionNegotiation(
   673  				protocol.ArbitraryLenConnectionID(srcConnID.Bytes()),
   674  				protocol.ArbitraryLenConnectionID(destConnID.Bytes()),
   675  				conn.config.Versions,
   676  			)
   677  			tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, protocol.ByteCount(len(b)), logging.PacketDropUnexpectedPacket)
   678  			Expect(conn.handlePacketImpl(receivedPacket{
   679  				data:   b,
   680  				buffer: getPacketBuffer(),
   681  			})).To(BeFalse())
   682  		})
   683  
   684  		It("drops packets for which header decryption fails", func() {
   685  			p := getLongHeaderPacket(&wire.ExtendedHeader{
   686  				Header: wire.Header{
   687  					Type:    protocol.PacketTypeHandshake,
   688  					Version: conn.version,
   689  				},
   690  				PacketNumberLen: protocol.PacketNumberLen2,
   691  			}, nil)
   692  			p.data[0] ^= 0x40 // unset the QUIC bit
   693  			tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError)
   694  			Expect(conn.handlePacketImpl(p)).To(BeFalse())
   695  		})
   696  
   697  		It("drops packets for which the version is unsupported", func() {
   698  			p := getLongHeaderPacket(&wire.ExtendedHeader{
   699  				Header: wire.Header{
   700  					Type:    protocol.PacketTypeHandshake,
   701  					Version: conn.version + 1,
   702  				},
   703  				PacketNumberLen: protocol.PacketNumberLen2,
   704  			}, nil)
   705  			tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnsupportedVersion)
   706  			Expect(conn.handlePacketImpl(p)).To(BeFalse())
   707  		})
   708  
   709  		It("drops packets with an unsupported version", func() {
   710  			origSupportedVersions := make([]protocol.Version, len(protocol.SupportedVersions))
   711  			copy(origSupportedVersions, protocol.SupportedVersions)
   712  			defer func() {
   713  				protocol.SupportedVersions = origSupportedVersions
   714  			}()
   715  
   716  			protocol.SupportedVersions = append(protocol.SupportedVersions, conn.version+1)
   717  			p := getLongHeaderPacket(&wire.ExtendedHeader{
   718  				Header: wire.Header{
   719  					Type:             protocol.PacketTypeHandshake,
   720  					DestConnectionID: destConnID,
   721  					SrcConnectionID:  srcConnID,
   722  					Version:          conn.version + 1,
   723  				},
   724  				PacketNumberLen: protocol.PacketNumberLen2,
   725  			}, nil)
   726  			tracer.EXPECT().DroppedPacket(logging.PacketTypeHandshake, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedVersion)
   727  			Expect(conn.handlePacketImpl(p)).To(BeFalse())
   728  		})
   729  
   730  		It("informs the ReceivedPacketHandler about non-ack-eliciting packets", func() {
   731  			hdr := &wire.ExtendedHeader{
   732  				Header: wire.Header{
   733  					Type:             protocol.PacketTypeInitial,
   734  					DestConnectionID: srcConnID,
   735  					Version:          protocol.Version1,
   736  					Length:           1,
   737  				},
   738  				PacketNumber:    0x37,
   739  				PacketNumberLen: protocol.PacketNumberLen1,
   740  			}
   741  			unpackedHdr := *hdr
   742  			unpackedHdr.PacketNumber = 0x1337
   743  			packet := getLongHeaderPacket(hdr, nil)
   744  			packet.ecn = protocol.ECNCE
   745  			rcvTime := time.Now().Add(-10 * time.Second)
   746  			unpacker.EXPECT().UnpackLongHeader(gomock.Any(), rcvTime, gomock.Any(), conn.version).Return(&unpackedPacket{
   747  				encryptionLevel: protocol.EncryptionInitial,
   748  				hdr:             &unpackedHdr,
   749  				data:            []byte{0}, // one PADDING frame
   750  			}, nil)
   751  			rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl)
   752  			gomock.InOrder(
   753  				rph.EXPECT().IsPotentiallyDuplicate(protocol.PacketNumber(0x1337), protocol.EncryptionInitial),
   754  				rph.EXPECT().ReceivedPacket(protocol.PacketNumber(0x1337), protocol.ECNCE, protocol.EncryptionInitial, rcvTime, false),
   755  			)
   756  			conn.receivedPacketHandler = rph
   757  			packet.rcvTime = rcvTime
   758  			tracer.EXPECT().StartedConnection(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
   759  			tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), logging.ECNCE, []logging.Frame{})
   760  			Expect(conn.handlePacketImpl(packet)).To(BeTrue())
   761  		})
   762  
   763  		It("informs the ReceivedPacketHandler about ack-eliciting packets", func() {
   764  			rcvTime := time.Now().Add(-10 * time.Second)
   765  			b, err := (&wire.PingFrame{}).Append(nil, conn.version)
   766  			Expect(err).ToNot(HaveOccurred())
   767  			packet := getShortHeaderPacket(srcConnID, 0x37, nil)
   768  			packet.ecn = protocol.ECT1
   769  			unpacker.EXPECT().UnpackShortHeader(rcvTime, gomock.Any()).Return(protocol.PacketNumber(0x1337), protocol.PacketNumberLen2, protocol.KeyPhaseZero, b, nil)
   770  			rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl)
   771  			gomock.InOrder(
   772  				rph.EXPECT().IsPotentiallyDuplicate(protocol.PacketNumber(0x1337), protocol.Encryption1RTT),
   773  				rph.EXPECT().ReceivedPacket(protocol.PacketNumber(0x1337), protocol.ECT1, protocol.Encryption1RTT, rcvTime, true),
   774  			)
   775  			conn.receivedPacketHandler = rph
   776  			packet.rcvTime = rcvTime
   777  			tracer.EXPECT().ReceivedShortHeaderPacket(
   778  				&logging.ShortHeader{PacketNumber: 0x1337, PacketNumberLen: 2, KeyPhase: protocol.KeyPhaseZero},
   779  				protocol.ByteCount(len(packet.data)),
   780  				logging.ECT1,
   781  				[]logging.Frame{&logging.PingFrame{}},
   782  			)
   783  			Expect(conn.handlePacketImpl(packet)).To(BeTrue())
   784  		})
   785  
   786  		It("drops duplicate packets", func() {
   787  			packet := getShortHeaderPacket(srcConnID, 0x37, nil)
   788  			unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).Return(protocol.PacketNumber(0x1337), protocol.PacketNumberLen2, protocol.KeyPhaseOne, []byte("foobar"), nil)
   789  			rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl)
   790  			rph.EXPECT().IsPotentiallyDuplicate(protocol.PacketNumber(0x1337), protocol.Encryption1RTT).Return(true)
   791  			conn.receivedPacketHandler = rph
   792  			tracer.EXPECT().DroppedPacket(logging.PacketType1RTT, protocol.PacketNumber(0x1337), protocol.ByteCount(len(packet.data)), logging.PacketDropDuplicate)
   793  			Expect(conn.handlePacketImpl(packet)).To(BeFalse())
   794  		})
   795  
   796  		It("drops a packet when unpacking fails", func() {
   797  			unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).Return(nil, handshake.ErrDecryptionFailed)
   798  			streamManager.EXPECT().CloseWithError(gomock.Any())
   799  			cryptoSetup.EXPECT().Close()
   800  			packer.EXPECT().PackConnectionClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
   801  			go func() {
   802  				defer GinkgoRecover()
   803  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
   804  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
   805  				conn.run()
   806  			}()
   807  			expectReplaceWithClosed()
   808  			p := getLongHeaderPacket(&wire.ExtendedHeader{
   809  				Header: wire.Header{
   810  					Type:             protocol.PacketTypeHandshake,
   811  					DestConnectionID: srcConnID,
   812  					Version:          conn.version,
   813  					Length:           2 + 6,
   814  				},
   815  				PacketNumber:    0x1337,
   816  				PacketNumberLen: protocol.PacketNumberLen2,
   817  			}, []byte("foobar"))
   818  			tracer.EXPECT().DroppedPacket(logging.PacketTypeHandshake, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropPayloadDecryptError)
   819  			conn.handlePacket(p)
   820  			Consistently(conn.Context().Done()).ShouldNot(BeClosed())
   821  			// make the go routine return
   822  			tracer.EXPECT().ClosedConnection(gomock.Any())
   823  			tracer.EXPECT().Close()
   824  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
   825  			conn.closeLocal(errors.New("close"))
   826  			Eventually(conn.Context().Done()).Should(BeClosed())
   827  		})
   828  
   829  		It("processes multiple received packets before sending one", func() {
   830  			conn.creationTime = time.Now()
   831  			var pn protocol.PacketNumber
   832  			unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).DoAndReturn(func(rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
   833  				pn++
   834  				return pn, protocol.PacketNumberLen2, protocol.KeyPhaseZero, []byte{0} /* PADDING frame */, nil
   835  			}).Times(3)
   836  			tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
   837  			packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version) // only expect a single call
   838  
   839  			for i := 0; i < 3; i++ {
   840  				conn.handlePacket(getShortHeaderPacket(srcConnID, 0x1337+protocol.PacketNumber(i), []byte("foobar")))
   841  			}
   842  
   843  			go func() {
   844  				defer GinkgoRecover()
   845  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
   846  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
   847  				conn.run()
   848  			}()
   849  			Consistently(conn.Context().Done()).ShouldNot(BeClosed())
   850  
   851  			// make the go routine return
   852  			streamManager.EXPECT().CloseWithError(gomock.Any())
   853  			cryptoSetup.EXPECT().Close()
   854  			packer.EXPECT().PackConnectionClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
   855  			expectReplaceWithClosed()
   856  			tracer.EXPECT().ClosedConnection(gomock.Any())
   857  			tracer.EXPECT().Close()
   858  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
   859  			conn.closeLocal(errors.New("close"))
   860  			Eventually(conn.Context().Done()).Should(BeClosed())
   861  		})
   862  
   863  		It("doesn't processes multiple received packets before sending one before handshake completion", func() {
   864  			conn.handshakeComplete = false
   865  			conn.creationTime = time.Now()
   866  			var pn protocol.PacketNumber
   867  			unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).DoAndReturn(func(rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
   868  				pn++
   869  				return pn, protocol.PacketNumberLen4, protocol.KeyPhaseZero, []byte{0} /* PADDING frame */, nil
   870  			}).Times(3)
   871  			tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
   872  			packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).Times(3)
   873  
   874  			for i := 0; i < 3; i++ {
   875  				conn.handlePacket(getShortHeaderPacket(srcConnID, 0x1337+protocol.PacketNumber(i), []byte("foobar")))
   876  			}
   877  
   878  			go func() {
   879  				defer GinkgoRecover()
   880  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
   881  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
   882  				conn.run()
   883  			}()
   884  			Consistently(conn.Context().Done()).ShouldNot(BeClosed())
   885  
   886  			// make the go routine return
   887  			streamManager.EXPECT().CloseWithError(gomock.Any())
   888  			cryptoSetup.EXPECT().Close()
   889  			packer.EXPECT().PackConnectionClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
   890  			expectReplaceWithClosed()
   891  			tracer.EXPECT().ClosedConnection(gomock.Any())
   892  			tracer.EXPECT().Close()
   893  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
   894  			conn.closeLocal(errors.New("close"))
   895  			Eventually(conn.Context().Done()).Should(BeClosed())
   896  		})
   897  
   898  		It("closes the connection when unpacking fails because the reserved bits were incorrect", func() {
   899  			unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).Return(protocol.PacketNumber(0), protocol.PacketNumberLen(0), protocol.KeyPhaseBit(0), nil, wire.ErrInvalidReservedBits)
   900  			streamManager.EXPECT().CloseWithError(gomock.Any())
   901  			cryptoSetup.EXPECT().Close()
   902  			packer.EXPECT().PackConnectionClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
   903  			done := make(chan struct{})
   904  			go func() {
   905  				defer GinkgoRecover()
   906  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
   907  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
   908  				err := conn.run()
   909  				Expect(err).To(HaveOccurred())
   910  				Expect(err).To(BeAssignableToTypeOf(&qerr.TransportError{}))
   911  				Expect(err.(*qerr.TransportError).ErrorCode).To(Equal(qerr.ProtocolViolation))
   912  				close(done)
   913  			}()
   914  			expectReplaceWithClosed()
   915  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
   916  			packet := getShortHeaderPacket(srcConnID, 0x42, nil)
   917  			tracer.EXPECT().ClosedConnection(gomock.Any())
   918  			tracer.EXPECT().Close()
   919  			conn.handlePacket(packet)
   920  			Eventually(conn.Context().Done()).Should(BeClosed())
   921  		})
   922  
   923  		It("ignores packets when unpacking the header fails", func() {
   924  			testErr := &headerParseError{errors.New("test error")}
   925  			unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).Return(protocol.PacketNumber(0), protocol.PacketNumberLen(0), protocol.KeyPhaseBit(0), nil, testErr)
   926  			streamManager.EXPECT().CloseWithError(gomock.Any())
   927  			cryptoSetup.EXPECT().Close()
   928  			runErr := make(chan error)
   929  			go func() {
   930  				defer GinkgoRecover()
   931  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
   932  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
   933  				runErr <- conn.run()
   934  			}()
   935  			expectReplaceWithClosed()
   936  			tracer.EXPECT().DroppedPacket(logging.PacketType1RTT, protocol.InvalidPacketNumber, gomock.Any(), logging.PacketDropHeaderParseError)
   937  			conn.handlePacket(getShortHeaderPacket(srcConnID, 0x42, nil))
   938  			Consistently(runErr).ShouldNot(Receive())
   939  			// make the go routine return
   940  			packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
   941  			tracer.EXPECT().ClosedConnection(gomock.Any())
   942  			tracer.EXPECT().Close()
   943  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
   944  			conn.CloseWithError(0, "")
   945  			Eventually(conn.Context().Done()).Should(BeClosed())
   946  		})
   947  
   948  		It("closes the connection when unpacking fails because of an error other than a decryption error", func() {
   949  			unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).Return(protocol.PacketNumber(0), protocol.PacketNumberLen(0), protocol.KeyPhaseBit(0), nil, &qerr.TransportError{ErrorCode: qerr.ConnectionIDLimitError})
   950  			streamManager.EXPECT().CloseWithError(gomock.Any())
   951  			cryptoSetup.EXPECT().Close()
   952  			packer.EXPECT().PackConnectionClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
   953  			done := make(chan struct{})
   954  			go func() {
   955  				defer GinkgoRecover()
   956  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
   957  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
   958  				err := conn.run()
   959  				Expect(err).To(HaveOccurred())
   960  				Expect(err).To(BeAssignableToTypeOf(&qerr.TransportError{}))
   961  				Expect(err.(*qerr.TransportError).ErrorCode).To(Equal(qerr.ConnectionIDLimitError))
   962  				close(done)
   963  			}()
   964  			expectReplaceWithClosed()
   965  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
   966  			tracer.EXPECT().ClosedConnection(gomock.Any())
   967  			tracer.EXPECT().Close()
   968  			conn.handlePacket(getShortHeaderPacket(srcConnID, 0x42, nil))
   969  			Eventually(conn.Context().Done()).Should(BeClosed())
   970  		})
   971  
   972  		It("ignores packets with a different source connection ID", func() {
   973  			hdr1 := &wire.ExtendedHeader{
   974  				Header: wire.Header{
   975  					Type:             protocol.PacketTypeInitial,
   976  					DestConnectionID: destConnID,
   977  					SrcConnectionID:  srcConnID,
   978  					Length:           1,
   979  					Version:          conn.version,
   980  				},
   981  				PacketNumberLen: protocol.PacketNumberLen1,
   982  				PacketNumber:    1,
   983  			}
   984  			hdr2 := &wire.ExtendedHeader{
   985  				Header: wire.Header{
   986  					Type:             protocol.PacketTypeInitial,
   987  					DestConnectionID: destConnID,
   988  					SrcConnectionID:  protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}),
   989  					Length:           1,
   990  					Version:          conn.version,
   991  				},
   992  				PacketNumberLen: protocol.PacketNumberLen1,
   993  				PacketNumber:    2,
   994  			}
   995  			Expect(srcConnID).ToNot(Equal(hdr2.SrcConnectionID))
   996  			// Send one packet, which might change the connection ID.
   997  			// only EXPECT one call to the unpacker
   998  			unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).Return(&unpackedPacket{
   999  				encryptionLevel: protocol.Encryption1RTT,
  1000  				hdr:             hdr1,
  1001  				data:            []byte{0}, // one PADDING frame
  1002  			}, nil)
  1003  			p1 := getLongHeaderPacket(hdr1, nil)
  1004  			tracer.EXPECT().StartedConnection(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1005  			tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(p1.data)), gomock.Any(), gomock.Any())
  1006  			Expect(conn.handlePacketImpl(p1)).To(BeTrue())
  1007  			// The next packet has to be ignored, since the source connection ID doesn't match.
  1008  			p2 := getLongHeaderPacket(hdr2, nil)
  1009  			tracer.EXPECT().DroppedPacket(logging.PacketTypeInitial, protocol.InvalidPacketNumber, protocol.ByteCount(len(p2.data)), logging.PacketDropUnknownConnectionID)
  1010  			Expect(conn.handlePacketImpl(p2)).To(BeFalse())
  1011  		})
  1012  
  1013  		It("queues undecryptable packets", func() {
  1014  			conn.handshakeComplete = false
  1015  			hdr := &wire.ExtendedHeader{
  1016  				Header: wire.Header{
  1017  					Type:             protocol.PacketTypeHandshake,
  1018  					DestConnectionID: destConnID,
  1019  					SrcConnectionID:  srcConnID,
  1020  					Length:           1,
  1021  					Version:          conn.version,
  1022  				},
  1023  				PacketNumberLen: protocol.PacketNumberLen1,
  1024  				PacketNumber:    1,
  1025  			}
  1026  			unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).Return(nil, handshake.ErrKeysNotYetAvailable)
  1027  			packet := getLongHeaderPacket(hdr, nil)
  1028  			tracer.EXPECT().BufferedPacket(logging.PacketTypeHandshake, packet.Size())
  1029  			Expect(conn.handlePacketImpl(packet)).To(BeFalse())
  1030  			Expect(conn.undecryptablePackets).To(Equal([]receivedPacket{packet}))
  1031  		})
  1032  
  1033  		Context("updating the remote address", func() {
  1034  			It("doesn't support connection migration", func() {
  1035  				unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).Return(protocol.PacketNumber(10), protocol.PacketNumberLen2, protocol.KeyPhaseZero, []byte{0} /* one PADDING frame */, nil)
  1036  				packet := getShortHeaderPacket(srcConnID, 0x42, nil)
  1037  				packet.remoteAddr = &net.IPAddr{IP: net.IPv4(192, 168, 0, 100)}
  1038  				tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet.data)), gomock.Any(), gomock.Any())
  1039  				Expect(conn.handlePacketImpl(packet)).To(BeTrue())
  1040  			})
  1041  		})
  1042  
  1043  		Context("coalesced packets", func() {
  1044  			BeforeEach(func() {
  1045  				tracer.EXPECT().StartedConnection(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1)
  1046  			})
  1047  
  1048  			getPacketWithLength := func(connID protocol.ConnectionID, length protocol.ByteCount) (int /* header length */, receivedPacket) {
  1049  				hdr := &wire.ExtendedHeader{
  1050  					Header: wire.Header{
  1051  						Type:             protocol.PacketTypeHandshake,
  1052  						DestConnectionID: connID,
  1053  						SrcConnectionID:  destConnID,
  1054  						Version:          protocol.Version1,
  1055  						Length:           length,
  1056  					},
  1057  					PacketNumberLen: protocol.PacketNumberLen3,
  1058  				}
  1059  				hdrLen := hdr.GetLength(conn.version)
  1060  				b := make([]byte, 1)
  1061  				rand.Read(b)
  1062  				packet := getLongHeaderPacket(hdr, bytes.Repeat(b, int(length)-3))
  1063  				return int(hdrLen), packet
  1064  			}
  1065  
  1066  			It("cuts packets to the right length", func() {
  1067  				hdrLen, packet := getPacketWithLength(srcConnID, 456)
  1068  				unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).DoAndReturn(func(_ *wire.Header, _ time.Time, data []byte, _ protocol.Version) (*unpackedPacket, error) {
  1069  					Expect(data).To(HaveLen(hdrLen + 456 - 3))
  1070  					return &unpackedPacket{
  1071  						encryptionLevel: protocol.EncryptionHandshake,
  1072  						data:            []byte{0},
  1073  						hdr:             &wire.ExtendedHeader{Header: wire.Header{}},
  1074  					}, nil
  1075  				})
  1076  				cryptoSetup.EXPECT().DiscardInitialKeys()
  1077  				tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionInitial)
  1078  				tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet.data)), gomock.Any(), gomock.Any())
  1079  				Expect(conn.handlePacketImpl(packet)).To(BeTrue())
  1080  			})
  1081  
  1082  			It("handles coalesced packets", func() {
  1083  				hdrLen1, packet1 := getPacketWithLength(srcConnID, 456)
  1084  				packet1.ecn = protocol.ECT1
  1085  				unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).DoAndReturn(func(_ *wire.Header, _ time.Time, data []byte, _ protocol.Version) (*unpackedPacket, error) {
  1086  					Expect(data).To(HaveLen(hdrLen1 + 456 - 3))
  1087  					return &unpackedPacket{
  1088  						encryptionLevel: protocol.EncryptionHandshake,
  1089  						data:            []byte{0},
  1090  						hdr: &wire.ExtendedHeader{
  1091  							PacketNumber: 1,
  1092  							Header:       wire.Header{SrcConnectionID: destConnID},
  1093  						},
  1094  					}, nil
  1095  				})
  1096  				hdrLen2, packet2 := getPacketWithLength(srcConnID, 123)
  1097  				unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).DoAndReturn(func(_ *wire.Header, _ time.Time, data []byte, _ protocol.Version) (*unpackedPacket, error) {
  1098  					Expect(data).To(HaveLen(hdrLen2 + 123 - 3))
  1099  					return &unpackedPacket{
  1100  						encryptionLevel: protocol.EncryptionHandshake,
  1101  						data:            []byte{0},
  1102  						hdr: &wire.ExtendedHeader{
  1103  							PacketNumber: 2,
  1104  							Header:       wire.Header{SrcConnectionID: destConnID},
  1105  						},
  1106  					}, nil
  1107  				})
  1108  				tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionInitial).AnyTimes()
  1109  				cryptoSetup.EXPECT().DiscardInitialKeys().AnyTimes()
  1110  				gomock.InOrder(
  1111  					tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet1.data)), logging.ECT1, gomock.Any()),
  1112  					tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet2.data)), logging.ECT1, gomock.Any()),
  1113  				)
  1114  				packet1.data = append(packet1.data, packet2.data...)
  1115  				Expect(conn.handlePacketImpl(packet1)).To(BeTrue())
  1116  			})
  1117  
  1118  			It("works with undecryptable packets", func() {
  1119  				conn.handshakeComplete = false
  1120  				hdrLen1, packet1 := getPacketWithLength(srcConnID, 456)
  1121  				hdrLen2, packet2 := getPacketWithLength(srcConnID, 123)
  1122  				gomock.InOrder(
  1123  					unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).Return(nil, handshake.ErrKeysNotYetAvailable),
  1124  					unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).DoAndReturn(func(_ *wire.Header, _ time.Time, data []byte, _ protocol.Version) (*unpackedPacket, error) {
  1125  						Expect(data).To(HaveLen(hdrLen2 + 123 - 3))
  1126  						return &unpackedPacket{
  1127  							encryptionLevel: protocol.EncryptionHandshake,
  1128  							data:            []byte{0},
  1129  							hdr:             &wire.ExtendedHeader{Header: wire.Header{}},
  1130  						}, nil
  1131  					}),
  1132  				)
  1133  				tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionInitial).AnyTimes()
  1134  				cryptoSetup.EXPECT().DiscardInitialKeys().AnyTimes()
  1135  				gomock.InOrder(
  1136  					tracer.EXPECT().BufferedPacket(gomock.Any(), protocol.ByteCount(len(packet1.data))),
  1137  					tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet2.data)), gomock.Any(), gomock.Any()),
  1138  				)
  1139  				packet1.data = append(packet1.data, packet2.data...)
  1140  				Expect(conn.handlePacketImpl(packet1)).To(BeTrue())
  1141  
  1142  				Expect(conn.undecryptablePackets).To(HaveLen(1))
  1143  				Expect(conn.undecryptablePackets[0].data).To(HaveLen(hdrLen1 + 456 - 3))
  1144  			})
  1145  
  1146  			It("ignores coalesced packet parts if the destination connection IDs don't match", func() {
  1147  				wrongConnID := protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef})
  1148  				Expect(srcConnID).ToNot(Equal(wrongConnID))
  1149  				hdrLen1, packet1 := getPacketWithLength(srcConnID, 456)
  1150  				unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).DoAndReturn(func(_ *wire.Header, _ time.Time, data []byte, _ protocol.Version) (*unpackedPacket, error) {
  1151  					Expect(data).To(HaveLen(hdrLen1 + 456 - 3))
  1152  					return &unpackedPacket{
  1153  						encryptionLevel: protocol.EncryptionHandshake,
  1154  						data:            []byte{0},
  1155  						hdr:             &wire.ExtendedHeader{Header: wire.Header{}},
  1156  					}, nil
  1157  				})
  1158  				_, packet2 := getPacketWithLength(wrongConnID, 123)
  1159  				tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionInitial).AnyTimes()
  1160  				cryptoSetup.EXPECT().DiscardInitialKeys().AnyTimes()
  1161  				// don't EXPECT any more calls to unpacker.UnpackLongHeader()
  1162  				gomock.InOrder(
  1163  					tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet1.data)), gomock.Any(), gomock.Any()),
  1164  					tracer.EXPECT().DroppedPacket(gomock.Any(), protocol.InvalidPacketNumber, protocol.ByteCount(len(packet2.data)), logging.PacketDropUnknownConnectionID),
  1165  				)
  1166  				packet1.data = append(packet1.data, packet2.data...)
  1167  				Expect(conn.handlePacketImpl(packet1)).To(BeTrue())
  1168  			})
  1169  		})
  1170  	})
  1171  
  1172  	Context("sending packets", func() {
  1173  		var (
  1174  			connDone chan struct{}
  1175  			sender   *MockSender
  1176  			sph      *mockackhandler.MockSentPacketHandler
  1177  		)
  1178  
  1179  		BeforeEach(func() {
  1180  			sender = NewMockSender(mockCtrl)
  1181  			sender.EXPECT().Run()
  1182  			sender.EXPECT().WouldBlock().AnyTimes()
  1183  			conn.sendQueue = sender
  1184  			connDone = make(chan struct{})
  1185  			sph = mockackhandler.NewMockSentPacketHandler(mockCtrl)
  1186  			conn.sentPacketHandler = sph
  1187  		})
  1188  
  1189  		AfterEach(func() {
  1190  			streamManager.EXPECT().CloseWithError(gomock.Any())
  1191  			sph.EXPECT().ECNMode(gomock.Any()).Return(protocol.ECNCE).MaxTimes(1)
  1192  			packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
  1193  			expectReplaceWithClosed()
  1194  			cryptoSetup.EXPECT().Close()
  1195  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  1196  			tracer.EXPECT().ClosedConnection(gomock.Any())
  1197  			tracer.EXPECT().Close()
  1198  			sender.EXPECT().Close()
  1199  			conn.CloseWithError(0, "")
  1200  			Eventually(conn.Context().Done()).Should(BeClosed())
  1201  			Eventually(connDone).Should(BeClosed())
  1202  		})
  1203  
  1204  		runConn := func() {
  1205  			go func() {
  1206  				defer GinkgoRecover()
  1207  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1208  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1209  				conn.run()
  1210  				close(connDone)
  1211  			}()
  1212  		}
  1213  
  1214  		It("sends packets", func() {
  1215  			conn.handshakeConfirmed = true
  1216  			sph.EXPECT().TimeUntilSend().AnyTimes()
  1217  			sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1218  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
  1219  			sph.EXPECT().ECNMode(true).Return(protocol.ECNNon).AnyTimes()
  1220  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1221  			runConn()
  1222  			p := shortHeaderPacket{
  1223  				DestConnID:      protocol.ParseConnectionID([]byte{1, 2, 3}),
  1224  				PacketNumber:    1337,
  1225  				PacketNumberLen: protocol.PacketNumberLen3,
  1226  				KeyPhase:        protocol.KeyPhaseOne,
  1227  			}
  1228  			expectAppendPacket(packer, p, []byte("foobar"))
  1229  			packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack).AnyTimes()
  1230  			sent := make(chan struct{})
  1231  			sender.EXPECT().WouldBlock().AnyTimes()
  1232  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(sent) })
  1233  			tracer.EXPECT().SentShortHeaderPacket(&logging.ShortHeader{
  1234  				DestConnectionID: p.DestConnID,
  1235  				PacketNumber:     p.PacketNumber,
  1236  				PacketNumberLen:  p.PacketNumberLen,
  1237  				KeyPhase:         p.KeyPhase,
  1238  			}, gomock.Any(), gomock.Any(), nil, []logging.Frame{})
  1239  			conn.scheduleSending()
  1240  			Eventually(sent).Should(BeClosed())
  1241  		})
  1242  
  1243  		It("doesn't send packets if there's nothing to send", func() {
  1244  			conn.handshakeConfirmed = true
  1245  			sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1246  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
  1247  			sph.EXPECT().ECNMode(true).AnyTimes()
  1248  			runConn()
  1249  			packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack).AnyTimes()
  1250  			conn.scheduleSending()
  1251  			time.Sleep(50 * time.Millisecond) // make sure there are no calls to mconn.Write()
  1252  		})
  1253  
  1254  		It("sends ACK only packets", func() {
  1255  			sph.EXPECT().TimeUntilSend().AnyTimes()
  1256  			sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1257  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAck)
  1258  			sph.EXPECT().ECNMode(gomock.Any()).Return(protocol.ECT1).AnyTimes()
  1259  			done := make(chan struct{})
  1260  			packer.EXPECT().PackCoalescedPacket(true, gomock.Any(), conn.version).Do(func(bool, protocol.ByteCount, protocol.Version) (*coalescedPacket, error) {
  1261  				close(done)
  1262  				return nil, nil
  1263  			})
  1264  			runConn()
  1265  			conn.scheduleSending()
  1266  			Eventually(done).Should(BeClosed())
  1267  		})
  1268  
  1269  		It("adds a BLOCKED frame when it is connection-level flow control blocked", func() {
  1270  			conn.handshakeConfirmed = true
  1271  			sph.EXPECT().TimeUntilSend().AnyTimes()
  1272  			sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1273  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
  1274  			sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
  1275  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1276  			fc := mocks.NewMockConnectionFlowController(mockCtrl)
  1277  			fc.EXPECT().IsNewlyBlocked().Return(true, protocol.ByteCount(1337))
  1278  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 13}, []byte("foobar"))
  1279  			packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack).AnyTimes()
  1280  			conn.connFlowController = fc
  1281  			runConn()
  1282  			sent := make(chan struct{})
  1283  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(sent) })
  1284  			tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), nil, []logging.Frame{})
  1285  			conn.scheduleSending()
  1286  			Eventually(sent).Should(BeClosed())
  1287  			frames, _ := conn.framer.AppendControlFrames(nil, 1000, protocol.Version1)
  1288  			Expect(frames).To(Equal([]ackhandler.Frame{{Frame: &logging.DataBlockedFrame{MaximumData: 1337}}}))
  1289  		})
  1290  
  1291  		It("doesn't send when the SentPacketHandler doesn't allow it", func() {
  1292  			sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1293  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone).AnyTimes()
  1294  			sph.EXPECT().TimeUntilSend().AnyTimes()
  1295  			runConn()
  1296  			conn.scheduleSending()
  1297  			time.Sleep(50 * time.Millisecond)
  1298  		})
  1299  
  1300  		for _, enc := range []protocol.EncryptionLevel{protocol.EncryptionInitial, protocol.EncryptionHandshake, protocol.Encryption1RTT} {
  1301  			encLevel := enc
  1302  
  1303  			Context(fmt.Sprintf("sending %s probe packets", encLevel), func() {
  1304  				var sendMode ackhandler.SendMode
  1305  				var getFrame func(protocol.ByteCount, protocol.Version) wire.Frame
  1306  
  1307  				BeforeEach(func() {
  1308  					//nolint:exhaustive
  1309  					switch encLevel {
  1310  					case protocol.EncryptionInitial:
  1311  						sendMode = ackhandler.SendPTOInitial
  1312  						getFrame = conn.retransmissionQueue.GetInitialFrame
  1313  					case protocol.EncryptionHandshake:
  1314  						sendMode = ackhandler.SendPTOHandshake
  1315  						getFrame = conn.retransmissionQueue.GetHandshakeFrame
  1316  					case protocol.Encryption1RTT:
  1317  						sendMode = ackhandler.SendPTOAppData
  1318  						getFrame = conn.retransmissionQueue.GetAppDataFrame
  1319  					}
  1320  				})
  1321  
  1322  				It("sends a probe packet", func() {
  1323  					sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1324  					sph.EXPECT().TimeUntilSend().AnyTimes()
  1325  					sph.EXPECT().SendMode(gomock.Any()).Return(sendMode)
  1326  					sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
  1327  					sph.EXPECT().QueueProbePacket(encLevel)
  1328  					sph.EXPECT().ECNMode(gomock.Any())
  1329  					p := getCoalescedPacket(123, enc != protocol.Encryption1RTT)
  1330  					packer.EXPECT().MaybePackProbePacket(encLevel, gomock.Any(), conn.version).Return(p, nil)
  1331  					sph.EXPECT().SentPacket(gomock.Any(), protocol.PacketNumber(123), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1332  					conn.sentPacketHandler = sph
  1333  					runConn()
  1334  					sent := make(chan struct{})
  1335  					sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(sent) })
  1336  					if enc == protocol.Encryption1RTT {
  1337  						tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), p.shortHdrPacket.Length, gomock.Any(), gomock.Any(), gomock.Any())
  1338  					} else {
  1339  						tracer.EXPECT().SentLongHeaderPacket(gomock.Any(), p.longHdrPackets[0].length, gomock.Any(), gomock.Any(), gomock.Any())
  1340  					}
  1341  					conn.scheduleSending()
  1342  					Eventually(sent).Should(BeClosed())
  1343  				})
  1344  
  1345  				It("sends a PING as a probe packet", func() {
  1346  					sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1347  					sph.EXPECT().TimeUntilSend().AnyTimes()
  1348  					sph.EXPECT().SendMode(gomock.Any()).Return(sendMode)
  1349  					sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
  1350  					sph.EXPECT().ECNMode(gomock.Any()).Return(protocol.ECT0)
  1351  					sph.EXPECT().QueueProbePacket(encLevel).Return(false)
  1352  					p := getCoalescedPacket(123, enc != protocol.Encryption1RTT)
  1353  					packer.EXPECT().MaybePackProbePacket(encLevel, gomock.Any(), conn.version).Return(p, nil)
  1354  					sph.EXPECT().SentPacket(gomock.Any(), protocol.PacketNumber(123), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1355  					runConn()
  1356  					sent := make(chan struct{})
  1357  					sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(sent) })
  1358  					if enc == protocol.Encryption1RTT {
  1359  						tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), p.shortHdrPacket.Length, logging.ECT0, gomock.Any(), gomock.Any())
  1360  					} else {
  1361  						tracer.EXPECT().SentLongHeaderPacket(gomock.Any(), p.longHdrPackets[0].length, logging.ECT0, gomock.Any(), gomock.Any())
  1362  					}
  1363  					conn.scheduleSending()
  1364  					Eventually(sent).Should(BeClosed())
  1365  					// We're using a mock packet packer in this test.
  1366  					// We therefore need to test separately that the PING was actually queued.
  1367  					Expect(getFrame(1000, protocol.Version1)).To(BeAssignableToTypeOf(&wire.PingFrame{}))
  1368  				})
  1369  			})
  1370  		}
  1371  	})
  1372  
  1373  	Context("packet pacing", func() {
  1374  		var (
  1375  			sph    *mockackhandler.MockSentPacketHandler
  1376  			sender *MockSender
  1377  		)
  1378  
  1379  		BeforeEach(func() {
  1380  			tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
  1381  			sph = mockackhandler.NewMockSentPacketHandler(mockCtrl)
  1382  			sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1383  			conn.handshakeConfirmed = true
  1384  			conn.handshakeComplete = true
  1385  			conn.sentPacketHandler = sph
  1386  			sender = NewMockSender(mockCtrl)
  1387  			sender.EXPECT().Run()
  1388  			conn.sendQueue = sender
  1389  			streamManager.EXPECT().CloseWithError(gomock.Any())
  1390  		})
  1391  
  1392  		AfterEach(func() {
  1393  			// make the go routine return
  1394  			sph.EXPECT().ECNMode(gomock.Any()).MaxTimes(1)
  1395  			packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
  1396  			expectReplaceWithClosed()
  1397  			cryptoSetup.EXPECT().Close()
  1398  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  1399  			tracer.EXPECT().ClosedConnection(gomock.Any())
  1400  			tracer.EXPECT().Close()
  1401  			sender.EXPECT().Close()
  1402  			conn.CloseWithError(0, "")
  1403  			Eventually(conn.Context().Done()).Should(BeClosed())
  1404  		})
  1405  
  1406  		It("sends multiple packets one by one immediately", func() {
  1407  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2)
  1408  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(2)
  1409  			sph.EXPECT().ECNMode(gomock.Any()).Times(2)
  1410  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited)
  1411  			sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour))
  1412  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, []byte("packet10"))
  1413  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, []byte("packet11"))
  1414  			sender.EXPECT().WouldBlock().AnyTimes()
  1415  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
  1416  				Expect(b.Data).To(Equal([]byte("packet10")))
  1417  			})
  1418  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
  1419  				Expect(b.Data).To(Equal([]byte("packet11")))
  1420  			})
  1421  			go func() {
  1422  				defer GinkgoRecover()
  1423  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1424  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1425  				conn.run()
  1426  			}()
  1427  			conn.scheduleSending()
  1428  			time.Sleep(50 * time.Millisecond) // make sure that only 2 packets are sent
  1429  		})
  1430  
  1431  		It("sends multiple packets one by one immediately, with GSO", func() {
  1432  			enableGSO()
  1433  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2)
  1434  			sph.EXPECT().ECNMode(true).Return(protocol.ECT1).Times(4)
  1435  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
  1436  			payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
  1437  			rand.Read(payload1)
  1438  			payload2 := make([]byte, conn.mtuDiscoverer.CurrentSize())
  1439  			rand.Read(payload2)
  1440  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, payload1)
  1441  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2)
  1442  			packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any()).Return(shortHeaderPacket{}, errNothingToPack)
  1443  			sender.EXPECT().WouldBlock().AnyTimes()
  1444  			sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
  1445  				Expect(b.Data).To(Equal(append(payload1, payload2...)))
  1446  			})
  1447  			go func() {
  1448  				defer GinkgoRecover()
  1449  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1450  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1451  				conn.run()
  1452  			}()
  1453  			conn.scheduleSending()
  1454  			time.Sleep(50 * time.Millisecond) // make sure that only 2 packets are sent
  1455  		})
  1456  
  1457  		It("stops appending packets when a smaller packet is packed, with GSO", func() {
  1458  			enableGSO()
  1459  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
  1460  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
  1461  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
  1462  			sph.EXPECT().ECNMode(true).Times(4)
  1463  			payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
  1464  			rand.Read(payload1)
  1465  			payload2 := make([]byte, conn.mtuDiscoverer.CurrentSize()-1)
  1466  			rand.Read(payload2)
  1467  			payload3 := make([]byte, conn.mtuDiscoverer.CurrentSize())
  1468  			rand.Read(payload3)
  1469  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, payload1)
  1470  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2)
  1471  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 12}, payload3)
  1472  			sender.EXPECT().WouldBlock().AnyTimes()
  1473  			sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
  1474  				Expect(b.Data).To(Equal(append(payload1, payload2...)))
  1475  			})
  1476  			sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
  1477  				Expect(b.Data).To(Equal(payload3))
  1478  			})
  1479  			go func() {
  1480  				defer GinkgoRecover()
  1481  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1482  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1483  				conn.run()
  1484  			}()
  1485  			conn.scheduleSending()
  1486  			time.Sleep(50 * time.Millisecond) // make sure that only 2 packets are sent
  1487  		})
  1488  
  1489  		It("stops appending packets when the ECN marking changes, with GSO", func() {
  1490  			enableGSO()
  1491  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
  1492  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
  1493  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
  1494  			sph.EXPECT().ECNMode(true).Return(protocol.ECT1).Times(2)
  1495  			sph.EXPECT().ECNMode(true).Return(protocol.ECT0).Times(2)
  1496  			payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
  1497  			rand.Read(payload1)
  1498  			payload2 := make([]byte, conn.mtuDiscoverer.CurrentSize())
  1499  			rand.Read(payload2)
  1500  			payload3 := make([]byte, conn.mtuDiscoverer.CurrentSize())
  1501  			rand.Read(payload3)
  1502  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, payload1)
  1503  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2)
  1504  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload3)
  1505  			sender.EXPECT().WouldBlock().AnyTimes()
  1506  			sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
  1507  				Expect(b.Data).To(Equal(append(payload1, payload2...)))
  1508  			})
  1509  			sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
  1510  				Expect(b.Data).To(Equal(payload3))
  1511  			})
  1512  			go func() {
  1513  				defer GinkgoRecover()
  1514  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1515  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1516  				conn.run()
  1517  			}()
  1518  			conn.scheduleSending()
  1519  			time.Sleep(50 * time.Millisecond) // make sure that only 2 packets are sent
  1520  		})
  1521  
  1522  		It("sends multiple packets, when the pacer allows immediate sending", func() {
  1523  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1524  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(2)
  1525  			sph.EXPECT().ECNMode(gomock.Any()).Times(2)
  1526  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, []byte("packet10"))
  1527  			packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
  1528  			sender.EXPECT().WouldBlock().AnyTimes()
  1529  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any())
  1530  			go func() {
  1531  				defer GinkgoRecover()
  1532  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1533  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1534  				conn.run()
  1535  			}()
  1536  			conn.scheduleSending()
  1537  			time.Sleep(50 * time.Millisecond) // make sure that only 1 packet is sent
  1538  		})
  1539  
  1540  		It("allows an ACK to be sent when pacing limited", func() {
  1541  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1542  			sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour))
  1543  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited)
  1544  			sph.EXPECT().ECNMode(gomock.Any())
  1545  			packer.EXPECT().PackAckOnlyPacket(gomock.Any(), conn.version).Return(shortHeaderPacket{PacketNumber: 123}, getPacketBuffer(), nil)
  1546  
  1547  			sender.EXPECT().WouldBlock().AnyTimes()
  1548  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any())
  1549  			go func() {
  1550  				defer GinkgoRecover()
  1551  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1552  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1553  				conn.run()
  1554  			}()
  1555  			conn.scheduleSending()
  1556  			time.Sleep(50 * time.Millisecond) // make sure that only 1 packet is sent
  1557  		})
  1558  
  1559  		// when becoming congestion limited, at some point the SendMode will change from SendAny to SendAck
  1560  		// we shouldn't send the ACK in the same run
  1561  		It("doesn't send an ACK right after becoming congestion limited", func() {
  1562  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1563  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny)
  1564  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAck)
  1565  			sph.EXPECT().ECNMode(gomock.Any()).Times(2)
  1566  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 100}, []byte("packet100"))
  1567  			sender.EXPECT().WouldBlock().AnyTimes()
  1568  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any())
  1569  			go func() {
  1570  				defer GinkgoRecover()
  1571  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1572  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1573  				conn.run()
  1574  			}()
  1575  			conn.scheduleSending()
  1576  			time.Sleep(50 * time.Millisecond) // make sure that only 1 packet is sent
  1577  		})
  1578  
  1579  		It("paces packets", func() {
  1580  			pacingDelay := scaleDuration(100 * time.Millisecond)
  1581  			gomock.InOrder(
  1582  				sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny),
  1583  				sph.EXPECT().ECNMode(gomock.Any()),
  1584  				expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 100}, []byte("packet100")),
  1585  				sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()),
  1586  				sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited),
  1587  				sph.EXPECT().TimeUntilSend().Return(time.Now().Add(pacingDelay)),
  1588  				sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny),
  1589  				sph.EXPECT().ECNMode(gomock.Any()),
  1590  				expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 101}, []byte("packet101")),
  1591  				sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()),
  1592  				sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited),
  1593  				sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour)),
  1594  			)
  1595  			written := make(chan struct{}, 2)
  1596  			sender.EXPECT().WouldBlock().AnyTimes()
  1597  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { written <- struct{}{} }).Times(2)
  1598  			go func() {
  1599  				defer GinkgoRecover()
  1600  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1601  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1602  				conn.run()
  1603  			}()
  1604  			conn.scheduleSending()
  1605  			Eventually(written).Should(HaveLen(1))
  1606  			Consistently(written, pacingDelay/2).Should(HaveLen(1))
  1607  			Eventually(written, 2*pacingDelay).Should(HaveLen(2))
  1608  		})
  1609  
  1610  		It("sends multiple packets at once", func() {
  1611  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
  1612  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
  1613  			sph.EXPECT().ECNMode(gomock.Any()).Times(3)
  1614  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited)
  1615  			sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour))
  1616  			for pn := protocol.PacketNumber(1000); pn < 1003; pn++ {
  1617  				expectAppendPacket(packer, shortHeaderPacket{PacketNumber: pn}, []byte("packet"))
  1618  			}
  1619  			written := make(chan struct{}, 3)
  1620  			sender.EXPECT().WouldBlock().AnyTimes()
  1621  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { written <- struct{}{} }).Times(3)
  1622  			go func() {
  1623  				defer GinkgoRecover()
  1624  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1625  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1626  				conn.run()
  1627  			}()
  1628  			conn.scheduleSending()
  1629  			Eventually(written).Should(HaveLen(3))
  1630  		})
  1631  
  1632  		for _, withGSO := range []bool{false, true} {
  1633  			withGSO := withGSO
  1634  			It(fmt.Sprintf("doesn't try to send if the send queue is full: %t", withGSO), func() {
  1635  				if withGSO {
  1636  					enableGSO()
  1637  				}
  1638  				available := make(chan struct{}, 1)
  1639  				sender.EXPECT().WouldBlock().Return(true)
  1640  				sender.EXPECT().Available().Return(available)
  1641  				go func() {
  1642  					defer GinkgoRecover()
  1643  					cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1644  					cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1645  					conn.run()
  1646  				}()
  1647  				conn.scheduleSending()
  1648  				time.Sleep(scaleDuration(50 * time.Millisecond))
  1649  
  1650  				written := make(chan struct{})
  1651  				sender.EXPECT().WouldBlock().AnyTimes()
  1652  				sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1653  				sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
  1654  				sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
  1655  				expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 1000}, []byte("packet1000"))
  1656  				packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
  1657  				sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { close(written) })
  1658  				available <- struct{}{}
  1659  				Eventually(written).Should(BeClosed())
  1660  			})
  1661  		}
  1662  
  1663  		It("stops sending when there are new packets to receive", func() {
  1664  			sender.EXPECT().WouldBlock().AnyTimes()
  1665  			go func() {
  1666  				defer GinkgoRecover()
  1667  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1668  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1669  				conn.run()
  1670  			}()
  1671  
  1672  			written := make(chan struct{})
  1673  			sender.EXPECT().WouldBlock().AnyTimes()
  1674  			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) {
  1675  				sph.EXPECT().ReceivedBytes(gomock.Any())
  1676  				conn.handlePacket(receivedPacket{buffer: getPacketBuffer()})
  1677  			})
  1678  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
  1679  			sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
  1680  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, []byte("packet10"))
  1681  			packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
  1682  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { close(written) })
  1683  
  1684  			conn.scheduleSending()
  1685  			time.Sleep(scaleDuration(50 * time.Millisecond))
  1686  
  1687  			Eventually(written).Should(BeClosed())
  1688  		})
  1689  
  1690  		It("stops sending when the send queue is full", func() {
  1691  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1692  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny)
  1693  			sph.EXPECT().ECNMode(gomock.Any())
  1694  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 1000}, []byte("packet1000"))
  1695  			written := make(chan struct{}, 1)
  1696  			sender.EXPECT().WouldBlock()
  1697  			sender.EXPECT().WouldBlock().Return(true).Times(2)
  1698  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { written <- struct{}{} })
  1699  			go func() {
  1700  				defer GinkgoRecover()
  1701  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1702  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1703  				conn.run()
  1704  			}()
  1705  			available := make(chan struct{}, 1)
  1706  			sender.EXPECT().Available().Return(available)
  1707  			conn.scheduleSending()
  1708  			Eventually(written).Should(Receive())
  1709  			time.Sleep(scaleDuration(50 * time.Millisecond))
  1710  
  1711  			// now make room in the send queue
  1712  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1713  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
  1714  			sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
  1715  			sender.EXPECT().WouldBlock().AnyTimes()
  1716  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 1001}, []byte("packet1001"))
  1717  			packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
  1718  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { written <- struct{}{} })
  1719  			available <- struct{}{}
  1720  			Eventually(written).Should(Receive())
  1721  
  1722  			// The send queue is not full any more. Sending on the available channel should have no effect.
  1723  			available <- struct{}{}
  1724  			time.Sleep(scaleDuration(50 * time.Millisecond))
  1725  		})
  1726  
  1727  		It("doesn't set a pacing timer when there is no data to send", func() {
  1728  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
  1729  			sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
  1730  			sender.EXPECT().WouldBlock().AnyTimes()
  1731  			packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
  1732  			// don't EXPECT any calls to mconn.Write()
  1733  			go func() {
  1734  				defer GinkgoRecover()
  1735  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1736  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1737  				conn.run()
  1738  			}()
  1739  			conn.scheduleSending() // no packet will get sent
  1740  			time.Sleep(50 * time.Millisecond)
  1741  		})
  1742  
  1743  		It("sends a Path MTU probe packet", func() {
  1744  			mtuDiscoverer := NewMockMTUDiscoverer(mockCtrl)
  1745  			conn.mtuDiscoverer = mtuDiscoverer
  1746  			conn.config.DisablePathMTUDiscovery = false
  1747  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1748  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny)
  1749  			sph.EXPECT().ECNMode(true)
  1750  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
  1751  			written := make(chan struct{}, 1)
  1752  			sender.EXPECT().WouldBlock().AnyTimes()
  1753  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*packetBuffer, uint16, protocol.ECN) { written <- struct{}{} })
  1754  			mtuDiscoverer.EXPECT().ShouldSendProbe(gomock.Any()).Return(true)
  1755  			ping := ackhandler.Frame{Frame: &wire.PingFrame{}}
  1756  			mtuDiscoverer.EXPECT().GetPing().Return(ping, protocol.ByteCount(1234))
  1757  			packer.EXPECT().PackMTUProbePacket(ping, protocol.ByteCount(1234), conn.version).Return(shortHeaderPacket{PacketNumber: 1}, getPacketBuffer(), nil)
  1758  			go func() {
  1759  				defer GinkgoRecover()
  1760  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1761  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1762  				conn.run()
  1763  			}()
  1764  			conn.scheduleSending()
  1765  			Eventually(written).Should(Receive())
  1766  			mtuDiscoverer.EXPECT().CurrentSize().Return(protocol.ByteCount(1234))
  1767  		})
  1768  	})
  1769  
  1770  	Context("scheduling sending", func() {
  1771  		var sender *MockSender
  1772  
  1773  		BeforeEach(func() {
  1774  			sender = NewMockSender(mockCtrl)
  1775  			sender.EXPECT().WouldBlock().AnyTimes()
  1776  			sender.EXPECT().Run()
  1777  			conn.sendQueue = sender
  1778  			conn.handshakeConfirmed = true
  1779  		})
  1780  
  1781  		AfterEach(func() {
  1782  			// make the go routine return
  1783  			expectReplaceWithClosed()
  1784  			streamManager.EXPECT().CloseWithError(gomock.Any())
  1785  			packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
  1786  			cryptoSetup.EXPECT().Close()
  1787  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  1788  			sender.EXPECT().Close()
  1789  			tracer.EXPECT().ClosedConnection(gomock.Any())
  1790  			tracer.EXPECT().Close()
  1791  			conn.CloseWithError(0, "")
  1792  			Eventually(conn.Context().Done()).Should(BeClosed())
  1793  		})
  1794  
  1795  		It("sends when scheduleSending is called", func() {
  1796  			sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  1797  			sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1798  			sph.EXPECT().TimeUntilSend().AnyTimes()
  1799  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
  1800  			sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
  1801  
  1802  			sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1803  			conn.sentPacketHandler = sph
  1804  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 1}, []byte("packet1"))
  1805  			packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
  1806  
  1807  			go func() {
  1808  				defer GinkgoRecover()
  1809  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1810  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1811  				conn.run()
  1812  			}()
  1813  			// don't EXPECT any calls to mconn.Write()
  1814  			time.Sleep(50 * time.Millisecond)
  1815  			// only EXPECT calls after scheduleSending is called
  1816  			written := make(chan struct{})
  1817  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(written) })
  1818  			tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
  1819  			conn.scheduleSending()
  1820  			Eventually(written).Should(BeClosed())
  1821  		})
  1822  
  1823  		It("sets the timer to the ack timer", func() {
  1824  			expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 1234}, []byte("packet1234"))
  1825  			packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack)
  1826  			sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  1827  			sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1828  			sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
  1829  			sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
  1830  			sph.EXPECT().SentPacket(gomock.Any(), protocol.PacketNumber(1234), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  1831  			conn.sentPacketHandler = sph
  1832  			rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl)
  1833  			rph.EXPECT().GetAlarmTimeout().Return(time.Now().Add(10 * time.Millisecond))
  1834  			// make the run loop wait
  1835  			rph.EXPECT().GetAlarmTimeout().Return(time.Now().Add(time.Hour)).MaxTimes(1)
  1836  			conn.receivedPacketHandler = rph
  1837  
  1838  			written := make(chan struct{})
  1839  			sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(*packetBuffer, uint16, protocol.ECN) { close(written) })
  1840  			tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
  1841  			go func() {
  1842  				defer GinkgoRecover()
  1843  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1844  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1845  				conn.run()
  1846  			}()
  1847  			Eventually(written).Should(BeClosed())
  1848  		})
  1849  	})
  1850  
  1851  	It("sends coalesced packets before the handshake is confirmed", func() {
  1852  		conn.handshakeComplete = false
  1853  		conn.handshakeConfirmed = false
  1854  		sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  1855  		conn.sentPacketHandler = sph
  1856  		buffer := getPacketBuffer()
  1857  		buffer.Data = append(buffer.Data, []byte("foobar")...)
  1858  		packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).Return(&coalescedPacket{
  1859  			buffer: buffer,
  1860  			longHdrPackets: []*longHeaderPacket{
  1861  				{
  1862  					header: &wire.ExtendedHeader{
  1863  						Header:       wire.Header{Type: protocol.PacketTypeInitial},
  1864  						PacketNumber: 13,
  1865  					},
  1866  					length: 123,
  1867  				},
  1868  				{
  1869  					header: &wire.ExtendedHeader{
  1870  						Header:       wire.Header{Type: protocol.PacketTypeHandshake},
  1871  						PacketNumber: 37,
  1872  					},
  1873  					length: 1234,
  1874  				},
  1875  			},
  1876  		}, nil)
  1877  		packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).AnyTimes()
  1878  
  1879  		sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1880  		sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
  1881  		sph.EXPECT().ECNMode(false).Return(protocol.ECT1).AnyTimes()
  1882  		sph.EXPECT().TimeUntilSend().Return(time.Now()).AnyTimes()
  1883  		gomock.InOrder(
  1884  			sph.EXPECT().SentPacket(gomock.Any(), protocol.PacketNumber(13), gomock.Any(), gomock.Any(), gomock.Any(), protocol.EncryptionInitial, protocol.ECT1, protocol.ByteCount(123), gomock.Any()),
  1885  			sph.EXPECT().SentPacket(gomock.Any(), protocol.PacketNumber(37), gomock.Any(), gomock.Any(), gomock.Any(), protocol.EncryptionHandshake, protocol.ECT1, protocol.ByteCount(1234), gomock.Any()),
  1886  		)
  1887  		gomock.InOrder(
  1888  			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) {
  1889  				Expect(hdr.Type).To(Equal(protocol.PacketTypeInitial))
  1890  			}),
  1891  			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) {
  1892  				Expect(hdr.Type).To(Equal(protocol.PacketTypeHandshake))
  1893  			}),
  1894  		)
  1895  
  1896  		sent := make(chan struct{})
  1897  		mconn.EXPECT().Write([]byte("foobar"), uint16(0), protocol.ECT1).Do(func([]byte, uint16, protocol.ECN) error { close(sent); return nil })
  1898  
  1899  		go func() {
  1900  			defer GinkgoRecover()
  1901  			cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  1902  			cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1903  			conn.run()
  1904  		}()
  1905  
  1906  		conn.scheduleSending()
  1907  		Eventually(sent).Should(BeClosed())
  1908  
  1909  		// make sure the go routine returns
  1910  		streamManager.EXPECT().CloseWithError(gomock.Any())
  1911  		expectReplaceWithClosed()
  1912  		packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
  1913  		cryptoSetup.EXPECT().Close()
  1914  		mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  1915  		tracer.EXPECT().ClosedConnection(gomock.Any())
  1916  		tracer.EXPECT().Close()
  1917  		conn.CloseWithError(0, "")
  1918  		Eventually(conn.Context().Done()).Should(BeClosed())
  1919  	})
  1920  
  1921  	It("cancels the HandshakeComplete context when the handshake completes", func() {
  1922  		packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).AnyTimes()
  1923  		sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  1924  		conn.sentPacketHandler = sph
  1925  		tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionHandshake)
  1926  		tracer.EXPECT().ChoseALPN(gomock.Any())
  1927  		sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  1928  		sph.EXPECT().TimeUntilSend().AnyTimes()
  1929  		sph.EXPECT().SendMode(gomock.Any()).AnyTimes()
  1930  		sph.EXPECT().DropPackets(protocol.EncryptionHandshake)
  1931  		sph.EXPECT().SetHandshakeConfirmed()
  1932  		connRunner.EXPECT().Retire(clientDestConnID)
  1933  		cryptoSetup.EXPECT().SetHandshakeConfirmed()
  1934  		cryptoSetup.EXPECT().GetSessionTicket()
  1935  		cryptoSetup.EXPECT().ConnectionState()
  1936  		handshakeCtx := conn.HandshakeComplete()
  1937  		Consistently(handshakeCtx).ShouldNot(BeClosed())
  1938  		Expect(conn.handleHandshakeComplete()).To(Succeed())
  1939  		Eventually(handshakeCtx).Should(BeClosed())
  1940  	})
  1941  
  1942  	It("sends a session ticket when the handshake completes", func() {
  1943  		const size = protocol.MaxPostHandshakeCryptoFrameSize * 3 / 2
  1944  		packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).AnyTimes()
  1945  		connRunner.EXPECT().Retire(clientDestConnID)
  1946  		conn.sentPacketHandler.DropPackets(protocol.EncryptionInitial)
  1947  		tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionHandshake)
  1948  		tracer.EXPECT().ChoseALPN(gomock.Any())
  1949  		cryptoSetup.EXPECT().SetHandshakeConfirmed()
  1950  		cryptoSetup.EXPECT().GetSessionTicket().Return(make([]byte, size), nil)
  1951  		cryptoSetup.EXPECT().ConnectionState()
  1952  
  1953  		handshakeCtx := conn.HandshakeComplete()
  1954  		Consistently(handshakeCtx).ShouldNot(BeClosed())
  1955  		Expect(conn.handleHandshakeComplete()).To(Succeed())
  1956  		var frames []ackhandler.Frame
  1957  		Eventually(func() []ackhandler.Frame {
  1958  			frames, _ = conn.framer.AppendControlFrames(nil, protocol.MaxByteCount, protocol.Version1)
  1959  			return frames
  1960  		}).ShouldNot(BeEmpty())
  1961  		var count int
  1962  		var s int
  1963  		for _, f := range frames {
  1964  			if cf, ok := f.Frame.(*wire.CryptoFrame); ok {
  1965  				count++
  1966  				s += len(cf.Data)
  1967  				Expect(f.Frame.Length(conn.version)).To(BeNumerically("<=", protocol.MaxPostHandshakeCryptoFrameSize))
  1968  			}
  1969  		}
  1970  		Expect(size).To(BeEquivalentTo(s))
  1971  	})
  1972  
  1973  	It("doesn't cancel the HandshakeComplete context when the handshake fails", func() {
  1974  		packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).AnyTimes()
  1975  		streamManager.EXPECT().CloseWithError(gomock.Any())
  1976  		expectReplaceWithClosed()
  1977  		packer.EXPECT().PackConnectionClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
  1978  		cryptoSetup.EXPECT().Close()
  1979  		tracer.EXPECT().ClosedConnection(gomock.Any())
  1980  		tracer.EXPECT().Close()
  1981  		go func() {
  1982  			defer GinkgoRecover()
  1983  			cryptoSetup.EXPECT().StartHandshake()
  1984  			cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  1985  			conn.run()
  1986  		}()
  1987  		handshakeCtx := conn.HandshakeComplete()
  1988  		Consistently(handshakeCtx).ShouldNot(BeClosed())
  1989  		mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  1990  		conn.closeLocal(errors.New("handshake error"))
  1991  		Consistently(handshakeCtx).ShouldNot(BeClosed())
  1992  		Eventually(conn.Context().Done()).Should(BeClosed())
  1993  	})
  1994  
  1995  	It("sends a HANDSHAKE_DONE frame when the handshake completes", func() {
  1996  		sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  1997  		sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
  1998  		sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
  1999  		sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
  2000  		sph.EXPECT().TimeUntilSend().AnyTimes()
  2001  		sph.EXPECT().SetHandshakeConfirmed()
  2002  		sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  2003  		mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  2004  		tracer.EXPECT().SentShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  2005  		tracer.EXPECT().ChoseALPN(gomock.Any())
  2006  		conn.sentPacketHandler = sph
  2007  		done := make(chan struct{})
  2008  		connRunner.EXPECT().Retire(clientDestConnID)
  2009  		packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).DoAndReturn(func(_ *packetBuffer, _ protocol.ByteCount, v protocol.Version) (shortHeaderPacket, error) {
  2010  			frames, _ := conn.framer.AppendControlFrames(nil, protocol.MaxByteCount, v)
  2011  			Expect(frames).ToNot(BeEmpty())
  2012  			Expect(frames[0].Frame).To(BeEquivalentTo(&wire.HandshakeDoneFrame{}))
  2013  			defer close(done)
  2014  			return shortHeaderPacket{}, nil
  2015  		})
  2016  		packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), conn.version).Return(shortHeaderPacket{}, errNothingToPack).AnyTimes()
  2017  		tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionHandshake)
  2018  		sph.EXPECT().DropPackets(protocol.EncryptionHandshake)
  2019  		go func() {
  2020  			defer GinkgoRecover()
  2021  			cryptoSetup.EXPECT().StartHandshake()
  2022  			cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventHandshakeComplete})
  2023  			cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2024  			cryptoSetup.EXPECT().SetHandshakeConfirmed()
  2025  			cryptoSetup.EXPECT().GetSessionTicket()
  2026  			cryptoSetup.EXPECT().ConnectionState()
  2027  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  2028  			Expect(conn.handleHandshakeComplete()).To(Succeed())
  2029  			conn.run()
  2030  		}()
  2031  		Eventually(done).Should(BeClosed())
  2032  		// make sure the go routine returns
  2033  		streamManager.EXPECT().CloseWithError(gomock.Any())
  2034  		expectReplaceWithClosed()
  2035  		packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
  2036  		cryptoSetup.EXPECT().Close()
  2037  		tracer.EXPECT().ClosedConnection(gomock.Any())
  2038  		tracer.EXPECT().Close()
  2039  		conn.CloseWithError(0, "")
  2040  		Eventually(conn.Context().Done()).Should(BeClosed())
  2041  	})
  2042  
  2043  	It("doesn't return a run error when closing", func() {
  2044  		done := make(chan struct{})
  2045  		go func() {
  2046  			defer GinkgoRecover()
  2047  			cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2048  			cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2049  			Expect(conn.run()).To(Succeed())
  2050  			close(done)
  2051  		}()
  2052  		streamManager.EXPECT().CloseWithError(gomock.Any())
  2053  		cryptoSetup.EXPECT().Close()
  2054  		connRunner.EXPECT().Remove(gomock.Any()).AnyTimes()
  2055  		tracer.EXPECT().ClosedConnection(gomock.Any())
  2056  		tracer.EXPECT().Close()
  2057  		conn.destroy(nil)
  2058  		Eventually(done).Should(BeClosed())
  2059  		Expect(context.Cause(conn.Context())).To(MatchError(context.Canceled))
  2060  	})
  2061  
  2062  	It("passes errors to the connection runner", func() {
  2063  		testErr := errors.New("handshake error")
  2064  		expectedErr := &qerr.ApplicationError{
  2065  			ErrorCode:    0x1337,
  2066  			ErrorMessage: testErr.Error(),
  2067  		}
  2068  		done := make(chan struct{})
  2069  		go func() {
  2070  			defer GinkgoRecover()
  2071  			cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2072  			cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2073  			err := conn.run()
  2074  			Expect(err).To(MatchError(expectedErr))
  2075  			close(done)
  2076  		}()
  2077  		streamManager.EXPECT().CloseWithError(gomock.Any())
  2078  		expectReplaceWithClosed()
  2079  		packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
  2080  		cryptoSetup.EXPECT().Close()
  2081  		mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  2082  		tracer.EXPECT().ClosedConnection(gomock.Any())
  2083  		tracer.EXPECT().Close()
  2084  		Expect(conn.CloseWithError(0x1337, testErr.Error())).To(Succeed())
  2085  		Eventually(done).Should(BeClosed())
  2086  		Expect(context.Cause(conn.Context())).To(MatchError(expectedErr))
  2087  	})
  2088  
  2089  	Context("transport parameters", func() {
  2090  		It("processes transport parameters received from the client", func() {
  2091  			params := &wire.TransportParameters{
  2092  				MaxIdleTimeout:                90 * time.Second,
  2093  				InitialMaxStreamDataBidiLocal: 0x5000,
  2094  				InitialMaxData:                0x5000,
  2095  				ActiveConnectionIDLimit:       3,
  2096  				// marshaling always sets it to this value
  2097  				MaxUDPPayloadSize:         protocol.MaxPacketBufferSize,
  2098  				InitialSourceConnectionID: destConnID,
  2099  			}
  2100  			streamManager.EXPECT().UpdateLimits(params)
  2101  			packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).MaxTimes(3)
  2102  			Expect(conn.earlyConnReady()).ToNot(BeClosed())
  2103  			tracer.EXPECT().ReceivedTransportParameters(params)
  2104  			conn.handleTransportParameters(params)
  2105  			Expect(conn.earlyConnReady()).To(BeClosed())
  2106  		})
  2107  	})
  2108  
  2109  	Context("keep-alives", func() {
  2110  		setRemoteIdleTimeout := func(t time.Duration) {
  2111  			streamManager.EXPECT().UpdateLimits(gomock.Any())
  2112  			tracer.EXPECT().ReceivedTransportParameters(gomock.Any())
  2113  			conn.handleTransportParameters(&wire.TransportParameters{
  2114  				MaxIdleTimeout:            t,
  2115  				InitialSourceConnectionID: destConnID,
  2116  			})
  2117  		}
  2118  
  2119  		runConn := func() {
  2120  			go func() {
  2121  				defer GinkgoRecover()
  2122  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2123  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2124  				conn.run()
  2125  			}()
  2126  		}
  2127  
  2128  		BeforeEach(func() {
  2129  			conn.config.MaxIdleTimeout = 30 * time.Second
  2130  			conn.config.KeepAlivePeriod = 15 * time.Second
  2131  			conn.receivedPacketHandler.ReceivedPacket(0, protocol.ECNNon, protocol.EncryptionHandshake, time.Now(), true)
  2132  		})
  2133  
  2134  		AfterEach(func() {
  2135  			// make the go routine return
  2136  			expectReplaceWithClosed()
  2137  			streamManager.EXPECT().CloseWithError(gomock.Any())
  2138  			packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
  2139  			cryptoSetup.EXPECT().Close()
  2140  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  2141  			tracer.EXPECT().ClosedConnection(gomock.Any())
  2142  			tracer.EXPECT().Close()
  2143  			conn.CloseWithError(0, "")
  2144  			Eventually(conn.Context().Done()).Should(BeClosed())
  2145  		})
  2146  
  2147  		It("sends a PING as a keep-alive after half the idle timeout", func() {
  2148  			setRemoteIdleTimeout(5 * time.Second)
  2149  			conn.lastPacketReceivedTime = time.Now().Add(-5 * time.Second / 2)
  2150  			sent := make(chan struct{})
  2151  			packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).Do(func(bool, protocol.ByteCount, protocol.Version) (*coalescedPacket, error) {
  2152  				close(sent)
  2153  				return nil, nil
  2154  			})
  2155  			runConn()
  2156  			Eventually(sent).Should(BeClosed())
  2157  		})
  2158  
  2159  		It("sends a PING after a maximum of protocol.MaxKeepAliveInterval", func() {
  2160  			conn.config.MaxIdleTimeout = time.Hour
  2161  			setRemoteIdleTimeout(time.Hour)
  2162  			conn.lastPacketReceivedTime = time.Now().Add(-protocol.MaxKeepAliveInterval).Add(-time.Millisecond)
  2163  			sent := make(chan struct{})
  2164  			packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).Do(func(bool, protocol.ByteCount, protocol.Version) (*coalescedPacket, error) {
  2165  				close(sent)
  2166  				return nil, nil
  2167  			})
  2168  			runConn()
  2169  			Eventually(sent).Should(BeClosed())
  2170  		})
  2171  
  2172  		It("doesn't send a PING packet if keep-alive is disabled", func() {
  2173  			setRemoteIdleTimeout(5 * time.Second)
  2174  			conn.config.KeepAlivePeriod = 0
  2175  			conn.lastPacketReceivedTime = time.Now().Add(-time.Second * 5 / 2)
  2176  			runConn()
  2177  			// don't EXPECT() any calls to mconn.Write()
  2178  			time.Sleep(50 * time.Millisecond)
  2179  		})
  2180  
  2181  		It("doesn't send a PING if the handshake isn't completed yet", func() {
  2182  			conn.config.HandshakeIdleTimeout = time.Hour
  2183  			conn.handshakeComplete = false
  2184  			// Needs to be shorter than our idle timeout.
  2185  			// Otherwise we'll try to send a CONNECTION_CLOSE.
  2186  			conn.lastPacketReceivedTime = time.Now().Add(-20 * time.Second)
  2187  			runConn()
  2188  			// don't EXPECT() any calls to mconn.Write()
  2189  			time.Sleep(50 * time.Millisecond)
  2190  		})
  2191  
  2192  		It("send PING as keep-alive earliest after 1.5 times the PTO", func() {
  2193  			conn.config.KeepAlivePeriod = time.Microsecond
  2194  			pto := conn.rttStats.PTO(true)
  2195  			conn.lastPacketReceivedTime = time.Now()
  2196  			sentPingTimeChan := make(chan time.Time)
  2197  			packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).Do(func(bool, protocol.ByteCount, protocol.Version) (*coalescedPacket, error) {
  2198  				sentPingTimeChan <- time.Now()
  2199  				return nil, nil
  2200  			})
  2201  			runConn()
  2202  			sentPingTime := <-sentPingTimeChan
  2203  			Expect(sentPingTime.Sub(conn.lastPacketReceivedTime)).To(BeNumerically(">", pto*3/2))
  2204  		})
  2205  	})
  2206  
  2207  	Context("timeouts", func() {
  2208  		BeforeEach(func() {
  2209  			streamManager.EXPECT().CloseWithError(gomock.Any())
  2210  		})
  2211  
  2212  		It("times out due to no network activity", func() {
  2213  			connRunner.EXPECT().Remove(gomock.Any()).Times(2)
  2214  			conn.lastPacketReceivedTime = time.Now().Add(-time.Hour)
  2215  			done := make(chan struct{})
  2216  			cryptoSetup.EXPECT().Close()
  2217  			gomock.InOrder(
  2218  				tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) {
  2219  					Expect(e).To(MatchError(&qerr.IdleTimeoutError{}))
  2220  				}),
  2221  				tracer.EXPECT().Close(),
  2222  			)
  2223  			go func() {
  2224  				defer GinkgoRecover()
  2225  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2226  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2227  				err := conn.run()
  2228  				nerr, ok := err.(net.Error)
  2229  				Expect(ok).To(BeTrue())
  2230  				Expect(nerr.Timeout()).To(BeTrue())
  2231  				Expect(err).To(MatchError(qerr.ErrIdleTimeout))
  2232  				close(done)
  2233  			}()
  2234  			Eventually(done).Should(BeClosed())
  2235  		})
  2236  
  2237  		It("times out due to non-completed handshake", func() {
  2238  			conn.handshakeComplete = false
  2239  			conn.creationTime = time.Now().Add(-2 * protocol.DefaultHandshakeIdleTimeout).Add(-time.Second)
  2240  			connRunner.EXPECT().Remove(gomock.Any()).Times(2)
  2241  			cryptoSetup.EXPECT().Close()
  2242  			gomock.InOrder(
  2243  				tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) {
  2244  					Expect(e).To(MatchError(&HandshakeTimeoutError{}))
  2245  				}),
  2246  				tracer.EXPECT().Close(),
  2247  			)
  2248  			done := make(chan struct{})
  2249  			go func() {
  2250  				defer GinkgoRecover()
  2251  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2252  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2253  				err := conn.run()
  2254  				nerr, ok := err.(net.Error)
  2255  				Expect(ok).To(BeTrue())
  2256  				Expect(nerr.Timeout()).To(BeTrue())
  2257  				Expect(err).To(MatchError(qerr.ErrHandshakeTimeout))
  2258  				close(done)
  2259  			}()
  2260  			Eventually(done).Should(BeClosed())
  2261  		})
  2262  
  2263  		It("does not use the idle timeout before the handshake complete", func() {
  2264  			conn.handshakeComplete = false
  2265  			conn.config.HandshakeIdleTimeout = 9999 * time.Second
  2266  			conn.config.MaxIdleTimeout = 9999 * time.Second
  2267  			conn.lastPacketReceivedTime = time.Now().Add(-time.Minute)
  2268  			packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).DoAndReturn(func(e *qerr.ApplicationError, _ protocol.ByteCount, _ protocol.Version) (*coalescedPacket, error) {
  2269  				Expect(e.ErrorCode).To(BeZero())
  2270  				return &coalescedPacket{buffer: getPacketBuffer()}, nil
  2271  			})
  2272  			gomock.InOrder(
  2273  				tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) {
  2274  					idleTimeout := &IdleTimeoutError{}
  2275  					handshakeTimeout := &HandshakeTimeoutError{}
  2276  					Expect(errors.As(e, &idleTimeout)).To(BeFalse())
  2277  					Expect(errors.As(e, &handshakeTimeout)).To(BeFalse())
  2278  				}),
  2279  				tracer.EXPECT().Close(),
  2280  			)
  2281  			// the handshake timeout is irrelevant here, since it depends on the time the connection was created,
  2282  			// and not on the last network activity
  2283  			go func() {
  2284  				defer GinkgoRecover()
  2285  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2286  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2287  				conn.run()
  2288  			}()
  2289  			Consistently(conn.Context().Done()).ShouldNot(BeClosed())
  2290  			// make the go routine return
  2291  			expectReplaceWithClosed()
  2292  			cryptoSetup.EXPECT().Close()
  2293  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  2294  			conn.CloseWithError(0, "")
  2295  			Eventually(conn.Context().Done()).Should(BeClosed())
  2296  		})
  2297  
  2298  		It("closes the connection due to the idle timeout before handshake", func() {
  2299  			conn.config.HandshakeIdleTimeout = scaleDuration(25 * time.Millisecond)
  2300  			packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).AnyTimes()
  2301  			connRunner.EXPECT().Remove(gomock.Any()).AnyTimes()
  2302  			cryptoSetup.EXPECT().Close()
  2303  			gomock.InOrder(
  2304  				tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) {
  2305  					Expect(e).To(MatchError(&IdleTimeoutError{}))
  2306  				}),
  2307  				tracer.EXPECT().Close(),
  2308  			)
  2309  			done := make(chan struct{})
  2310  			conn.handshakeComplete = false
  2311  			go func() {
  2312  				defer GinkgoRecover()
  2313  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2314  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2315  				cryptoSetup.EXPECT().GetSessionTicket().MaxTimes(1)
  2316  				err := conn.run()
  2317  				nerr, ok := err.(net.Error)
  2318  				Expect(ok).To(BeTrue())
  2319  				Expect(nerr.Timeout()).To(BeTrue())
  2320  				Expect(err).To(MatchError(qerr.ErrIdleTimeout))
  2321  				close(done)
  2322  			}()
  2323  			Eventually(done).Should(BeClosed())
  2324  		})
  2325  
  2326  		It("closes the connection due to the idle timeout after handshake", func() {
  2327  			conn.sentPacketHandler.DropPackets(protocol.EncryptionInitial)
  2328  			packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).AnyTimes()
  2329  			gomock.InOrder(
  2330  				connRunner.EXPECT().Retire(clientDestConnID),
  2331  				connRunner.EXPECT().Remove(gomock.Any()),
  2332  			)
  2333  			cryptoSetup.EXPECT().Close()
  2334  			gomock.InOrder(
  2335  				tracer.EXPECT().ChoseALPN(gomock.Any()),
  2336  				tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionHandshake),
  2337  				tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) {
  2338  					Expect(e).To(MatchError(&IdleTimeoutError{}))
  2339  				}),
  2340  				tracer.EXPECT().Close(),
  2341  			)
  2342  			conn.idleTimeout = 0
  2343  			done := make(chan struct{})
  2344  			go func() {
  2345  				defer GinkgoRecover()
  2346  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2347  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventHandshakeComplete})
  2348  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2349  				cryptoSetup.EXPECT().GetSessionTicket().MaxTimes(1)
  2350  				cryptoSetup.EXPECT().SetHandshakeConfirmed().MaxTimes(1)
  2351  				cryptoSetup.EXPECT().ConnectionState()
  2352  				Expect(conn.handleHandshakeComplete()).To(Succeed())
  2353  				err := conn.run()
  2354  				nerr, ok := err.(net.Error)
  2355  				Expect(ok).To(BeTrue())
  2356  				Expect(nerr.Timeout()).To(BeTrue())
  2357  				Expect(err).To(MatchError(qerr.ErrIdleTimeout))
  2358  				close(done)
  2359  			}()
  2360  			Eventually(done).Should(BeClosed())
  2361  		})
  2362  
  2363  		It("doesn't time out when it just sent a packet", func() {
  2364  			conn.lastPacketReceivedTime = time.Now().Add(-time.Hour)
  2365  			conn.firstAckElicitingPacketAfterIdleSentTime = time.Now().Add(-time.Second)
  2366  			conn.idleTimeout = 30 * time.Second
  2367  			go func() {
  2368  				defer GinkgoRecover()
  2369  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2370  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2371  				conn.run()
  2372  			}()
  2373  			Consistently(conn.Context().Done()).ShouldNot(BeClosed())
  2374  			// make the go routine return
  2375  			packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
  2376  			expectReplaceWithClosed()
  2377  			cryptoSetup.EXPECT().Close()
  2378  			mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  2379  			tracer.EXPECT().ClosedConnection(gomock.Any())
  2380  			tracer.EXPECT().Close()
  2381  			conn.CloseWithError(0, "")
  2382  			Eventually(conn.Context().Done()).Should(BeClosed())
  2383  		})
  2384  
  2385  		It("times out earliest after 3 times the PTO", func() {
  2386  			packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).AnyTimes()
  2387  			connRunner.EXPECT().Retire(gomock.Any()).AnyTimes()
  2388  			connRunner.EXPECT().Remove(gomock.Any()).Times(2)
  2389  			cryptoSetup.EXPECT().Close()
  2390  			closeTimeChan := make(chan time.Time)
  2391  			tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) {
  2392  				Expect(e).To(MatchError(&IdleTimeoutError{}))
  2393  				closeTimeChan <- time.Now()
  2394  			})
  2395  			tracer.EXPECT().Close()
  2396  			conn.idleTimeout = time.Millisecond
  2397  			done := make(chan struct{})
  2398  			pto := conn.rttStats.PTO(true)
  2399  			go func() {
  2400  				defer GinkgoRecover()
  2401  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2402  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2403  				cryptoSetup.EXPECT().GetSessionTicket().MaxTimes(1)
  2404  				cryptoSetup.EXPECT().SetHandshakeConfirmed().MaxTimes(1)
  2405  				conn.run()
  2406  				close(done)
  2407  			}()
  2408  			closeTime := <-closeTimeChan
  2409  			Expect(closeTime.Sub(conn.lastPacketReceivedTime)).To(BeNumerically(">", pto*3))
  2410  			Eventually(done).Should(BeClosed())
  2411  		})
  2412  	})
  2413  
  2414  	It("stores up to MaxConnUnprocessedPackets packets", func() {
  2415  		done := make(chan struct{})
  2416  		tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, logging.ByteCount(6), logging.PacketDropDOSPrevention).Do(func(logging.PacketType, logging.PacketNumber, logging.ByteCount, logging.PacketDropReason) {
  2417  			close(done)
  2418  		})
  2419  		// Nothing here should block
  2420  		for i := protocol.PacketNumber(0); i < protocol.MaxConnUnprocessedPackets+1; i++ {
  2421  			conn.handlePacket(receivedPacket{data: []byte("foobar")})
  2422  		}
  2423  		Eventually(done).Should(BeClosed())
  2424  	})
  2425  
  2426  	Context("getting streams", func() {
  2427  		It("opens streams", func() {
  2428  			mstr := NewMockStreamI(mockCtrl)
  2429  			streamManager.EXPECT().OpenStream().Return(mstr, nil)
  2430  			str, err := conn.OpenStream()
  2431  			Expect(err).ToNot(HaveOccurred())
  2432  			Expect(str).To(Equal(mstr))
  2433  		})
  2434  
  2435  		It("opens streams synchronously", func() {
  2436  			mstr := NewMockStreamI(mockCtrl)
  2437  			streamManager.EXPECT().OpenStreamSync(context.Background()).Return(mstr, nil)
  2438  			str, err := conn.OpenStreamSync(context.Background())
  2439  			Expect(err).ToNot(HaveOccurred())
  2440  			Expect(str).To(Equal(mstr))
  2441  		})
  2442  
  2443  		It("opens unidirectional streams", func() {
  2444  			mstr := NewMockSendStreamI(mockCtrl)
  2445  			streamManager.EXPECT().OpenUniStream().Return(mstr, nil)
  2446  			str, err := conn.OpenUniStream()
  2447  			Expect(err).ToNot(HaveOccurred())
  2448  			Expect(str).To(Equal(mstr))
  2449  		})
  2450  
  2451  		It("opens unidirectional streams synchronously", func() {
  2452  			mstr := NewMockSendStreamI(mockCtrl)
  2453  			streamManager.EXPECT().OpenUniStreamSync(context.Background()).Return(mstr, nil)
  2454  			str, err := conn.OpenUniStreamSync(context.Background())
  2455  			Expect(err).ToNot(HaveOccurred())
  2456  			Expect(str).To(Equal(mstr))
  2457  		})
  2458  
  2459  		It("accepts streams", func() {
  2460  			ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
  2461  			defer cancel()
  2462  			mstr := NewMockStreamI(mockCtrl)
  2463  			streamManager.EXPECT().AcceptStream(ctx).Return(mstr, nil)
  2464  			str, err := conn.AcceptStream(ctx)
  2465  			Expect(err).ToNot(HaveOccurred())
  2466  			Expect(str).To(Equal(mstr))
  2467  		})
  2468  
  2469  		It("accepts unidirectional streams", func() {
  2470  			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  2471  			defer cancel()
  2472  			mstr := NewMockReceiveStreamI(mockCtrl)
  2473  			streamManager.EXPECT().AcceptUniStream(ctx).Return(mstr, nil)
  2474  			str, err := conn.AcceptUniStream(ctx)
  2475  			Expect(err).ToNot(HaveOccurred())
  2476  			Expect(str).To(Equal(mstr))
  2477  		})
  2478  	})
  2479  
  2480  	It("returns the local address", func() {
  2481  		Expect(conn.LocalAddr()).To(Equal(localAddr))
  2482  	})
  2483  
  2484  	It("returns the remote address", func() {
  2485  		Expect(conn.RemoteAddr()).To(Equal(remoteAddr))
  2486  	})
  2487  })
  2488  
  2489  var _ = Describe("Client Connection", func() {
  2490  	var (
  2491  		conn        *connection
  2492  		connRunner  *MockConnRunner
  2493  		packer      *MockPacker
  2494  		mconn       *MockSendConn
  2495  		cryptoSetup *mocks.MockCryptoSetup
  2496  		tracer      *mocklogging.MockConnectionTracer
  2497  		tlsConf     *tls.Config
  2498  		quicConf    *Config
  2499  	)
  2500  	srcConnID := protocol.ParseConnectionID([]byte{1, 2, 3, 4, 5, 6, 7, 8})
  2501  	destConnID := protocol.ParseConnectionID([]byte{8, 7, 6, 5, 4, 3, 2, 1})
  2502  
  2503  	getPacket := func(hdr *wire.ExtendedHeader, data []byte) receivedPacket {
  2504  		b, err := hdr.Append(nil, conn.version)
  2505  		Expect(err).ToNot(HaveOccurred())
  2506  		return receivedPacket{
  2507  			rcvTime: time.Now(),
  2508  			data:    append(b, data...),
  2509  			buffer:  getPacketBuffer(),
  2510  		}
  2511  	}
  2512  
  2513  	BeforeEach(func() {
  2514  		quicConf = populateConfig(&Config{})
  2515  		tlsConf = nil
  2516  	})
  2517  
  2518  	JustBeforeEach(func() {
  2519  		Eventually(areConnsRunning).Should(BeFalse())
  2520  
  2521  		mconn = NewMockSendConn(mockCtrl)
  2522  		mconn.EXPECT().capabilities().AnyTimes()
  2523  		mconn.EXPECT().RemoteAddr().Return(&net.UDPAddr{}).AnyTimes()
  2524  		mconn.EXPECT().LocalAddr().Return(&net.UDPAddr{}).AnyTimes()
  2525  		mconn.EXPECT().capabilities().AnyTimes()
  2526  		if tlsConf == nil {
  2527  			tlsConf = &tls.Config{}
  2528  		}
  2529  		connRunner = NewMockConnRunner(mockCtrl)
  2530  		var tr *logging.ConnectionTracer
  2531  		tr, tracer = mocklogging.NewMockConnectionTracer(mockCtrl)
  2532  		tracer.EXPECT().NegotiatedVersion(gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1)
  2533  		tracer.EXPECT().SentTransportParameters(gomock.Any())
  2534  		tracer.EXPECT().UpdatedKeyFromTLS(gomock.Any(), gomock.Any()).AnyTimes()
  2535  		tracer.EXPECT().UpdatedCongestionState(gomock.Any())
  2536  		conn = newClientConnection(
  2537  			mconn,
  2538  			connRunner,
  2539  			destConnID,
  2540  			protocol.ParseConnectionID([]byte{1, 2, 3, 4, 5, 6, 7, 8}),
  2541  			&protocol.DefaultConnectionIDGenerator{},
  2542  			quicConf,
  2543  			tlsConf,
  2544  			42, // initial packet number
  2545  			false,
  2546  			false,
  2547  			tr,
  2548  			1234,
  2549  			utils.DefaultLogger,
  2550  			protocol.Version1,
  2551  		).(*connection)
  2552  		packer = NewMockPacker(mockCtrl)
  2553  		conn.packer = packer
  2554  		cryptoSetup = mocks.NewMockCryptoSetup(mockCtrl)
  2555  		conn.cryptoStreamHandler = cryptoSetup
  2556  		conn.sentFirstPacket = true
  2557  	})
  2558  
  2559  	It("changes the connection ID when receiving the first packet from the server", func() {
  2560  		unpacker := NewMockUnpacker(mockCtrl)
  2561  		unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).DoAndReturn(func(hdr *wire.Header, _ time.Time, data []byte, _ protocol.Version) (*unpackedPacket, error) {
  2562  			return &unpackedPacket{
  2563  				encryptionLevel: protocol.Encryption1RTT,
  2564  				hdr:             &wire.ExtendedHeader{Header: *hdr},
  2565  				data:            []byte{0}, // one PADDING frame
  2566  			}, nil
  2567  		})
  2568  		conn.unpacker = unpacker
  2569  		done := make(chan struct{})
  2570  		packer.EXPECT().PackCoalescedPacket(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(onlyAck bool, maxPacketSize protocol.ByteCount, v protocol.Version) (*coalescedPacket, error) {
  2571  			close(done)
  2572  			return nil, nil
  2573  		})
  2574  		newConnID := protocol.ParseConnectionID([]byte{1, 3, 3, 7, 1, 3, 3, 7})
  2575  		p := getPacket(&wire.ExtendedHeader{
  2576  			Header: wire.Header{
  2577  				Type:             protocol.PacketTypeHandshake,
  2578  				SrcConnectionID:  newConnID,
  2579  				DestConnectionID: srcConnID,
  2580  				Length:           2 + 6,
  2581  				Version:          conn.version,
  2582  			},
  2583  			PacketNumberLen: protocol.PacketNumberLen2,
  2584  		}, []byte("foobar"))
  2585  		tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), p.Size(), gomock.Any(), []logging.Frame{})
  2586  		Expect(conn.handlePacketImpl(p)).To(BeTrue())
  2587  		go func() {
  2588  			defer GinkgoRecover()
  2589  			cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2590  			cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2591  			conn.run()
  2592  		}()
  2593  		Eventually(done).Should(BeClosed())
  2594  		// make sure the go routine returns
  2595  		packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
  2596  		cryptoSetup.EXPECT().Close()
  2597  		connRunner.EXPECT().ReplaceWithClosed([]protocol.ConnectionID{srcConnID}, gomock.Any(), gomock.Any())
  2598  		mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1)
  2599  		tracer.EXPECT().ClosedConnection(gomock.Any())
  2600  		tracer.EXPECT().Close()
  2601  		conn.CloseWithError(0, "")
  2602  		Eventually(conn.Context().Done()).Should(BeClosed())
  2603  		time.Sleep(200 * time.Millisecond)
  2604  	})
  2605  
  2606  	It("continues accepting Long Header packets after using a new connection ID", func() {
  2607  		unpacker := NewMockUnpacker(mockCtrl)
  2608  		conn.unpacker = unpacker
  2609  		connRunner.EXPECT().AddResetToken(gomock.Any(), gomock.Any())
  2610  		conn.connIDManager.SetHandshakeComplete()
  2611  		conn.handleNewConnectionIDFrame(&wire.NewConnectionIDFrame{
  2612  			SequenceNumber: 1,
  2613  			ConnectionID:   protocol.ParseConnectionID([]byte{1, 2, 3, 4, 5}),
  2614  		})
  2615  		Expect(conn.connIDManager.Get()).To(Equal(protocol.ParseConnectionID([]byte{1, 2, 3, 4, 5})))
  2616  		// now receive a packet with the original source connection ID
  2617  		unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).DoAndReturn(func(hdr *wire.Header, _ time.Time, _ []byte, _ protocol.Version) (*unpackedPacket, error) {
  2618  			return &unpackedPacket{
  2619  				hdr:             &wire.ExtendedHeader{Header: *hdr},
  2620  				data:            []byte{0},
  2621  				encryptionLevel: protocol.EncryptionHandshake,
  2622  			}, nil
  2623  		})
  2624  		hdr := &wire.Header{
  2625  			Type:             protocol.PacketTypeHandshake,
  2626  			DestConnectionID: srcConnID,
  2627  			SrcConnectionID:  destConnID,
  2628  		}
  2629  		tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  2630  		Expect(conn.handleLongHeaderPacket(receivedPacket{buffer: getPacketBuffer()}, hdr)).To(BeTrue())
  2631  	})
  2632  
  2633  	It("handles HANDSHAKE_DONE frames", func() {
  2634  		conn.peerParams = &wire.TransportParameters{}
  2635  		sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  2636  		conn.sentPacketHandler = sph
  2637  		tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionHandshake)
  2638  		sph.EXPECT().DropPackets(protocol.EncryptionHandshake)
  2639  		sph.EXPECT().SetHandshakeConfirmed()
  2640  		cryptoSetup.EXPECT().SetHandshakeConfirmed()
  2641  		Expect(conn.handleHandshakeDoneFrame()).To(Succeed())
  2642  	})
  2643  
  2644  	It("interprets an ACK for 1-RTT packets as confirmation of the handshake", func() {
  2645  		conn.peerParams = &wire.TransportParameters{}
  2646  		sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  2647  		conn.sentPacketHandler = sph
  2648  		ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 3}}}
  2649  		tracer.EXPECT().DroppedEncryptionLevel(protocol.EncryptionHandshake)
  2650  		sph.EXPECT().ReceivedAck(ack, protocol.Encryption1RTT, gomock.Any()).Return(true, nil)
  2651  		sph.EXPECT().DropPackets(protocol.EncryptionHandshake)
  2652  		sph.EXPECT().SetHandshakeConfirmed()
  2653  		cryptoSetup.EXPECT().SetLargest1RTTAcked(protocol.PacketNumber(3))
  2654  		cryptoSetup.EXPECT().SetHandshakeConfirmed()
  2655  		Expect(conn.handleAckFrame(ack, protocol.Encryption1RTT)).To(Succeed())
  2656  	})
  2657  
  2658  	It("doesn't send a CONNECTION_CLOSE when no packet was sent", func() {
  2659  		conn.sentFirstPacket = false
  2660  		tracer.EXPECT().ClosedConnection(gomock.Any())
  2661  		tracer.EXPECT().Close()
  2662  		running := make(chan struct{})
  2663  		cryptoSetup.EXPECT().StartHandshake().Do(func() error {
  2664  			close(running)
  2665  			conn.closeLocal(errors.New("early error"))
  2666  			return nil
  2667  		})
  2668  		cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2669  		cryptoSetup.EXPECT().Close()
  2670  		connRunner.EXPECT().Remove(gomock.Any())
  2671  		go func() {
  2672  			defer GinkgoRecover()
  2673  			conn.run()
  2674  		}()
  2675  		Eventually(running).Should(BeClosed())
  2676  		Eventually(areConnsRunning).Should(BeFalse())
  2677  	})
  2678  
  2679  	Context("handling tokens", func() {
  2680  		var mockTokenStore *MockTokenStore
  2681  
  2682  		BeforeEach(func() {
  2683  			mockTokenStore = NewMockTokenStore(mockCtrl)
  2684  			tlsConf = &tls.Config{ServerName: "server"}
  2685  			quicConf.TokenStore = mockTokenStore
  2686  			mockTokenStore.EXPECT().Pop(gomock.Any())
  2687  			quicConf.TokenStore = mockTokenStore
  2688  		})
  2689  
  2690  		It("handles NEW_TOKEN frames", func() {
  2691  			mockTokenStore.EXPECT().Put("server", &ClientToken{data: []byte("foobar")})
  2692  			Expect(conn.handleNewTokenFrame(&wire.NewTokenFrame{Token: []byte("foobar")})).To(Succeed())
  2693  		})
  2694  	})
  2695  
  2696  	Context("handling Version Negotiation", func() {
  2697  		getVNP := func(versions ...protocol.Version) receivedPacket {
  2698  			b := wire.ComposeVersionNegotiation(
  2699  				protocol.ArbitraryLenConnectionID(srcConnID.Bytes()),
  2700  				protocol.ArbitraryLenConnectionID(destConnID.Bytes()),
  2701  				versions,
  2702  			)
  2703  			return receivedPacket{
  2704  				rcvTime: time.Now(),
  2705  				data:    b,
  2706  				buffer:  getPacketBuffer(),
  2707  			}
  2708  		}
  2709  
  2710  		It("closes and returns the right error", func() {
  2711  			sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  2712  			conn.sentPacketHandler = sph
  2713  			sph.EXPECT().ReceivedBytes(gomock.Any())
  2714  			sph.EXPECT().PeekPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(128), protocol.PacketNumberLen4)
  2715  			conn.config.Versions = []protocol.Version{1234, 4321}
  2716  			errChan := make(chan error, 1)
  2717  			start := make(chan struct{})
  2718  			go func() {
  2719  				defer GinkgoRecover()
  2720  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2721  				cryptoSetup.EXPECT().NextEvent().DoAndReturn(func() handshake.Event {
  2722  					<-start
  2723  					return handshake.Event{Kind: handshake.EventNoEvent}
  2724  				})
  2725  				errChan <- conn.run()
  2726  			}()
  2727  			connRunner.EXPECT().Remove(srcConnID)
  2728  			tracer.EXPECT().ReceivedVersionNegotiationPacket(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_, _ protocol.ArbitraryLenConnectionID, versions []logging.VersionNumber) {
  2729  				Expect(versions).To(And(
  2730  					ContainElement(protocol.Version(4321)),
  2731  					ContainElement(protocol.Version(1337)),
  2732  				))
  2733  			})
  2734  			cryptoSetup.EXPECT().Close()
  2735  			Expect(conn.handlePacketImpl(getVNP(4321, 1337))).To(BeFalse())
  2736  			close(start)
  2737  			var err error
  2738  			Eventually(errChan).Should(Receive(&err))
  2739  			Expect(err).To(HaveOccurred())
  2740  			Expect(err).To(BeAssignableToTypeOf(&errCloseForRecreating{}))
  2741  			recreateErr := err.(*errCloseForRecreating)
  2742  			Expect(recreateErr.nextVersion).To(Equal(protocol.Version(4321)))
  2743  			Expect(recreateErr.nextPacketNumber).To(Equal(protocol.PacketNumber(128)))
  2744  		})
  2745  
  2746  		It("closes when no matching version is found", func() {
  2747  			errChan := make(chan error, 1)
  2748  			packer.EXPECT().PackCoalescedPacket(gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1)
  2749  			go func() {
  2750  				defer GinkgoRecover()
  2751  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2752  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
  2753  				errChan <- conn.run()
  2754  			}()
  2755  			connRunner.EXPECT().Remove(srcConnID).MaxTimes(1)
  2756  			gomock.InOrder(
  2757  				tracer.EXPECT().ReceivedVersionNegotiationPacket(gomock.Any(), gomock.Any(), gomock.Any()),
  2758  				tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(e error) {
  2759  					var vnErr *VersionNegotiationError
  2760  					Expect(errors.As(e, &vnErr)).To(BeTrue())
  2761  					Expect(vnErr.Theirs).To(ContainElement(logging.VersionNumber(12345678)))
  2762  				}),
  2763  				tracer.EXPECT().Close(),
  2764  			)
  2765  			cryptoSetup.EXPECT().Close()
  2766  			Expect(conn.handlePacketImpl(getVNP(12345678))).To(BeFalse())
  2767  			var err error
  2768  			Eventually(errChan).Should(Receive(&err))
  2769  			Expect(err).To(HaveOccurred())
  2770  			Expect(err).ToNot(BeAssignableToTypeOf(errCloseForRecreating{}))
  2771  			Expect(err.Error()).To(ContainSubstring("no compatible QUIC version found"))
  2772  		})
  2773  
  2774  		It("ignores Version Negotiation packets that offer the current version", func() {
  2775  			p := getVNP(conn.version)
  2776  			tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedVersion)
  2777  			Expect(conn.handlePacketImpl(p)).To(BeFalse())
  2778  		})
  2779  
  2780  		It("ignores unparseable Version Negotiation packets", func() {
  2781  			p := getVNP(conn.version)
  2782  			p.data = p.data[:len(p.data)-2]
  2783  			tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError)
  2784  			Expect(conn.handlePacketImpl(p)).To(BeFalse())
  2785  		})
  2786  	})
  2787  
  2788  	Context("handling Retry", func() {
  2789  		origDestConnID := protocol.ParseConnectionID([]byte{8, 7, 6, 5, 4, 3, 2, 1})
  2790  
  2791  		var retryHdr *wire.ExtendedHeader
  2792  
  2793  		JustBeforeEach(func() {
  2794  			retryHdr = &wire.ExtendedHeader{
  2795  				Header: wire.Header{
  2796  					Type:             protocol.PacketTypeRetry,
  2797  					SrcConnectionID:  protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}),
  2798  					DestConnectionID: protocol.ParseConnectionID([]byte{1, 2, 3, 4, 5, 6, 7, 8}),
  2799  					Token:            []byte("foobar"),
  2800  					Version:          conn.version,
  2801  				},
  2802  			}
  2803  		})
  2804  
  2805  		getRetryTag := func(hdr *wire.ExtendedHeader) []byte {
  2806  			b, err := hdr.Append(nil, conn.version)
  2807  			Expect(err).ToNot(HaveOccurred())
  2808  			return handshake.GetRetryIntegrityTag(b, origDestConnID, hdr.Version)[:]
  2809  		}
  2810  
  2811  		It("handles Retry packets", func() {
  2812  			now := time.Now()
  2813  			sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  2814  			conn.sentPacketHandler = sph
  2815  			sph.EXPECT().ResetForRetry(now)
  2816  			sph.EXPECT().ReceivedBytes(gomock.Any())
  2817  			cryptoSetup.EXPECT().ChangeConnectionID(protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}))
  2818  			packer.EXPECT().SetToken([]byte("foobar"))
  2819  			tracer.EXPECT().ReceivedRetry(gomock.Any()).Do(func(hdr *wire.Header) {
  2820  				Expect(hdr.DestConnectionID).To(Equal(retryHdr.DestConnectionID))
  2821  				Expect(hdr.SrcConnectionID).To(Equal(retryHdr.SrcConnectionID))
  2822  				Expect(hdr.Token).To(Equal(retryHdr.Token))
  2823  			})
  2824  			p := getPacket(retryHdr, getRetryTag(retryHdr))
  2825  			p.rcvTime = now
  2826  			Expect(conn.handlePacketImpl(p)).To(BeTrue())
  2827  		})
  2828  
  2829  		It("ignores Retry packets after receiving a regular packet", func() {
  2830  			conn.receivedFirstPacket = true
  2831  			p := getPacket(retryHdr, getRetryTag(retryHdr))
  2832  			tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket)
  2833  			Expect(conn.handlePacketImpl(p)).To(BeFalse())
  2834  		})
  2835  
  2836  		It("ignores Retry packets if the server didn't change the connection ID", func() {
  2837  			retryHdr.SrcConnectionID = destConnID
  2838  			p := getPacket(retryHdr, getRetryTag(retryHdr))
  2839  			tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket)
  2840  			Expect(conn.handlePacketImpl(p)).To(BeFalse())
  2841  		})
  2842  
  2843  		It("ignores Retry packets with the a wrong Integrity tag", func() {
  2844  			tag := getRetryTag(retryHdr)
  2845  			tag[0]++
  2846  			p := getPacket(retryHdr, tag)
  2847  			tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropPayloadDecryptError)
  2848  			Expect(conn.handlePacketImpl(p)).To(BeFalse())
  2849  		})
  2850  	})
  2851  
  2852  	Context("transport parameters", func() {
  2853  		var (
  2854  			closed     bool
  2855  			errChan    chan error
  2856  			paramsChan chan *wire.TransportParameters
  2857  		)
  2858  
  2859  		JustBeforeEach(func() {
  2860  			errChan = make(chan error, 1)
  2861  			paramsChan = make(chan *wire.TransportParameters, 1)
  2862  			closed = false
  2863  			packer.EXPECT().PackCoalescedPacket(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
  2864  			go func() {
  2865  				defer GinkgoRecover()
  2866  				cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
  2867  				// This is not 100% what would happen in reality.
  2868  				// The run loop calls NextEvent once when it starts up (to send out the ClientHello),
  2869  				// and then again every time a CRYPTO frame is handled.
  2870  				// Injecting a CRYPTO frame is not straightforward though,
  2871  				// so we inject the transport parameters on the first call to NextEvent.
  2872  				params := <-paramsChan
  2873  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{
  2874  					Kind:                handshake.EventReceivedTransportParameters,
  2875  					TransportParameters: params,
  2876  				})
  2877  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventHandshakeComplete}).MaxTimes(1)
  2878  				cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}).MaxTimes(1).Do(func() {
  2879  					defer GinkgoRecover()
  2880  					Expect(conn.handleHandshakeComplete()).To(Succeed())
  2881  				})
  2882  				tracer.EXPECT().ChoseALPN(gomock.Any()).MaxTimes(1)
  2883  				cryptoSetup.EXPECT().ConnectionState().MaxTimes(1)
  2884  				errChan <- conn.run()
  2885  				close(errChan)
  2886  			}()
  2887  		})
  2888  
  2889  		expectClose := func(applicationClose, errored bool) {
  2890  			if !closed && !errored {
  2891  				connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any(), gomock.Any())
  2892  				if applicationClose {
  2893  					packer.EXPECT().PackApplicationClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil).MaxTimes(1)
  2894  				} else {
  2895  					packer.EXPECT().PackConnectionClose(gomock.Any(), gomock.Any(), conn.version).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil).MaxTimes(1)
  2896  				}
  2897  				cryptoSetup.EXPECT().Close()
  2898  				mconn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any())
  2899  				gomock.InOrder(
  2900  					tracer.EXPECT().ClosedConnection(gomock.Any()),
  2901  					tracer.EXPECT().Close(),
  2902  				)
  2903  			}
  2904  			closed = true
  2905  		}
  2906  
  2907  		AfterEach(func() {
  2908  			conn.CloseWithError(0, "")
  2909  			Eventually(conn.Context().Done()).Should(BeClosed())
  2910  			Eventually(errChan).Should(BeClosed())
  2911  		})
  2912  
  2913  		It("uses the preferred_address connection ID", func() {
  2914  			params := &wire.TransportParameters{
  2915  				OriginalDestinationConnectionID: destConnID,
  2916  				InitialSourceConnectionID:       destConnID,
  2917  				PreferredAddress: &wire.PreferredAddress{
  2918  					IPv4:                netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), 42),
  2919  					IPv6:                netip.AddrPortFrom(netip.AddrFrom16([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), 13),
  2920  					ConnectionID:        protocol.ParseConnectionID([]byte{1, 2, 3, 4}),
  2921  					StatelessResetToken: protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
  2922  				},
  2923  			}
  2924  			packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), conn.version).MaxTimes(1)
  2925  			processed := make(chan struct{})
  2926  			tracer.EXPECT().ReceivedTransportParameters(params).Do(func(*wire.TransportParameters) { close(processed) })
  2927  			paramsChan <- params
  2928  			Eventually(processed).Should(BeClosed())
  2929  			// make sure the connection ID is not retired
  2930  			cf, _ := conn.framer.AppendControlFrames(nil, protocol.MaxByteCount, protocol.Version1)
  2931  			Expect(cf).To(BeEmpty())
  2932  			connRunner.EXPECT().AddResetToken(protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, conn)
  2933  			Expect(conn.connIDManager.Get()).To(Equal(protocol.ParseConnectionID([]byte{1, 2, 3, 4})))
  2934  			// shut down
  2935  			connRunner.EXPECT().RemoveResetToken(protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1})
  2936  			expectClose(true, false)
  2937  		})
  2938  
  2939  		It("uses the minimum of the peers' idle timeouts", func() {
  2940  			conn.config.MaxIdleTimeout = 19 * time.Second
  2941  			params := &wire.TransportParameters{
  2942  				OriginalDestinationConnectionID: destConnID,
  2943  				InitialSourceConnectionID:       destConnID,
  2944  				MaxIdleTimeout:                  18 * time.Second,
  2945  			}
  2946  			processed := make(chan struct{})
  2947  			tracer.EXPECT().ReceivedTransportParameters(params).Do(func(*wire.TransportParameters) { close(processed) })
  2948  			paramsChan <- params
  2949  			Eventually(processed).Should(BeClosed())
  2950  			// close first
  2951  			expectClose(true, false)
  2952  			conn.CloseWithError(0, "")
  2953  			// then check. Avoids race condition when accessing idleTimeout
  2954  			Expect(conn.idleTimeout).To(Equal(18 * time.Second))
  2955  		})
  2956  
  2957  		It("errors if the transport parameters contain a wrong initial_source_connection_id", func() {
  2958  			conn.handshakeDestConnID = protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef})
  2959  			params := &wire.TransportParameters{
  2960  				OriginalDestinationConnectionID: destConnID,
  2961  				InitialSourceConnectionID:       protocol.ParseConnectionID([]byte{0xde, 0xca, 0xfb, 0xad}),
  2962  				StatelessResetToken:             &protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
  2963  			}
  2964  			expectClose(false, true)
  2965  			processed := make(chan struct{})
  2966  			tracer.EXPECT().ReceivedTransportParameters(params).Do(func(*wire.TransportParameters) { close(processed) })
  2967  			paramsChan <- params
  2968  			Eventually(processed).Should(BeClosed())
  2969  			Eventually(errChan).Should(Receive(MatchError(&qerr.TransportError{
  2970  				ErrorCode:    qerr.TransportParameterError,
  2971  				ErrorMessage: "expected initial_source_connection_id to equal deadbeef, is decafbad",
  2972  			})))
  2973  		})
  2974  
  2975  		It("errors if the transport parameters don't contain the retry_source_connection_id, if a Retry was performed", func() {
  2976  			rcid := protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef})
  2977  			conn.retrySrcConnID = &rcid
  2978  			params := &wire.TransportParameters{
  2979  				OriginalDestinationConnectionID: destConnID,
  2980  				InitialSourceConnectionID:       destConnID,
  2981  				StatelessResetToken:             &protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
  2982  			}
  2983  			expectClose(false, true)
  2984  			processed := make(chan struct{})
  2985  			tracer.EXPECT().ReceivedTransportParameters(params).Do(func(*wire.TransportParameters) { close(processed) })
  2986  			paramsChan <- params
  2987  			Eventually(processed).Should(BeClosed())
  2988  			Eventually(errChan).Should(Receive(MatchError(&qerr.TransportError{
  2989  				ErrorCode:    qerr.TransportParameterError,
  2990  				ErrorMessage: "missing retry_source_connection_id",
  2991  			})))
  2992  		})
  2993  
  2994  		It("errors if the transport parameters contain the wrong retry_source_connection_id, if a Retry was performed", func() {
  2995  			rcid := protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef})
  2996  			rcid2 := protocol.ParseConnectionID([]byte{0xde, 0xad, 0xc0, 0xde})
  2997  			conn.retrySrcConnID = &rcid
  2998  			params := &wire.TransportParameters{
  2999  				OriginalDestinationConnectionID: destConnID,
  3000  				InitialSourceConnectionID:       destConnID,
  3001  				RetrySourceConnectionID:         &rcid2,
  3002  				StatelessResetToken:             &protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
  3003  			}
  3004  			expectClose(false, true)
  3005  			processed := make(chan struct{})
  3006  			tracer.EXPECT().ReceivedTransportParameters(params).Do(func(*wire.TransportParameters) { close(processed) })
  3007  			paramsChan <- params
  3008  			Eventually(processed).Should(BeClosed())
  3009  			Eventually(errChan).Should(Receive(MatchError(&qerr.TransportError{
  3010  				ErrorCode:    qerr.TransportParameterError,
  3011  				ErrorMessage: "expected retry_source_connection_id to equal deadbeef, is deadc0de",
  3012  			})))
  3013  		})
  3014  
  3015  		It("errors if the transport parameters contain the retry_source_connection_id, if no Retry was performed", func() {
  3016  			rcid := protocol.ParseConnectionID([]byte{0xde, 0xad, 0xc0, 0xde})
  3017  			params := &wire.TransportParameters{
  3018  				OriginalDestinationConnectionID: destConnID,
  3019  				InitialSourceConnectionID:       destConnID,
  3020  				RetrySourceConnectionID:         &rcid,
  3021  				StatelessResetToken:             &protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
  3022  			}
  3023  			expectClose(false, true)
  3024  			processed := make(chan struct{})
  3025  			tracer.EXPECT().ReceivedTransportParameters(params).Do(func(*wire.TransportParameters) { close(processed) })
  3026  			paramsChan <- params
  3027  			Eventually(processed).Should(BeClosed())
  3028  			Eventually(errChan).Should(Receive(MatchError(&qerr.TransportError{
  3029  				ErrorCode:    qerr.TransportParameterError,
  3030  				ErrorMessage: "received retry_source_connection_id, although no Retry was performed",
  3031  			})))
  3032  		})
  3033  
  3034  		It("errors if the transport parameters contain a wrong original_destination_connection_id", func() {
  3035  			conn.origDestConnID = protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef})
  3036  			params := &wire.TransportParameters{
  3037  				OriginalDestinationConnectionID: protocol.ParseConnectionID([]byte{0xde, 0xca, 0xfb, 0xad}),
  3038  				InitialSourceConnectionID:       conn.handshakeDestConnID,
  3039  				StatelessResetToken:             &protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
  3040  			}
  3041  			expectClose(false, true)
  3042  			processed := make(chan struct{})
  3043  			tracer.EXPECT().ReceivedTransportParameters(params).Do(func(*wire.TransportParameters) { close(processed) })
  3044  			paramsChan <- params
  3045  			Eventually(processed).Should(BeClosed())
  3046  			Eventually(errChan).Should(Receive(MatchError(&qerr.TransportError{
  3047  				ErrorCode:    qerr.TransportParameterError,
  3048  				ErrorMessage: "expected original_destination_connection_id to equal deadbeef, is decafbad",
  3049  			})))
  3050  		})
  3051  
  3052  		It("errors if the transport parameters contain reduced limits after knowing 0-RTT data is accepted by the server", func() {
  3053  			conn.perspective = protocol.PerspectiveClient
  3054  			conn.peerParams = &wire.TransportParameters{
  3055  				ActiveConnectionIDLimit:        3,
  3056  				InitialMaxData:                 0x5000,
  3057  				InitialMaxStreamDataBidiLocal:  0x5000,
  3058  				InitialMaxStreamDataBidiRemote: 1000,
  3059  				InitialMaxStreamDataUni:        1000,
  3060  				MaxBidiStreamNum:               500,
  3061  				MaxUniStreamNum:                500,
  3062  			}
  3063  			params := &wire.TransportParameters{
  3064  				OriginalDestinationConnectionID: destConnID,
  3065  				InitialSourceConnectionID:       destConnID,
  3066  				ActiveConnectionIDLimit:         3,
  3067  				InitialMaxData:                  0x5000,
  3068  				InitialMaxStreamDataBidiLocal:   0x5000,
  3069  				InitialMaxStreamDataBidiRemote:  1000,
  3070  				InitialMaxStreamDataUni:         1000,
  3071  				MaxBidiStreamNum:                300,
  3072  				MaxUniStreamNum:                 300,
  3073  			}
  3074  			expectClose(false, true)
  3075  			processed := make(chan struct{})
  3076  			tracer.EXPECT().ReceivedTransportParameters(params).Do(func(*wire.TransportParameters) { close(processed) })
  3077  			cryptoSetup.EXPECT().ConnectionState().Return(handshake.ConnectionState{Used0RTT: true})
  3078  			paramsChan <- params
  3079  			Eventually(processed).Should(BeClosed())
  3080  			Eventually(errChan).Should(Receive(MatchError(&qerr.TransportError{
  3081  				ErrorCode:    qerr.ProtocolViolation,
  3082  				ErrorMessage: "server sent reduced limits after accepting 0-RTT data",
  3083  			})))
  3084  		})
  3085  	})
  3086  
  3087  	Context("handling potentially injected packets", func() {
  3088  		var unpacker *MockUnpacker
  3089  
  3090  		getPacket := func(extHdr *wire.ExtendedHeader, data []byte) receivedPacket {
  3091  			b, err := extHdr.Append(nil, conn.version)
  3092  			Expect(err).ToNot(HaveOccurred())
  3093  			return receivedPacket{
  3094  				data:   append(b, data...),
  3095  				buffer: getPacketBuffer(),
  3096  			}
  3097  		}
  3098  
  3099  		// Convert an already packed raw packet into a receivedPacket
  3100  		wrapPacket := func(packet []byte) receivedPacket {
  3101  			return receivedPacket{
  3102  				data:   packet,
  3103  				buffer: getPacketBuffer(),
  3104  			}
  3105  		}
  3106  
  3107  		// Illustrates that attacker may inject an Initial packet with a different
  3108  		// source connection ID, causing endpoint to ignore a subsequent real Initial packets.
  3109  		It("ignores Initial packets with a different source connection ID", func() {
  3110  			// Modified from test "ignores packets with a different source connection ID"
  3111  			unpacker = NewMockUnpacker(mockCtrl)
  3112  			conn.unpacker = unpacker
  3113  
  3114  			hdr1 := &wire.ExtendedHeader{
  3115  				Header: wire.Header{
  3116  					Type:             protocol.PacketTypeInitial,
  3117  					DestConnectionID: destConnID,
  3118  					SrcConnectionID:  srcConnID,
  3119  					Length:           1,
  3120  					Version:          conn.version,
  3121  				},
  3122  				PacketNumberLen: protocol.PacketNumberLen1,
  3123  				PacketNumber:    1,
  3124  			}
  3125  			hdr2 := &wire.ExtendedHeader{
  3126  				Header: wire.Header{
  3127  					Type:             protocol.PacketTypeInitial,
  3128  					DestConnectionID: destConnID,
  3129  					SrcConnectionID:  protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}),
  3130  					Length:           1,
  3131  					Version:          conn.version,
  3132  				},
  3133  				PacketNumberLen: protocol.PacketNumberLen1,
  3134  				PacketNumber:    2,
  3135  			}
  3136  			Expect(hdr2.SrcConnectionID).ToNot(Equal(srcConnID))
  3137  			// Send one packet, which might change the connection ID.
  3138  			// only EXPECT one call to the unpacker
  3139  			unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any(), gomock.Any(), conn.version).Return(&unpackedPacket{
  3140  				encryptionLevel: protocol.EncryptionInitial,
  3141  				hdr:             hdr1,
  3142  				data:            []byte{0}, // one PADDING frame
  3143  			}, nil)
  3144  			tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  3145  			Expect(conn.handlePacketImpl(getPacket(hdr1, nil))).To(BeTrue())
  3146  			// The next packet has to be ignored, since the source connection ID doesn't match.
  3147  			tracer.EXPECT().DroppedPacket(gomock.Any(), protocol.InvalidPacketNumber, gomock.Any(), gomock.Any())
  3148  			Expect(conn.handlePacketImpl(getPacket(hdr2, nil))).To(BeFalse())
  3149  		})
  3150  
  3151  		It("ignores 0-RTT packets", func() {
  3152  			p := getPacket(&wire.ExtendedHeader{
  3153  				Header: wire.Header{
  3154  					Type:             protocol.PacketType0RTT,
  3155  					DestConnectionID: srcConnID,
  3156  					Length:           2 + 6,
  3157  					Version:          conn.version,
  3158  				},
  3159  				PacketNumber:    0x42,
  3160  				PacketNumberLen: protocol.PacketNumberLen2,
  3161  			}, []byte("foobar"))
  3162  			tracer.EXPECT().DroppedPacket(logging.PacketType0RTT, protocol.InvalidPacketNumber, p.Size(), gomock.Any())
  3163  			Expect(conn.handlePacketImpl(p)).To(BeFalse())
  3164  		})
  3165  
  3166  		// Illustrates that an injected Initial with an ACK frame for an unsent packet causes
  3167  		// the connection to immediately break down
  3168  		It("fails on Initial-level ACK for unsent packet", func() {
  3169  			ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 2}}}
  3170  			initialPacket := testutils.ComposeInitialPacket(destConnID, srcConnID, destConnID, []wire.Frame{ack}, protocol.PerspectiveServer, conn.version)
  3171  			tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  3172  			Expect(conn.handlePacketImpl(wrapPacket(initialPacket))).To(BeFalse())
  3173  		})
  3174  
  3175  		// Illustrates that an injected Initial with a CONNECTION_CLOSE frame causes
  3176  		// the connection to immediately break down
  3177  		It("fails on Initial-level CONNECTION_CLOSE frame", func() {
  3178  			connCloseFrame := &wire.ConnectionCloseFrame{
  3179  				IsApplicationError: true,
  3180  				ReasonPhrase:       "mitm attacker",
  3181  			}
  3182  			initialPacket := testutils.ComposeInitialPacket(destConnID, srcConnID, destConnID, []wire.Frame{connCloseFrame}, protocol.PerspectiveServer, conn.version)
  3183  			tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  3184  			Expect(conn.handlePacketImpl(wrapPacket(initialPacket))).To(BeTrue())
  3185  		})
  3186  
  3187  		// Illustrates that attacker who injects a Retry packet and changes the connection ID
  3188  		// can cause subsequent real Initial packets to be ignored
  3189  		It("ignores Initial packets which use original source id, after accepting a Retry", func() {
  3190  			sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  3191  			conn.sentPacketHandler = sph
  3192  			sph.EXPECT().ReceivedBytes(gomock.Any()).Times(2)
  3193  			sph.EXPECT().ResetForRetry(gomock.Any())
  3194  			newSrcConnID := protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef})
  3195  			cryptoSetup.EXPECT().ChangeConnectionID(newSrcConnID)
  3196  			packer.EXPECT().SetToken([]byte("foobar"))
  3197  
  3198  			tracer.EXPECT().ReceivedRetry(gomock.Any())
  3199  			conn.handlePacketImpl(wrapPacket(testutils.ComposeRetryPacket(newSrcConnID, destConnID, destConnID, []byte("foobar"), conn.version)))
  3200  			initialPacket := testutils.ComposeInitialPacket(conn.connIDManager.Get(), srcConnID, conn.connIDManager.Get(), nil, protocol.PerspectiveServer, conn.version)
  3201  			tracer.EXPECT().DroppedPacket(gomock.Any(), protocol.InvalidPacketNumber, gomock.Any(), gomock.Any())
  3202  			Expect(conn.handlePacketImpl(wrapPacket(initialPacket))).To(BeFalse())
  3203  		})
  3204  	})
  3205  })