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