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