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