session_test.go 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692
  1. package quic
  2. import (
  3. "bytes"
  4. "context"
  5. "errors"
  6. "net"
  7. "runtime/pprof"
  8. "strings"
  9. "time"
  10. . "github.com/onsi/ginkgo"
  11. . "github.com/onsi/gomega"
  12. "github.com/golang/mock/gomock"
  13. "github.com/lucas-clemente/quic-go/internal/ackhandler"
  14. "github.com/lucas-clemente/quic-go/internal/handshake"
  15. "github.com/lucas-clemente/quic-go/internal/mocks"
  16. mockackhandler "github.com/lucas-clemente/quic-go/internal/mocks/ackhandler"
  17. "github.com/lucas-clemente/quic-go/internal/protocol"
  18. "github.com/lucas-clemente/quic-go/internal/qerr"
  19. "github.com/lucas-clemente/quic-go/internal/utils"
  20. "github.com/lucas-clemente/quic-go/internal/wire"
  21. )
  22. type mockConnection struct {
  23. remoteAddr net.Addr
  24. localAddr net.Addr
  25. written chan []byte
  26. }
  27. func newMockConnection() *mockConnection {
  28. return &mockConnection{
  29. remoteAddr: &net.UDPAddr{},
  30. written: make(chan []byte, 100),
  31. }
  32. }
  33. func (m *mockConnection) Write(p []byte) error {
  34. b := make([]byte, len(p))
  35. copy(b, p)
  36. select {
  37. case m.written <- b:
  38. default:
  39. panic("mockConnection channel full")
  40. }
  41. return nil
  42. }
  43. func (m *mockConnection) Read([]byte) (int, net.Addr, error) { panic("not implemented") }
  44. func (m *mockConnection) SetCurrentRemoteAddr(addr net.Addr) {
  45. m.remoteAddr = addr
  46. }
  47. func (m *mockConnection) LocalAddr() net.Addr { return m.localAddr }
  48. func (m *mockConnection) RemoteAddr() net.Addr { return m.remoteAddr }
  49. func (*mockConnection) Close() error { panic("not implemented") }
  50. func areSessionsRunning() bool {
  51. var b bytes.Buffer
  52. pprof.Lookup("goroutine").WriteTo(&b, 1)
  53. return strings.Contains(b.String(), "quic-go.(*session).run")
  54. }
  55. func insertPacketBuffer(p *receivedPacket) *receivedPacket {
  56. p.buffer = getPacketBuffer()
  57. return p
  58. }
  59. var _ = Describe("Session", func() {
  60. var (
  61. sess *session
  62. sessionRunner *MockSessionRunner
  63. mconn *mockConnection
  64. streamManager *MockStreamManager
  65. packer *MockPacker
  66. cryptoSetup *mocks.MockCryptoSetup
  67. )
  68. BeforeEach(func() {
  69. Eventually(areSessionsRunning).Should(BeFalse())
  70. sessionRunner = NewMockSessionRunner(mockCtrl)
  71. mconn = newMockConnection()
  72. var pSess Session
  73. var err error
  74. pSess, err = newSession(
  75. mconn,
  76. sessionRunner,
  77. protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
  78. protocol.ConnectionID{8, 7, 6, 5, 4, 3, 2, 1},
  79. protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
  80. populateServerConfig(&Config{}),
  81. nil, // tls.Config
  82. &handshake.TransportParameters{},
  83. utils.DefaultLogger,
  84. protocol.VersionTLS,
  85. )
  86. Expect(err).NotTo(HaveOccurred())
  87. sess = pSess.(*session)
  88. streamManager = NewMockStreamManager(mockCtrl)
  89. sess.streamsMap = streamManager
  90. packer = NewMockPacker(mockCtrl)
  91. sess.packer = packer
  92. cryptoSetup = mocks.NewMockCryptoSetup(mockCtrl)
  93. sess.cryptoStreamHandler = cryptoSetup
  94. })
  95. AfterEach(func() {
  96. Eventually(areSessionsRunning).Should(BeFalse())
  97. })
  98. Context("frame handling", func() {
  99. Context("handling STREAM frames", func() {
  100. It("passes STREAM frames to the stream", func() {
  101. f := &wire.StreamFrame{
  102. StreamID: 5,
  103. Data: []byte{0xde, 0xca, 0xfb, 0xad},
  104. }
  105. str := NewMockReceiveStreamI(mockCtrl)
  106. str.EXPECT().handleStreamFrame(f)
  107. streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(5)).Return(str, nil)
  108. err := sess.handleStreamFrame(f, protocol.Encryption1RTT)
  109. Expect(err).ToNot(HaveOccurred())
  110. })
  111. It("returns errors", func() {
  112. testErr := errors.New("test err")
  113. f := &wire.StreamFrame{
  114. StreamID: 5,
  115. Data: []byte{0xde, 0xca, 0xfb, 0xad},
  116. }
  117. str := NewMockReceiveStreamI(mockCtrl)
  118. str.EXPECT().handleStreamFrame(f).Return(testErr)
  119. streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(5)).Return(str, nil)
  120. err := sess.handleStreamFrame(f, protocol.Encryption1RTT)
  121. Expect(err).To(MatchError(testErr))
  122. })
  123. It("ignores STREAM frames for closed streams", func() {
  124. streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(5)).Return(nil, nil) // for closed streams, the streamManager returns nil
  125. err := sess.handleStreamFrame(&wire.StreamFrame{
  126. StreamID: 5,
  127. Data: []byte("foobar"),
  128. }, protocol.Encryption1RTT)
  129. Expect(err).ToNot(HaveOccurred())
  130. })
  131. It("does not accept STREAM frames in non-1RTT packets", func() {
  132. err := sess.handleStreamFrame(&wire.StreamFrame{
  133. StreamID: 3,
  134. Data: []byte("foobar"),
  135. }, protocol.EncryptionHandshake)
  136. Expect(err).To(MatchError(qerr.Error(qerr.UnencryptedStreamData, "received unencrypted stream data on stream 3")))
  137. })
  138. })
  139. Context("handling ACK frames", func() {
  140. It("informs the SentPacketHandler about ACKs", func() {
  141. f := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 3}}}
  142. sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  143. sph.EXPECT().ReceivedAck(f, protocol.PacketNumber(42), protocol.EncryptionHandshake, gomock.Any())
  144. sess.sentPacketHandler = sph
  145. err := sess.handleAckFrame(f, 42, protocol.EncryptionHandshake)
  146. Expect(err).ToNot(HaveOccurred())
  147. })
  148. It("tells the ReceivedPacketHandler to ignore low ranges", func() {
  149. ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 3}}}
  150. sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  151. sph.EXPECT().ReceivedAck(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
  152. sph.EXPECT().GetLowestPacketNotConfirmedAcked().Return(protocol.PacketNumber(0x42))
  153. sess.sentPacketHandler = sph
  154. rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl)
  155. rph.EXPECT().IgnoreBelow(protocol.PacketNumber(0x42))
  156. sess.receivedPacketHandler = rph
  157. Expect(sess.handleAckFrame(ack, 0, protocol.Encryption1RTT)).To(Succeed())
  158. })
  159. })
  160. Context("handling RESET_STREAM frames", func() {
  161. It("closes the streams for writing", func() {
  162. f := &wire.ResetStreamFrame{
  163. StreamID: 555,
  164. ErrorCode: 42,
  165. ByteOffset: 0x1337,
  166. }
  167. str := NewMockReceiveStreamI(mockCtrl)
  168. streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(555)).Return(str, nil)
  169. str.EXPECT().handleResetStreamFrame(f)
  170. err := sess.handleResetStreamFrame(f)
  171. Expect(err).ToNot(HaveOccurred())
  172. })
  173. It("returns errors", func() {
  174. f := &wire.ResetStreamFrame{
  175. StreamID: 7,
  176. ByteOffset: 0x1337,
  177. }
  178. testErr := errors.New("flow control violation")
  179. str := NewMockReceiveStreamI(mockCtrl)
  180. streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(7)).Return(str, nil)
  181. str.EXPECT().handleResetStreamFrame(f).Return(testErr)
  182. err := sess.handleResetStreamFrame(f)
  183. Expect(err).To(MatchError(testErr))
  184. })
  185. It("ignores RESET_STREAM frames for closed streams", func() {
  186. streamManager.EXPECT().GetOrOpenReceiveStream(protocol.StreamID(3)).Return(nil, nil)
  187. Expect(sess.handleFrame(&wire.ResetStreamFrame{
  188. StreamID: 3,
  189. ErrorCode: 42,
  190. }, 0, protocol.EncryptionUnspecified)).To(Succeed())
  191. })
  192. })
  193. Context("handling MAX_DATA and MAX_STREAM_DATA frames", func() {
  194. var connFC *mocks.MockConnectionFlowController
  195. BeforeEach(func() {
  196. connFC = mocks.NewMockConnectionFlowController(mockCtrl)
  197. sess.connFlowController = connFC
  198. })
  199. It("updates the flow control window of a stream", func() {
  200. f := &wire.MaxStreamDataFrame{
  201. StreamID: 12345,
  202. ByteOffset: 0x1337,
  203. }
  204. str := NewMockSendStreamI(mockCtrl)
  205. streamManager.EXPECT().GetOrOpenSendStream(protocol.StreamID(12345)).Return(str, nil)
  206. str.EXPECT().handleMaxStreamDataFrame(f)
  207. err := sess.handleMaxStreamDataFrame(f)
  208. Expect(err).ToNot(HaveOccurred())
  209. })
  210. It("updates the flow control window of the connection", func() {
  211. offset := protocol.ByteCount(0x800000)
  212. connFC.EXPECT().UpdateSendWindow(offset)
  213. sess.handleMaxDataFrame(&wire.MaxDataFrame{ByteOffset: offset})
  214. })
  215. It("ignores MAX_STREAM_DATA frames for a closed stream", func() {
  216. streamManager.EXPECT().GetOrOpenSendStream(protocol.StreamID(10)).Return(nil, nil)
  217. Expect(sess.handleFrame(&wire.MaxStreamDataFrame{
  218. StreamID: 10,
  219. ByteOffset: 1337,
  220. }, 0, protocol.EncryptionUnspecified)).To(Succeed())
  221. })
  222. })
  223. Context("handling MAX_STREAM_ID frames", func() {
  224. It("passes the frame to the streamsMap", func() {
  225. f := &wire.MaxStreamsFrame{
  226. Type: protocol.StreamTypeUni,
  227. MaxStreams: 10,
  228. }
  229. streamManager.EXPECT().HandleMaxStreamsFrame(f)
  230. err := sess.handleMaxStreamsFrame(f)
  231. Expect(err).ToNot(HaveOccurred())
  232. })
  233. It("returns errors", func() {
  234. f := &wire.MaxStreamsFrame{MaxStreams: 10}
  235. testErr := errors.New("test error")
  236. streamManager.EXPECT().HandleMaxStreamsFrame(f).Return(testErr)
  237. err := sess.handleMaxStreamsFrame(f)
  238. Expect(err).To(MatchError(testErr))
  239. })
  240. })
  241. Context("handling STOP_SENDING frames", func() {
  242. It("passes the frame to the stream", func() {
  243. f := &wire.StopSendingFrame{
  244. StreamID: 5,
  245. ErrorCode: 10,
  246. }
  247. str := NewMockSendStreamI(mockCtrl)
  248. streamManager.EXPECT().GetOrOpenSendStream(protocol.StreamID(5)).Return(str, nil)
  249. str.EXPECT().handleStopSendingFrame(f)
  250. err := sess.handleStopSendingFrame(f)
  251. Expect(err).ToNot(HaveOccurred())
  252. })
  253. It("ignores STOP_SENDING frames for a closed stream", func() {
  254. streamManager.EXPECT().GetOrOpenSendStream(protocol.StreamID(3)).Return(nil, nil)
  255. Expect(sess.handleFrame(&wire.StopSendingFrame{
  256. StreamID: 3,
  257. ErrorCode: 1337,
  258. }, 0, protocol.EncryptionUnspecified)).To(Succeed())
  259. })
  260. })
  261. It("handles PING frames", func() {
  262. err := sess.handleFrame(&wire.PingFrame{}, 0, protocol.EncryptionUnspecified)
  263. Expect(err).NotTo(HaveOccurred())
  264. })
  265. It("rejects PATH_RESPONSE frames", func() {
  266. err := sess.handleFrame(&wire.PathResponseFrame{Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}}, 0, protocol.EncryptionUnspecified)
  267. Expect(err).To(MatchError("unexpected PATH_RESPONSE frame"))
  268. })
  269. It("handles PATH_CHALLENGE frames", func() {
  270. data := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
  271. err := sess.handleFrame(&wire.PathChallengeFrame{Data: data}, 0, protocol.EncryptionUnspecified)
  272. Expect(err).ToNot(HaveOccurred())
  273. frames, _ := sess.framer.AppendControlFrames(nil, 1000)
  274. Expect(frames).To(Equal([]wire.Frame{&wire.PathResponseFrame{Data: data}}))
  275. })
  276. It("handles BLOCKED frames", func() {
  277. err := sess.handleFrame(&wire.DataBlockedFrame{}, 0, protocol.EncryptionUnspecified)
  278. Expect(err).NotTo(HaveOccurred())
  279. })
  280. It("handles STREAM_BLOCKED frames", func() {
  281. err := sess.handleFrame(&wire.StreamDataBlockedFrame{}, 0, protocol.EncryptionUnspecified)
  282. Expect(err).NotTo(HaveOccurred())
  283. })
  284. It("handles STREAM_ID_BLOCKED frames", func() {
  285. err := sess.handleFrame(&wire.StreamsBlockedFrame{}, 0, protocol.EncryptionUnspecified)
  286. Expect(err).NotTo(HaveOccurred())
  287. })
  288. It("handles CONNECTION_CLOSE frames", func() {
  289. testErr := qerr.Error(qerr.ProofInvalid, "foobar")
  290. streamManager.EXPECT().CloseWithError(testErr)
  291. sessionRunner.EXPECT().removeConnectionID(gomock.Any())
  292. cryptoSetup.EXPECT().Close()
  293. go func() {
  294. defer GinkgoRecover()
  295. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  296. err := sess.run()
  297. Expect(err).To(MatchError(testErr))
  298. }()
  299. err := sess.handleFrame(&wire.ConnectionCloseFrame{ErrorCode: qerr.ProofInvalid, ReasonPhrase: "foobar"}, 0, protocol.EncryptionUnspecified)
  300. Expect(err).NotTo(HaveOccurred())
  301. Eventually(sess.Context().Done()).Should(BeClosed())
  302. })
  303. })
  304. It("tells its versions", func() {
  305. sess.version = 4242
  306. Expect(sess.GetVersion()).To(Equal(protocol.VersionNumber(4242)))
  307. })
  308. It("accepts new streams", func() {
  309. mstr := NewMockStreamI(mockCtrl)
  310. streamManager.EXPECT().AcceptStream().Return(mstr, nil)
  311. str, err := sess.AcceptStream()
  312. Expect(err).ToNot(HaveOccurred())
  313. Expect(str).To(Equal(mstr))
  314. })
  315. It("drops Retry packets", func() {
  316. hdr := wire.Header{
  317. IsLongHeader: true,
  318. Type: protocol.PacketTypeRetry,
  319. }
  320. buf := &bytes.Buffer{}
  321. (&wire.ExtendedHeader{Header: hdr}).Write(buf, sess.version)
  322. Expect(sess.handlePacketImpl(&receivedPacket{
  323. hdr: &hdr,
  324. data: buf.Bytes(),
  325. buffer: getPacketBuffer(),
  326. })).To(BeFalse())
  327. })
  328. Context("closing", func() {
  329. var (
  330. runErr error
  331. expectedRunErr error
  332. )
  333. BeforeEach(func() {
  334. Eventually(areSessionsRunning).Should(BeFalse())
  335. go func() {
  336. defer GinkgoRecover()
  337. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  338. runErr = sess.run()
  339. }()
  340. Eventually(areSessionsRunning).Should(BeTrue())
  341. expectedRunErr = nil
  342. })
  343. AfterEach(func() {
  344. if expectedRunErr != nil {
  345. Expect(runErr).To(MatchError(expectedRunErr))
  346. }
  347. })
  348. It("shuts down without error", func() {
  349. streamManager.EXPECT().CloseWithError(qerr.Error(qerr.PeerGoingAway, ""))
  350. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  351. cryptoSetup.EXPECT().Close()
  352. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{raw: []byte("connection close")}, nil)
  353. Expect(sess.Close()).To(Succeed())
  354. Eventually(areSessionsRunning).Should(BeFalse())
  355. Expect(mconn.written).To(HaveLen(1))
  356. Expect(mconn.written).To(Receive(ContainSubstring("connection close")))
  357. Expect(sess.Context().Done()).To(BeClosed())
  358. })
  359. It("only closes once", func() {
  360. streamManager.EXPECT().CloseWithError(qerr.Error(qerr.PeerGoingAway, ""))
  361. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  362. cryptoSetup.EXPECT().Close()
  363. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  364. Expect(sess.Close()).To(Succeed())
  365. Expect(sess.Close()).To(Succeed())
  366. Eventually(areSessionsRunning).Should(BeFalse())
  367. Expect(mconn.written).To(HaveLen(1))
  368. Expect(sess.Context().Done()).To(BeClosed())
  369. })
  370. It("closes streams with proper error", func() {
  371. testErr := errors.New("test error")
  372. streamManager.EXPECT().CloseWithError(qerr.Error(0x1337, testErr.Error()))
  373. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  374. cryptoSetup.EXPECT().Close()
  375. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  376. sess.CloseWithError(0x1337, testErr)
  377. Eventually(areSessionsRunning).Should(BeFalse())
  378. Expect(sess.Context().Done()).To(BeClosed())
  379. })
  380. It("closes the session in order to recreate it", func() {
  381. streamManager.EXPECT().CloseWithError(gomock.Any())
  382. sessionRunner.EXPECT().removeConnectionID(gomock.Any())
  383. cryptoSetup.EXPECT().Close()
  384. sess.closeForRecreating()
  385. Expect(mconn.written).To(BeEmpty()) // no CONNECTION_CLOSE or PUBLIC_RESET sent
  386. Eventually(areSessionsRunning).Should(BeFalse())
  387. expectedRunErr = errCloseForRecreating
  388. })
  389. It("destroys the session", func() {
  390. testErr := errors.New("close")
  391. streamManager.EXPECT().CloseWithError(gomock.Any())
  392. sessionRunner.EXPECT().removeConnectionID(gomock.Any())
  393. cryptoSetup.EXPECT().Close()
  394. sess.destroy(testErr)
  395. Eventually(areSessionsRunning).Should(BeFalse())
  396. Expect(mconn.written).To(BeEmpty()) // no CONNECTION_CLOSE or PUBLIC_RESET sent
  397. expectedRunErr = testErr
  398. })
  399. It("cancels the context when the run loop exists", func() {
  400. streamManager.EXPECT().CloseWithError(gomock.Any())
  401. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  402. cryptoSetup.EXPECT().Close()
  403. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  404. returned := make(chan struct{})
  405. go func() {
  406. defer GinkgoRecover()
  407. ctx := sess.Context()
  408. <-ctx.Done()
  409. Expect(ctx.Err()).To(MatchError(context.Canceled))
  410. close(returned)
  411. }()
  412. Consistently(returned).ShouldNot(BeClosed())
  413. sess.Close()
  414. Eventually(returned).Should(BeClosed())
  415. })
  416. It("retransmits the CONNECTION_CLOSE packet if packets are arriving late", func() {
  417. streamManager.EXPECT().CloseWithError(gomock.Any())
  418. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  419. cryptoSetup.EXPECT().Close()
  420. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{raw: []byte("foobar")}, nil)
  421. sess.Close()
  422. Expect(mconn.written).To(Receive(Equal([]byte("foobar")))) // receive the CONNECTION_CLOSE
  423. Eventually(sess.Context().Done()).Should(BeClosed())
  424. for i := 1; i <= 20; i++ {
  425. sess.handlePacket(&receivedPacket{})
  426. if i == 1 || i == 2 || i == 4 || i == 8 || i == 16 {
  427. Expect(mconn.written).To(Receive(Equal([]byte("foobar")))) // receive the CONNECTION_CLOSE
  428. } else {
  429. Expect(mconn.written).To(HaveLen(0))
  430. }
  431. }
  432. })
  433. })
  434. Context("receiving packets", func() {
  435. var unpacker *MockUnpacker
  436. BeforeEach(func() {
  437. unpacker = NewMockUnpacker(mockCtrl)
  438. sess.unpacker = unpacker
  439. })
  440. getData := func(extHdr *wire.ExtendedHeader) []byte {
  441. buf := &bytes.Buffer{}
  442. Expect(extHdr.Write(buf, sess.version)).To(Succeed())
  443. // need to set extHdr.Header, since the wire.Header contains the parsed length
  444. hdr, err := wire.ParseHeader(bytes.NewReader(buf.Bytes()), 0)
  445. Expect(err).ToNot(HaveOccurred())
  446. extHdr.Header = *hdr
  447. return buf.Bytes()
  448. }
  449. It("informs the ReceivedPacketHandler about non-retransmittable packets", func() {
  450. hdr := &wire.ExtendedHeader{
  451. PacketNumber: 0x37,
  452. PacketNumberLen: protocol.PacketNumberLen1,
  453. }
  454. rcvTime := time.Now().Add(-10 * time.Second)
  455. unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any()).Return(&unpackedPacket{
  456. packetNumber: 0x1337,
  457. encryptionLevel: protocol.EncryptionInitial,
  458. hdr: hdr,
  459. data: []byte{0}, // one PADDING frame
  460. }, nil)
  461. rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl)
  462. rph.EXPECT().ReceivedPacket(protocol.PacketNumber(0x1337), protocol.EncryptionInitial, rcvTime, false)
  463. sess.receivedPacketHandler = rph
  464. Expect(sess.handlePacketImpl(insertPacketBuffer(&receivedPacket{
  465. rcvTime: rcvTime,
  466. hdr: &hdr.Header,
  467. data: getData(hdr),
  468. }))).To(BeTrue())
  469. })
  470. It("informs the ReceivedPacketHandler about retransmittable packets", func() {
  471. hdr := &wire.ExtendedHeader{
  472. PacketNumber: 0x37,
  473. PacketNumberLen: protocol.PacketNumberLen1,
  474. }
  475. rcvTime := time.Now().Add(-10 * time.Second)
  476. buf := &bytes.Buffer{}
  477. Expect((&wire.PingFrame{}).Write(buf, sess.version)).To(Succeed())
  478. unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any()).Return(&unpackedPacket{
  479. packetNumber: 0x1337,
  480. encryptionLevel: protocol.EncryptionHandshake,
  481. hdr: hdr,
  482. data: buf.Bytes(),
  483. }, nil)
  484. rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl)
  485. rph.EXPECT().ReceivedPacket(protocol.PacketNumber(0x1337), protocol.EncryptionHandshake, rcvTime, true)
  486. sess.receivedPacketHandler = rph
  487. Expect(sess.handlePacketImpl(insertPacketBuffer(&receivedPacket{
  488. rcvTime: rcvTime,
  489. hdr: &hdr.Header,
  490. data: getData(hdr),
  491. }))).To(BeTrue())
  492. })
  493. It("drops a packet when unpacking fails", func() {
  494. unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any()).Return(nil, errors.New("unpack error"))
  495. streamManager.EXPECT().CloseWithError(gomock.Any())
  496. cryptoSetup.EXPECT().Close()
  497. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  498. go func() {
  499. defer GinkgoRecover()
  500. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  501. sess.run()
  502. }()
  503. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  504. sess.handlePacket(insertPacketBuffer(&receivedPacket{
  505. hdr: &wire.Header{},
  506. data: getData(&wire.ExtendedHeader{PacketNumberLen: protocol.PacketNumberLen1}),
  507. }))
  508. Consistently(sess.Context().Done()).ShouldNot(BeClosed())
  509. // make the go routine return
  510. sess.closeLocal(errors.New("close"))
  511. Eventually(sess.Context().Done()).Should(BeClosed())
  512. })
  513. It("rejects packets with empty payload", func() {
  514. unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any()).Return(&unpackedPacket{
  515. hdr: &wire.ExtendedHeader{},
  516. data: []byte{}, // no payload
  517. }, nil)
  518. streamManager.EXPECT().CloseWithError(gomock.Any())
  519. cryptoSetup.EXPECT().Close()
  520. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  521. done := make(chan struct{})
  522. go func() {
  523. defer GinkgoRecover()
  524. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  525. err := sess.run()
  526. Expect(err).To(MatchError(qerr.MissingPayload))
  527. close(done)
  528. }()
  529. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  530. sess.handlePacket(insertPacketBuffer(&receivedPacket{
  531. hdr: &wire.Header{},
  532. data: getData(&wire.ExtendedHeader{PacketNumberLen: protocol.PacketNumberLen1}),
  533. }))
  534. Eventually(done).Should(BeClosed())
  535. })
  536. It("handles duplicate packets", func() {
  537. hdr := &wire.ExtendedHeader{
  538. PacketNumber: 5,
  539. PacketNumberLen: protocol.PacketNumberLen1,
  540. }
  541. unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any()).Return(&unpackedPacket{
  542. encryptionLevel: protocol.Encryption1RTT,
  543. hdr: hdr,
  544. data: []byte{0}, // one PADDING frame
  545. }, nil).Times(2)
  546. Expect(sess.handlePacketImpl(insertPacketBuffer(&receivedPacket{hdr: &hdr.Header, data: getData(hdr)}))).To(BeTrue())
  547. Expect(sess.handlePacketImpl(insertPacketBuffer(&receivedPacket{hdr: &hdr.Header, data: getData(hdr)}))).To(BeTrue())
  548. })
  549. It("ignores 0-RTT packets", func() {
  550. Expect(sess.handlePacketImpl(insertPacketBuffer(&receivedPacket{
  551. hdr: &wire.Header{
  552. IsLongHeader: true,
  553. Type: protocol.PacketType0RTT,
  554. DestConnectionID: sess.srcConnID,
  555. },
  556. }))).To(BeFalse())
  557. })
  558. It("ignores packets with a different source connection ID", func() {
  559. hdr := &wire.Header{
  560. IsLongHeader: true,
  561. DestConnectionID: sess.destConnID,
  562. SrcConnectionID: sess.srcConnID,
  563. Length: 1,
  564. }
  565. // Send one packet, which might change the connection ID.
  566. // only EXPECT one call to the unpacker
  567. unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any()).Return(&unpackedPacket{
  568. encryptionLevel: protocol.Encryption1RTT,
  569. hdr: &wire.ExtendedHeader{Header: *hdr},
  570. data: []byte{0}, // one PADDING frame
  571. }, nil)
  572. Expect(sess.handlePacketImpl(insertPacketBuffer(&receivedPacket{
  573. hdr: hdr,
  574. data: getData(&wire.ExtendedHeader{PacketNumberLen: protocol.PacketNumberLen1}),
  575. }))).To(BeTrue())
  576. // The next packet has to be ignored, since the source connection ID doesn't match.
  577. Expect(sess.handlePacketImpl(insertPacketBuffer(&receivedPacket{
  578. hdr: &wire.Header{
  579. IsLongHeader: true,
  580. DestConnectionID: sess.destConnID,
  581. SrcConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
  582. Length: 1,
  583. },
  584. data: getData(&wire.ExtendedHeader{PacketNumberLen: protocol.PacketNumberLen1}),
  585. }))).To(BeFalse())
  586. })
  587. Context("updating the remote address", func() {
  588. It("doesn't support connection migration", func() {
  589. unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any()).Return(&unpackedPacket{
  590. encryptionLevel: protocol.Encryption1RTT,
  591. hdr: &wire.ExtendedHeader{},
  592. data: []byte{0}, // one PADDING frame
  593. }, nil)
  594. origAddr := sess.conn.(*mockConnection).remoteAddr
  595. remoteIP := &net.IPAddr{IP: net.IPv4(192, 168, 0, 100)}
  596. Expect(origAddr).ToNot(Equal(remoteIP))
  597. Expect(sess.handlePacketImpl(insertPacketBuffer(&receivedPacket{
  598. remoteAddr: remoteIP,
  599. hdr: &wire.Header{},
  600. data: getData(&wire.ExtendedHeader{PacketNumberLen: protocol.PacketNumberLen1}),
  601. }))).To(BeTrue())
  602. Expect(sess.conn.(*mockConnection).remoteAddr).To(Equal(origAddr))
  603. })
  604. })
  605. })
  606. Context("sending packets", func() {
  607. getPacket := func(pn protocol.PacketNumber) *packedPacket {
  608. buffer := getPacketBuffer()
  609. data := buffer.Slice[:0]
  610. data = append(data, []byte("foobar")...)
  611. return &packedPacket{
  612. raw: data,
  613. buffer: buffer,
  614. header: &wire.ExtendedHeader{PacketNumber: pn},
  615. }
  616. }
  617. It("sends packets", func() {
  618. packer.EXPECT().PackPacket().Return(getPacket(1), nil)
  619. Expect(sess.receivedPacketHandler.ReceivedPacket(0x035e, protocol.Encryption1RTT, time.Now(), true)).To(Succeed())
  620. sent, err := sess.sendPacket()
  621. Expect(err).NotTo(HaveOccurred())
  622. Expect(sent).To(BeTrue())
  623. })
  624. It("doesn't send packets if there's nothing to send", func() {
  625. packer.EXPECT().PackPacket().Return(getPacket(2), nil)
  626. Expect(sess.receivedPacketHandler.ReceivedPacket(0x035e, protocol.Encryption1RTT, time.Now(), true)).To(Succeed())
  627. sent, err := sess.sendPacket()
  628. Expect(err).NotTo(HaveOccurred())
  629. Expect(sent).To(BeTrue())
  630. })
  631. It("sends ACK only packets", func() {
  632. sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  633. sph.EXPECT().GetAlarmTimeout().AnyTimes()
  634. sph.EXPECT().SendMode().Return(ackhandler.SendAck)
  635. sph.EXPECT().ShouldSendNumPackets().Return(1000)
  636. packer.EXPECT().MaybePackAckPacket()
  637. sess.sentPacketHandler = sph
  638. Expect(sess.sendPackets()).To(Succeed())
  639. })
  640. It("adds a BLOCKED frame when it is connection-level flow control blocked", func() {
  641. fc := mocks.NewMockConnectionFlowController(mockCtrl)
  642. fc.EXPECT().IsNewlyBlocked().Return(true, protocol.ByteCount(1337))
  643. packer.EXPECT().PackPacket().Return(getPacket(1), nil)
  644. sess.connFlowController = fc
  645. sent, err := sess.sendPacket()
  646. Expect(err).NotTo(HaveOccurred())
  647. Expect(sent).To(BeTrue())
  648. frames, _ := sess.framer.AppendControlFrames(nil, 1000)
  649. Expect(frames).To(Equal([]wire.Frame{&wire.DataBlockedFrame{DataLimit: 1337}}))
  650. })
  651. It("sends a retransmission and a regular packet in the same run", func() {
  652. packetToRetransmit := &ackhandler.Packet{
  653. PacketNumber: 10,
  654. PacketType: protocol.PacketTypeHandshake,
  655. }
  656. retransmittedPacket := getPacket(123)
  657. newPacket := getPacket(234)
  658. sess.windowUpdateQueue.callback(&wire.MaxDataFrame{})
  659. sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  660. sph.EXPECT().DequeuePacketForRetransmission().Return(packetToRetransmit)
  661. sph.EXPECT().SendMode().Return(ackhandler.SendRetransmission)
  662. sph.EXPECT().SendMode().Return(ackhandler.SendAny)
  663. sph.EXPECT().ShouldSendNumPackets().Return(2)
  664. sph.EXPECT().TimeUntilSend()
  665. gomock.InOrder(
  666. packer.EXPECT().PackRetransmission(packetToRetransmit).Return([]*packedPacket{retransmittedPacket}, nil),
  667. sph.EXPECT().SentPacketsAsRetransmission(gomock.Any(), protocol.PacketNumber(10)).Do(func(packets []*ackhandler.Packet, _ protocol.PacketNumber) {
  668. Expect(packets).To(HaveLen(1))
  669. Expect(packets[0].PacketNumber).To(Equal(protocol.PacketNumber(123)))
  670. }),
  671. packer.EXPECT().PackPacket().Return(newPacket, nil),
  672. sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
  673. Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(234)))
  674. }),
  675. )
  676. sess.sentPacketHandler = sph
  677. Expect(sess.sendPackets()).To(Succeed())
  678. })
  679. It("sends multiple packets, if the retransmission is split", func() {
  680. packet := &ackhandler.Packet{
  681. PacketNumber: 42,
  682. Frames: []wire.Frame{&wire.StreamFrame{
  683. StreamID: 0x5,
  684. Data: []byte("foobar"),
  685. }},
  686. EncryptionLevel: protocol.Encryption1RTT,
  687. }
  688. retransmissions := []*packedPacket{getPacket(1337), getPacket(1338)}
  689. sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  690. sph.EXPECT().DequeuePacketForRetransmission().Return(packet)
  691. packer.EXPECT().PackRetransmission(packet).Return(retransmissions, nil)
  692. sph.EXPECT().SentPacketsAsRetransmission(gomock.Any(), protocol.PacketNumber(42)).Do(func(packets []*ackhandler.Packet, _ protocol.PacketNumber) {
  693. Expect(packets).To(HaveLen(2))
  694. Expect(packets[0].PacketNumber).To(Equal(protocol.PacketNumber(1337)))
  695. Expect(packets[1].PacketNumber).To(Equal(protocol.PacketNumber(1338)))
  696. })
  697. sess.sentPacketHandler = sph
  698. sent, err := sess.maybeSendRetransmission()
  699. Expect(err).NotTo(HaveOccurred())
  700. Expect(sent).To(BeTrue())
  701. Expect(mconn.written).To(HaveLen(2))
  702. })
  703. It("sends a probe packet", func() {
  704. packetToRetransmit := &ackhandler.Packet{
  705. PacketNumber: 0x42,
  706. PacketType: protocol.PacketTypeHandshake,
  707. }
  708. retransmittedPacket := getPacket(123)
  709. sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  710. sph.EXPECT().TimeUntilSend()
  711. sph.EXPECT().SendMode().Return(ackhandler.SendPTO)
  712. sph.EXPECT().ShouldSendNumPackets().Return(1)
  713. sph.EXPECT().DequeueProbePacket().Return(packetToRetransmit, nil)
  714. packer.EXPECT().PackRetransmission(packetToRetransmit).Return([]*packedPacket{retransmittedPacket}, nil)
  715. sph.EXPECT().SentPacketsAsRetransmission(gomock.Any(), protocol.PacketNumber(0x42)).Do(func(packets []*ackhandler.Packet, _ protocol.PacketNumber) {
  716. Expect(packets).To(HaveLen(1))
  717. Expect(packets[0].PacketNumber).To(Equal(protocol.PacketNumber(123)))
  718. })
  719. sess.sentPacketHandler = sph
  720. Expect(sess.sendPackets()).To(Succeed())
  721. })
  722. It("doesn't send when the SentPacketHandler doesn't allow it", func() {
  723. sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  724. sph.EXPECT().SendMode().Return(ackhandler.SendNone)
  725. sess.sentPacketHandler = sph
  726. err := sess.sendPackets()
  727. Expect(err).ToNot(HaveOccurred())
  728. })
  729. Context("packet pacing", func() {
  730. var sph *mockackhandler.MockSentPacketHandler
  731. BeforeEach(func() {
  732. sph = mockackhandler.NewMockSentPacketHandler(mockCtrl)
  733. sph.EXPECT().GetAlarmTimeout().AnyTimes()
  734. sph.EXPECT().DequeuePacketForRetransmission().AnyTimes()
  735. sess.sentPacketHandler = sph
  736. streamManager.EXPECT().CloseWithError(gomock.Any())
  737. })
  738. It("sends multiple packets one by one immediately", func() {
  739. sph.EXPECT().SentPacket(gomock.Any()).Times(2)
  740. sph.EXPECT().ShouldSendNumPackets().Return(1).Times(2)
  741. sph.EXPECT().TimeUntilSend().Return(time.Now()).Times(2)
  742. sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour))
  743. sph.EXPECT().SendMode().Return(ackhandler.SendAny).Times(2) // allow 2 packets...
  744. packer.EXPECT().PackPacket().Return(getPacket(10), nil)
  745. packer.EXPECT().PackPacket().Return(getPacket(11), nil)
  746. done := make(chan struct{})
  747. go func() {
  748. defer GinkgoRecover()
  749. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  750. sess.run()
  751. close(done)
  752. }()
  753. sess.scheduleSending()
  754. Eventually(mconn.written).Should(HaveLen(2))
  755. Consistently(mconn.written).Should(HaveLen(2))
  756. // make the go routine return
  757. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  758. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  759. cryptoSetup.EXPECT().Close()
  760. sess.Close()
  761. Eventually(done).Should(BeClosed())
  762. })
  763. // when becoming congestion limited, at some point the SendMode will change from SendAny to SendAck
  764. // we shouldn't send the ACK in the same run
  765. It("doesn't send an ACK right after becoming congestion limited", func() {
  766. sph.EXPECT().SentPacket(gomock.Any())
  767. sph.EXPECT().ShouldSendNumPackets().Return(1000)
  768. sph.EXPECT().TimeUntilSend().Return(time.Now())
  769. sph.EXPECT().SendMode().Return(ackhandler.SendAny)
  770. sph.EXPECT().SendMode().Return(ackhandler.SendAck)
  771. packer.EXPECT().PackPacket().Return(getPacket(100), nil)
  772. done := make(chan struct{})
  773. go func() {
  774. defer GinkgoRecover()
  775. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  776. sess.run()
  777. close(done)
  778. }()
  779. sess.scheduleSending()
  780. Eventually(mconn.written).Should(HaveLen(1))
  781. Consistently(mconn.written).Should(HaveLen(1))
  782. // make the go routine return
  783. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  784. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  785. cryptoSetup.EXPECT().Close()
  786. sess.Close()
  787. Eventually(done).Should(BeClosed())
  788. })
  789. It("paces packets", func() {
  790. pacingDelay := scaleDuration(100 * time.Millisecond)
  791. sph.EXPECT().SentPacket(gomock.Any()).Times(2)
  792. sph.EXPECT().TimeUntilSend().Return(time.Now().Add(-time.Minute)) // send one packet immediately
  793. sph.EXPECT().TimeUntilSend().Return(time.Now().Add(pacingDelay)) // send one
  794. sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour))
  795. sph.EXPECT().ShouldSendNumPackets().Times(2).Return(1)
  796. sph.EXPECT().SendMode().Return(ackhandler.SendAny).AnyTimes()
  797. packer.EXPECT().PackPacket().Return(getPacket(100), nil)
  798. packer.EXPECT().PackPacket().Return(getPacket(101), nil)
  799. done := make(chan struct{})
  800. go func() {
  801. defer GinkgoRecover()
  802. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  803. sess.run()
  804. close(done)
  805. }()
  806. sess.scheduleSending()
  807. Eventually(mconn.written).Should(HaveLen(1))
  808. Consistently(mconn.written, pacingDelay/2).Should(HaveLen(1))
  809. Eventually(mconn.written, 2*pacingDelay).Should(HaveLen(2))
  810. // make the go routine return
  811. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  812. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  813. cryptoSetup.EXPECT().Close()
  814. sess.Close()
  815. Eventually(done).Should(BeClosed())
  816. })
  817. It("sends multiple packets at once", func() {
  818. sph.EXPECT().SentPacket(gomock.Any()).Times(3)
  819. sph.EXPECT().ShouldSendNumPackets().Return(3)
  820. sph.EXPECT().TimeUntilSend().Return(time.Now())
  821. sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour))
  822. sph.EXPECT().SendMode().Return(ackhandler.SendAny).Times(3)
  823. packer.EXPECT().PackPacket().Return(getPacket(1000), nil)
  824. packer.EXPECT().PackPacket().Return(getPacket(1001), nil)
  825. packer.EXPECT().PackPacket().Return(getPacket(1002), nil)
  826. done := make(chan struct{})
  827. go func() {
  828. defer GinkgoRecover()
  829. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  830. sess.run()
  831. close(done)
  832. }()
  833. sess.scheduleSending()
  834. Eventually(mconn.written).Should(HaveLen(3))
  835. // make the go routine return
  836. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  837. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  838. cryptoSetup.EXPECT().Close()
  839. sess.Close()
  840. Eventually(done).Should(BeClosed())
  841. })
  842. It("doesn't set a pacing timer when there is no data to send", func() {
  843. sph.EXPECT().TimeUntilSend().Return(time.Now())
  844. sph.EXPECT().ShouldSendNumPackets().Return(1)
  845. sph.EXPECT().SendMode().Return(ackhandler.SendAny).AnyTimes()
  846. packer.EXPECT().PackPacket()
  847. done := make(chan struct{})
  848. go func() {
  849. defer GinkgoRecover()
  850. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  851. sess.run()
  852. close(done)
  853. }()
  854. sess.scheduleSending() // no packet will get sent
  855. Consistently(mconn.written).ShouldNot(Receive())
  856. // make the go routine return
  857. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  858. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  859. cryptoSetup.EXPECT().Close()
  860. sess.Close()
  861. Eventually(done).Should(BeClosed())
  862. })
  863. })
  864. Context("scheduling sending", func() {
  865. It("sends when scheduleSending is called", func() {
  866. sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  867. sph.EXPECT().GetAlarmTimeout().AnyTimes()
  868. sph.EXPECT().TimeUntilSend().AnyTimes()
  869. sph.EXPECT().SendMode().Return(ackhandler.SendAny).AnyTimes()
  870. sph.EXPECT().ShouldSendNumPackets().AnyTimes().Return(1)
  871. sph.EXPECT().SentPacket(gomock.Any())
  872. sess.sentPacketHandler = sph
  873. packer.EXPECT().PackPacket().Return(getPacket(1), nil)
  874. go func() {
  875. defer GinkgoRecover()
  876. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  877. sess.run()
  878. }()
  879. Consistently(mconn.written).ShouldNot(Receive())
  880. sess.scheduleSending()
  881. Eventually(mconn.written).Should(Receive())
  882. // make the go routine return
  883. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  884. streamManager.EXPECT().CloseWithError(gomock.Any())
  885. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  886. cryptoSetup.EXPECT().Close()
  887. sess.Close()
  888. Eventually(sess.Context().Done()).Should(BeClosed())
  889. })
  890. It("sets the timer to the ack timer", func() {
  891. packer.EXPECT().PackPacket().Return(getPacket(1234), nil)
  892. sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
  893. sph.EXPECT().TimeUntilSend().Return(time.Now())
  894. sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour))
  895. sph.EXPECT().GetAlarmTimeout().AnyTimes()
  896. sph.EXPECT().SendMode().Return(ackhandler.SendAny).AnyTimes()
  897. sph.EXPECT().ShouldSendNumPackets().Return(1)
  898. sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
  899. Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(1234)))
  900. })
  901. sess.sentPacketHandler = sph
  902. rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl)
  903. rph.EXPECT().GetAlarmTimeout().Return(time.Now().Add(10 * time.Millisecond))
  904. // make the run loop wait
  905. rph.EXPECT().GetAlarmTimeout().Return(time.Now().Add(time.Hour)).MaxTimes(1)
  906. sess.receivedPacketHandler = rph
  907. go func() {
  908. defer GinkgoRecover()
  909. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  910. sess.run()
  911. }()
  912. Eventually(mconn.written).Should(Receive())
  913. // make sure the go routine returns
  914. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  915. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  916. streamManager.EXPECT().CloseWithError(gomock.Any())
  917. cryptoSetup.EXPECT().Close()
  918. sess.Close()
  919. Eventually(sess.Context().Done()).Should(BeClosed())
  920. })
  921. })
  922. })
  923. It("closes when RunHandshake() errors", func() {
  924. testErr := errors.New("crypto setup error")
  925. streamManager.EXPECT().CloseWithError(qerr.Error(qerr.InternalError, testErr.Error()))
  926. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  927. cryptoSetup.EXPECT().Close()
  928. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  929. go func() {
  930. defer GinkgoRecover()
  931. cryptoSetup.EXPECT().RunHandshake().Return(testErr)
  932. err := sess.run()
  933. Expect(err).To(MatchError(testErr))
  934. }()
  935. Eventually(sess.Context().Done()).Should(BeClosed())
  936. })
  937. It("calls the onHandshakeComplete callback when the handshake completes", func() {
  938. packer.EXPECT().PackPacket().AnyTimes()
  939. go func() {
  940. defer GinkgoRecover()
  941. sessionRunner.EXPECT().onHandshakeComplete(gomock.Any())
  942. cryptoSetup.EXPECT().RunHandshake()
  943. sess.run()
  944. }()
  945. Consistently(sess.Context().Done()).ShouldNot(BeClosed())
  946. // make sure the go routine returns
  947. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  948. streamManager.EXPECT().CloseWithError(gomock.Any())
  949. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  950. cryptoSetup.EXPECT().Close()
  951. Expect(sess.Close()).To(Succeed())
  952. Eventually(sess.Context().Done()).Should(BeClosed())
  953. })
  954. It("sends a forward-secure packet when the handshake completes", func() {
  955. done := make(chan struct{})
  956. gomock.InOrder(
  957. sessionRunner.EXPECT().onHandshakeComplete(gomock.Any()),
  958. packer.EXPECT().PackPacket().DoAndReturn(func() (*packedPacket, error) {
  959. defer close(done)
  960. return &packedPacket{
  961. header: &wire.ExtendedHeader{},
  962. buffer: getPacketBuffer(),
  963. }, nil
  964. }),
  965. packer.EXPECT().PackPacket().AnyTimes(),
  966. )
  967. go func() {
  968. defer GinkgoRecover()
  969. cryptoSetup.EXPECT().RunHandshake()
  970. sess.run()
  971. }()
  972. Eventually(done).Should(BeClosed())
  973. //make sure the go routine returns
  974. streamManager.EXPECT().CloseWithError(gomock.Any())
  975. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  976. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  977. cryptoSetup.EXPECT().Close()
  978. Expect(sess.Close()).To(Succeed())
  979. Eventually(sess.Context().Done()).Should(BeClosed())
  980. })
  981. It("doesn't return a run error when closing", func() {
  982. done := make(chan struct{})
  983. go func() {
  984. defer GinkgoRecover()
  985. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  986. Expect(sess.run()).To(Succeed())
  987. close(done)
  988. }()
  989. streamManager.EXPECT().CloseWithError(gomock.Any())
  990. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  991. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  992. cryptoSetup.EXPECT().Close()
  993. Expect(sess.Close()).To(Succeed())
  994. Eventually(done).Should(BeClosed())
  995. })
  996. It("passes errors to the session runner", func() {
  997. testErr := errors.New("handshake error")
  998. done := make(chan struct{})
  999. go func() {
  1000. defer GinkgoRecover()
  1001. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  1002. err := sess.run()
  1003. Expect(err).To(MatchError(qerr.Error(0x1337, testErr.Error())))
  1004. close(done)
  1005. }()
  1006. streamManager.EXPECT().CloseWithError(gomock.Any())
  1007. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1008. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  1009. cryptoSetup.EXPECT().Close()
  1010. Expect(sess.CloseWithError(0x1337, testErr)).To(Succeed())
  1011. Eventually(done).Should(BeClosed())
  1012. })
  1013. Context("transport parameters", func() {
  1014. It("errors if it can't unmarshal the TransportParameters", func() {
  1015. go func() {
  1016. defer GinkgoRecover()
  1017. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  1018. err := sess.run()
  1019. Expect(err).To(HaveOccurred())
  1020. Expect(err.Error()).To(ContainSubstring("transport parameter"))
  1021. }()
  1022. streamManager.EXPECT().CloseWithError(gomock.Any())
  1023. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1024. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  1025. cryptoSetup.EXPECT().Close()
  1026. sess.processTransportParameters([]byte("invalid"))
  1027. Eventually(sess.Context().Done()).Should(BeClosed())
  1028. })
  1029. It("process transport parameters received from the client", func() {
  1030. go func() {
  1031. defer GinkgoRecover()
  1032. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  1033. sess.run()
  1034. }()
  1035. params := &handshake.TransportParameters{
  1036. IdleTimeout: 90 * time.Second,
  1037. InitialMaxStreamDataBidiLocal: 0x5000,
  1038. InitialMaxData: 0x5000,
  1039. // marshaling always sets it to this value
  1040. MaxPacketSize: protocol.MaxReceivePacketSize,
  1041. }
  1042. chtp := &handshake.ClientHelloTransportParameters{
  1043. InitialVersion: sess.version,
  1044. Parameters: *params,
  1045. }
  1046. streamManager.EXPECT().UpdateLimits(params)
  1047. packer.EXPECT().HandleTransportParameters(params)
  1048. sess.processTransportParameters(chtp.Marshal())
  1049. // make the go routine return
  1050. streamManager.EXPECT().CloseWithError(gomock.Any())
  1051. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1052. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  1053. cryptoSetup.EXPECT().Close()
  1054. sess.Close()
  1055. Eventually(sess.Context().Done()).Should(BeClosed())
  1056. })
  1057. It("accepts a valid version negotiation", func() {
  1058. sess.version = 42
  1059. sess.config.Versions = []protocol.VersionNumber{13, 37, 42}
  1060. chtp := &handshake.ClientHelloTransportParameters{
  1061. InitialVersion: 22, // this must be an unsupported version
  1062. }
  1063. _, err := sess.processTransportParametersForServer(chtp.Marshal())
  1064. Expect(err).ToNot(HaveOccurred())
  1065. })
  1066. It("erros when a version negotiation was performed, although we already support the initial version", func() {
  1067. sess.version = 42
  1068. sess.config.Versions = []protocol.VersionNumber{13, 37, 42}
  1069. chtp := &handshake.ClientHelloTransportParameters{
  1070. InitialVersion: 13, // this must be a supported version
  1071. }
  1072. _, err := sess.processTransportParametersForServer(chtp.Marshal())
  1073. Expect(err).To(MatchError("VersionNegotiationMismatch: Client should have used the initial version"))
  1074. })
  1075. })
  1076. Context("keep-alives", func() {
  1077. // should be shorter than the local timeout for these tests
  1078. // otherwise we'd send a CONNECTION_CLOSE in the tests where we're testing that no PING is sent
  1079. remoteIdleTimeout := 20 * time.Second
  1080. BeforeEach(func() {
  1081. sess.peerParams = &handshake.TransportParameters{IdleTimeout: remoteIdleTimeout}
  1082. })
  1083. It("sends a PING", func() {
  1084. sess.handshakeComplete = true
  1085. sess.config.KeepAlive = true
  1086. sess.lastNetworkActivityTime = time.Now().Add(-remoteIdleTimeout / 2)
  1087. sent := make(chan struct{})
  1088. packer.EXPECT().PackPacket().Do(func() (*packedPacket, error) {
  1089. close(sent)
  1090. return nil, nil
  1091. })
  1092. done := make(chan struct{})
  1093. go func() {
  1094. defer GinkgoRecover()
  1095. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  1096. sess.run()
  1097. close(done)
  1098. }()
  1099. Eventually(sent).Should(BeClosed())
  1100. // make the go routine return
  1101. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1102. streamManager.EXPECT().CloseWithError(gomock.Any())
  1103. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  1104. cryptoSetup.EXPECT().Close()
  1105. sess.Close()
  1106. Eventually(done).Should(BeClosed())
  1107. })
  1108. It("doesn't send a PING packet if keep-alive is disabled", func() {
  1109. sess.handshakeComplete = true
  1110. sess.config.KeepAlive = false
  1111. sess.lastNetworkActivityTime = time.Now().Add(-remoteIdleTimeout / 2)
  1112. done := make(chan struct{})
  1113. go func() {
  1114. defer GinkgoRecover()
  1115. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  1116. sess.run()
  1117. close(done)
  1118. }()
  1119. Consistently(mconn.written).ShouldNot(Receive())
  1120. // make the go routine return
  1121. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1122. streamManager.EXPECT().CloseWithError(gomock.Any())
  1123. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  1124. cryptoSetup.EXPECT().Close()
  1125. sess.Close()
  1126. Eventually(done).Should(BeClosed())
  1127. })
  1128. It("doesn't send a PING if the handshake isn't completed yet", func() {
  1129. sess.handshakeComplete = false
  1130. sess.config.KeepAlive = true
  1131. sess.lastNetworkActivityTime = time.Now().Add(-remoteIdleTimeout / 2)
  1132. done := make(chan struct{})
  1133. go func() {
  1134. defer GinkgoRecover()
  1135. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  1136. sess.run()
  1137. close(done)
  1138. }()
  1139. Consistently(mconn.written).ShouldNot(Receive())
  1140. // make the go routine return
  1141. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1142. streamManager.EXPECT().CloseWithError(gomock.Any())
  1143. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  1144. cryptoSetup.EXPECT().Close()
  1145. sess.Close()
  1146. Eventually(done).Should(BeClosed())
  1147. })
  1148. })
  1149. Context("timeouts", func() {
  1150. BeforeEach(func() {
  1151. streamManager.EXPECT().CloseWithError(gomock.Any())
  1152. })
  1153. It("times out due to no network activity", func() {
  1154. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1155. sess.handshakeComplete = true
  1156. sess.lastNetworkActivityTime = time.Now().Add(-time.Hour)
  1157. done := make(chan struct{})
  1158. cryptoSetup.EXPECT().Close()
  1159. packer.EXPECT().PackConnectionClose(gomock.Any()).DoAndReturn(func(f *wire.ConnectionCloseFrame) (*packedPacket, error) {
  1160. Expect(f.ErrorCode).To(Equal(qerr.NetworkIdleTimeout))
  1161. return &packedPacket{}, nil
  1162. })
  1163. go func() {
  1164. defer GinkgoRecover()
  1165. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  1166. err := sess.run()
  1167. Expect(err.(*qerr.QuicError).ErrorCode).To(Equal(qerr.NetworkIdleTimeout))
  1168. close(done)
  1169. }()
  1170. Eventually(done).Should(BeClosed())
  1171. })
  1172. It("times out due to non-completed handshake", func() {
  1173. sess.sessionCreationTime = time.Now().Add(-protocol.DefaultHandshakeTimeout).Add(-time.Second)
  1174. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1175. cryptoSetup.EXPECT().Close()
  1176. packer.EXPECT().PackConnectionClose(gomock.Any()).DoAndReturn(func(f *wire.ConnectionCloseFrame) (*packedPacket, error) {
  1177. Expect(f.ErrorCode).To(Equal(qerr.HandshakeTimeout))
  1178. return &packedPacket{}, nil
  1179. })
  1180. done := make(chan struct{})
  1181. go func() {
  1182. defer GinkgoRecover()
  1183. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  1184. err := sess.run()
  1185. Expect(err.(*qerr.QuicError).ErrorCode).To(Equal(qerr.HandshakeTimeout))
  1186. close(done)
  1187. }()
  1188. Eventually(done).Should(BeClosed())
  1189. })
  1190. It("does not use the idle timeout before the handshake complete", func() {
  1191. sess.config.IdleTimeout = 9999 * time.Second
  1192. sess.lastNetworkActivityTime = time.Now().Add(-time.Minute)
  1193. packer.EXPECT().PackConnectionClose(gomock.Any()).DoAndReturn(func(f *wire.ConnectionCloseFrame) (*packedPacket, error) {
  1194. Expect(f.ErrorCode).To(Equal(qerr.PeerGoingAway))
  1195. return &packedPacket{}, nil
  1196. })
  1197. // the handshake timeout is irrelevant here, since it depends on the time the session was created,
  1198. // and not on the last network activity
  1199. go func() {
  1200. defer GinkgoRecover()
  1201. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  1202. sess.run()
  1203. }()
  1204. Consistently(sess.Context().Done()).ShouldNot(BeClosed())
  1205. // make the go routine return
  1206. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1207. cryptoSetup.EXPECT().Close()
  1208. sess.Close()
  1209. Eventually(sess.Context().Done()).Should(BeClosed())
  1210. })
  1211. It("closes the session due to the idle timeout after handshake", func() {
  1212. packer.EXPECT().PackPacket().AnyTimes()
  1213. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1214. cryptoSetup.EXPECT().Close()
  1215. packer.EXPECT().PackConnectionClose(gomock.Any()).DoAndReturn(func(f *wire.ConnectionCloseFrame) (*packedPacket, error) {
  1216. Expect(f.ErrorCode).To(Equal(qerr.NetworkIdleTimeout))
  1217. return &packedPacket{}, nil
  1218. })
  1219. sess.config.IdleTimeout = 0
  1220. done := make(chan struct{})
  1221. go func() {
  1222. defer GinkgoRecover()
  1223. sessionRunner.EXPECT().onHandshakeComplete(sess)
  1224. cryptoSetup.EXPECT().RunHandshake()
  1225. err := sess.run()
  1226. Expect(err.(*qerr.QuicError).ErrorCode).To(Equal(qerr.NetworkIdleTimeout))
  1227. close(done)
  1228. }()
  1229. Eventually(done).Should(BeClosed())
  1230. })
  1231. })
  1232. It("stores up to MaxSessionUnprocessedPackets packets", func(done Done) {
  1233. // Nothing here should block
  1234. for i := protocol.PacketNumber(0); i < protocol.MaxSessionUnprocessedPackets+10; i++ {
  1235. sess.handlePacket(&receivedPacket{})
  1236. }
  1237. close(done)
  1238. }, 0.5)
  1239. Context("getting streams", func() {
  1240. It("returns a new stream", func() {
  1241. mstr := NewMockStreamI(mockCtrl)
  1242. streamManager.EXPECT().GetOrOpenSendStream(protocol.StreamID(11)).Return(mstr, nil)
  1243. str, err := sess.GetOrOpenStream(11)
  1244. Expect(err).ToNot(HaveOccurred())
  1245. Expect(str).To(Equal(mstr))
  1246. })
  1247. It("returns a nil-value (not an interface with value nil) for closed streams", func() {
  1248. strI := Stream(nil)
  1249. streamManager.EXPECT().GetOrOpenSendStream(protocol.StreamID(1337)).Return(strI, nil)
  1250. str, err := sess.GetOrOpenStream(1337)
  1251. Expect(err).ToNot(HaveOccurred())
  1252. // make sure that the returned value is a plain nil, not an Stream with value nil
  1253. _, ok := str.(Stream)
  1254. Expect(ok).To(BeFalse())
  1255. })
  1256. It("errors when trying to get a unidirectional stream", func() {
  1257. streamManager.EXPECT().GetOrOpenSendStream(protocol.StreamID(100)).Return(&sendStream{}, nil)
  1258. _, err := sess.GetOrOpenStream(100)
  1259. Expect(err).To(MatchError("Stream 100 is not a bidirectional stream"))
  1260. })
  1261. It("opens streams", func() {
  1262. mstr := NewMockStreamI(mockCtrl)
  1263. streamManager.EXPECT().OpenStream().Return(mstr, nil)
  1264. str, err := sess.OpenStream()
  1265. Expect(err).ToNot(HaveOccurred())
  1266. Expect(str).To(Equal(mstr))
  1267. })
  1268. It("opens streams synchronously", func() {
  1269. mstr := NewMockStreamI(mockCtrl)
  1270. streamManager.EXPECT().OpenStreamSync().Return(mstr, nil)
  1271. str, err := sess.OpenStreamSync()
  1272. Expect(err).ToNot(HaveOccurred())
  1273. Expect(str).To(Equal(mstr))
  1274. })
  1275. It("opens unidirectional streams", func() {
  1276. mstr := NewMockSendStreamI(mockCtrl)
  1277. streamManager.EXPECT().OpenUniStream().Return(mstr, nil)
  1278. str, err := sess.OpenUniStream()
  1279. Expect(err).ToNot(HaveOccurred())
  1280. Expect(str).To(Equal(mstr))
  1281. })
  1282. It("opens unidirectional streams synchronously", func() {
  1283. mstr := NewMockSendStreamI(mockCtrl)
  1284. streamManager.EXPECT().OpenUniStreamSync().Return(mstr, nil)
  1285. str, err := sess.OpenUniStreamSync()
  1286. Expect(err).ToNot(HaveOccurred())
  1287. Expect(str).To(Equal(mstr))
  1288. })
  1289. It("accepts streams", func() {
  1290. mstr := NewMockStreamI(mockCtrl)
  1291. streamManager.EXPECT().AcceptStream().Return(mstr, nil)
  1292. str, err := sess.AcceptStream()
  1293. Expect(err).ToNot(HaveOccurred())
  1294. Expect(str).To(Equal(mstr))
  1295. })
  1296. It("accepts unidirectional streams", func() {
  1297. mstr := NewMockReceiveStreamI(mockCtrl)
  1298. streamManager.EXPECT().AcceptUniStream().Return(mstr, nil)
  1299. str, err := sess.AcceptUniStream()
  1300. Expect(err).ToNot(HaveOccurred())
  1301. Expect(str).To(Equal(mstr))
  1302. })
  1303. })
  1304. It("returns the local address", func() {
  1305. addr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337}
  1306. mconn.localAddr = addr
  1307. Expect(sess.LocalAddr()).To(Equal(addr))
  1308. })
  1309. It("returns the remote address", func() {
  1310. addr := &net.UDPAddr{IP: net.IPv4(1, 2, 7, 1), Port: 7331}
  1311. mconn.remoteAddr = addr
  1312. Expect(sess.RemoteAddr()).To(Equal(addr))
  1313. })
  1314. })
  1315. var _ = Describe("Client Session", func() {
  1316. var (
  1317. sess *session
  1318. sessionRunner *MockSessionRunner
  1319. packer *MockPacker
  1320. mconn *mockConnection
  1321. cryptoSetup *mocks.MockCryptoSetup
  1322. )
  1323. BeforeEach(func() {
  1324. Eventually(areSessionsRunning).Should(BeFalse())
  1325. mconn = newMockConnection()
  1326. sessionRunner = NewMockSessionRunner(mockCtrl)
  1327. sessP, err := newClientSession(
  1328. mconn,
  1329. sessionRunner,
  1330. protocol.ConnectionID{8, 7, 6, 5, 4, 3, 2, 1},
  1331. protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
  1332. populateClientConfig(&Config{}, true),
  1333. nil, // tls.Config
  1334. 42, // initial packet number
  1335. &handshake.TransportParameters{},
  1336. protocol.VersionWhatever,
  1337. utils.DefaultLogger,
  1338. protocol.VersionWhatever,
  1339. )
  1340. sess = sessP.(*session)
  1341. Expect(err).ToNot(HaveOccurred())
  1342. packer = NewMockPacker(mockCtrl)
  1343. sess.packer = packer
  1344. cryptoSetup = mocks.NewMockCryptoSetup(mockCtrl)
  1345. sess.cryptoStreamHandler = cryptoSetup
  1346. })
  1347. It("changes the connection ID when receiving the first packet from the server", func() {
  1348. unpacker := NewMockUnpacker(mockCtrl)
  1349. unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any()).DoAndReturn(func(hdr *wire.Header, data []byte) (*unpackedPacket, error) {
  1350. return &unpackedPacket{
  1351. encryptionLevel: protocol.Encryption1RTT,
  1352. hdr: &wire.ExtendedHeader{Header: *hdr},
  1353. data: []byte{0}, // one PADDING frame
  1354. }, nil
  1355. })
  1356. sess.unpacker = unpacker
  1357. go func() {
  1358. defer GinkgoRecover()
  1359. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() }).AnyTimes()
  1360. sess.run()
  1361. }()
  1362. newConnID := protocol.ConnectionID{1, 3, 3, 7, 1, 3, 3, 7}
  1363. packer.EXPECT().ChangeDestConnectionID(newConnID)
  1364. Expect(sess.handlePacketImpl(insertPacketBuffer(&receivedPacket{
  1365. hdr: &wire.Header{
  1366. IsLongHeader: true,
  1367. Type: protocol.PacketTypeHandshake,
  1368. SrcConnectionID: newConnID,
  1369. DestConnectionID: sess.srcConnID,
  1370. Length: 1,
  1371. },
  1372. data: []byte{0},
  1373. }))).To(BeTrue())
  1374. // make sure the go routine returns
  1375. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  1376. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1377. cryptoSetup.EXPECT().Close()
  1378. Expect(sess.Close()).To(Succeed())
  1379. Eventually(sess.Context().Done()).Should(BeClosed())
  1380. })
  1381. Context("handling Retry", func() {
  1382. var validRetryHdr *wire.Header
  1383. BeforeEach(func() {
  1384. validRetryHdr = &wire.Header{
  1385. IsLongHeader: true,
  1386. Type: protocol.PacketTypeRetry,
  1387. SrcConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
  1388. DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
  1389. OrigDestConnectionID: protocol.ConnectionID{8, 7, 6, 5, 4, 3, 2, 1},
  1390. Token: []byte("foobar"),
  1391. }
  1392. })
  1393. getPacket := func(hdr *wire.Header) *receivedPacket {
  1394. buf := &bytes.Buffer{}
  1395. (&wire.ExtendedHeader{Header: *hdr}).Write(buf, sess.version)
  1396. return &receivedPacket{
  1397. hdr: hdr,
  1398. data: buf.Bytes(),
  1399. buffer: getPacketBuffer(),
  1400. }
  1401. }
  1402. It("handles Retry packets", func() {
  1403. cryptoSetup.EXPECT().ChangeConnectionID(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef})
  1404. packer.EXPECT().SetToken([]byte("foobar"))
  1405. packer.EXPECT().ChangeDestConnectionID(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef})
  1406. Expect(sess.handlePacketImpl(getPacket(validRetryHdr))).To(BeTrue())
  1407. })
  1408. It("ignores Retry packets after receiving a regular packet", func() {
  1409. sess.receivedFirstPacket = true
  1410. Expect(sess.handlePacketImpl(getPacket(validRetryHdr))).To(BeFalse())
  1411. })
  1412. It("ignores Retry packets if the server didn't change the connection ID", func() {
  1413. validRetryHdr.SrcConnectionID = sess.destConnID
  1414. Expect(sess.handlePacketImpl(getPacket(validRetryHdr))).To(BeFalse())
  1415. })
  1416. It("ignores Retry packets with the wrong original destination connection ID", func() {
  1417. hdr := &wire.Header{
  1418. IsLongHeader: true,
  1419. Type: protocol.PacketTypeRetry,
  1420. SrcConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
  1421. DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
  1422. OrigDestConnectionID: protocol.ConnectionID{1, 2, 3, 4},
  1423. Token: []byte("foobar"),
  1424. }
  1425. Expect(sess.handlePacketImpl(getPacket(hdr))).To(BeFalse())
  1426. })
  1427. })
  1428. Context("transport parameters", func() {
  1429. It("errors if it can't unmarshal the TransportParameters", func() {
  1430. go func() {
  1431. defer GinkgoRecover()
  1432. cryptoSetup.EXPECT().RunHandshake().Do(func() { <-sess.Context().Done() })
  1433. err := sess.run()
  1434. Expect(err).To(HaveOccurred())
  1435. Expect(err.Error()).To(ContainSubstring("transport parameter"))
  1436. }()
  1437. // streamManager.EXPECT().CloseWithError(gomock.Any())
  1438. sessionRunner.EXPECT().retireConnectionID(gomock.Any())
  1439. packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
  1440. cryptoSetup.EXPECT().Close()
  1441. sess.processTransportParameters([]byte("invalid"))
  1442. Eventually(sess.Context().Done()).Should(BeClosed())
  1443. })
  1444. It("errors if the TransportParameters don't contain the stateless reset token", func() {
  1445. eetp := &handshake.EncryptedExtensionsTransportParameters{
  1446. NegotiatedVersion: sess.version,
  1447. SupportedVersions: []protocol.VersionNumber{sess.version},
  1448. }
  1449. _, err := sess.processTransportParametersForClient(eetp.Marshal())
  1450. Expect(err).To(MatchError("server didn't send stateless_reset_token"))
  1451. })
  1452. It("errors if the TransportParameters contain an original_connection_id, although no Retry was performed", func() {
  1453. eetp := &handshake.EncryptedExtensionsTransportParameters{
  1454. NegotiatedVersion: sess.version,
  1455. SupportedVersions: []protocol.VersionNumber{sess.version},
  1456. Parameters: handshake.TransportParameters{
  1457. OriginalConnectionID: protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad},
  1458. StatelessResetToken: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
  1459. },
  1460. }
  1461. _, err := sess.processTransportParametersForClient(eetp.Marshal())
  1462. Expect(err).To(MatchError("expected original_connection_id to equal (empty), is 0xdecafbad"))
  1463. })
  1464. It("errors if the TransportParameters contain an original_connection_id, although no Retry was performed", func() {
  1465. sess.origDestConnID = protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}
  1466. eetp := &handshake.EncryptedExtensionsTransportParameters{
  1467. NegotiatedVersion: sess.version,
  1468. SupportedVersions: []protocol.VersionNumber{sess.version},
  1469. Parameters: handshake.TransportParameters{
  1470. OriginalConnectionID: protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad},
  1471. StatelessResetToken: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
  1472. },
  1473. }
  1474. _, err := sess.processTransportParametersForClient(eetp.Marshal())
  1475. Expect(err).To(MatchError("expected original_connection_id to equal 0xdeadbeef, is 0xdecafbad"))
  1476. })
  1477. Context("Version Negotiation", func() {
  1478. var params handshake.TransportParameters
  1479. BeforeEach(func() {
  1480. params = handshake.TransportParameters{
  1481. StatelessResetToken: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
  1482. OriginalConnectionID: sess.origDestConnID,
  1483. }
  1484. })
  1485. It("accepts a valid version negotiation", func() {
  1486. sess.initialVersion = 13
  1487. sess.version = 37
  1488. sess.config.Versions = []protocol.VersionNumber{13, 37, 42}
  1489. eetp := &handshake.EncryptedExtensionsTransportParameters{
  1490. NegotiatedVersion: 37,
  1491. SupportedVersions: []protocol.VersionNumber{36, 37, 38},
  1492. Parameters: params,
  1493. }
  1494. _, err := sess.processTransportParametersForClient(eetp.Marshal())
  1495. Expect(err).ToNot(HaveOccurred())
  1496. })
  1497. It("errors if the current version doesn't match negotiated_version", func() {
  1498. sess.initialVersion = 13
  1499. sess.version = 37
  1500. sess.config.Versions = []protocol.VersionNumber{13, 37, 42}
  1501. eetp := &handshake.EncryptedExtensionsTransportParameters{
  1502. NegotiatedVersion: 38,
  1503. SupportedVersions: []protocol.VersionNumber{36, 37, 38},
  1504. Parameters: params,
  1505. }
  1506. _, err := sess.processTransportParametersForClient(eetp.Marshal())
  1507. Expect(err).To(MatchError("VersionNegotiationMismatch: current version doesn't match negotiated_version"))
  1508. })
  1509. It("errors if the current version is not contained in the server's supported versions", func() {
  1510. sess.version = 42
  1511. eetp := &handshake.EncryptedExtensionsTransportParameters{
  1512. NegotiatedVersion: 42,
  1513. SupportedVersions: []protocol.VersionNumber{43, 44},
  1514. Parameters: params,
  1515. }
  1516. _, err := sess.processTransportParametersForClient(eetp.Marshal())
  1517. Expect(err).To(MatchError("VersionNegotiationMismatch: current version not included in the supported versions"))
  1518. })
  1519. It("errors if version negotiation was performed, but would have picked a different version based on the supported version list", func() {
  1520. sess.version = 42
  1521. sess.initialVersion = 41
  1522. sess.config.Versions = []protocol.VersionNumber{43, 42, 41}
  1523. serverSupportedVersions := []protocol.VersionNumber{42, 43}
  1524. // check that version negotiation would have led us to pick version 43
  1525. ver, ok := protocol.ChooseSupportedVersion(sess.config.Versions, serverSupportedVersions)
  1526. Expect(ok).To(BeTrue())
  1527. Expect(ver).To(Equal(protocol.VersionNumber(43)))
  1528. eetp := &handshake.EncryptedExtensionsTransportParameters{
  1529. NegotiatedVersion: 42,
  1530. SupportedVersions: serverSupportedVersions,
  1531. Parameters: params,
  1532. }
  1533. _, err := sess.processTransportParametersForClient(eetp.Marshal())
  1534. Expect(err).To(MatchError("VersionNegotiationMismatch: would have picked a different version"))
  1535. })
  1536. It("doesn't error if it would have picked a different version based on the supported version list, if no version negotiation was performed", func() {
  1537. sess.version = 42
  1538. sess.initialVersion = 42 // version == initialVersion means no version negotiation was performed
  1539. sess.config.Versions = []protocol.VersionNumber{43, 42, 41}
  1540. serverSupportedVersions := []protocol.VersionNumber{42, 43}
  1541. // check that version negotiation would have led us to pick version 43
  1542. ver, ok := protocol.ChooseSupportedVersion(sess.config.Versions, serverSupportedVersions)
  1543. Expect(ok).To(BeTrue())
  1544. Expect(ver).To(Equal(protocol.VersionNumber(43)))
  1545. eetp := &handshake.EncryptedExtensionsTransportParameters{
  1546. NegotiatedVersion: 42,
  1547. SupportedVersions: serverSupportedVersions,
  1548. Parameters: params,
  1549. }
  1550. _, err := sess.processTransportParametersForClient(eetp.Marshal())
  1551. Expect(err).ToNot(HaveOccurred())
  1552. })
  1553. })
  1554. })
  1555. })