github.com/quic-go/quic-go@v0.44.0/connection_test.go (about)

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