1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  *
7  */
8 
9 #include <quic/api/QuicTransportFunctions.h>
10 
11 #include <folly/io/async/test/MockAsyncUDPSocket.h>
12 #include <quic/api/test/Mocks.h>
13 #include <quic/common/test/TestUtils.h>
14 #include <quic/fizz/server/handshake/FizzServerQuicHandshakeContext.h>
15 #include <quic/logging/FileQLogger.h>
16 #include <quic/logging/QLoggerConstants.h>
17 #include <quic/server/state/ServerStateMachine.h>
18 #include <quic/state/test/MockQuicStats.h>
19 #include <quic/state/test/Mocks.h>
20 
21 #include <gtest/gtest.h>
22 
23 using namespace folly;
24 using namespace testing;
25 
26 namespace quic {
27 namespace test {
28 
writeProbingDataToSocketForTest(folly::AsyncUDPSocket & sock,QuicConnectionStateBase & conn,uint8_t probesToSend,const Aead & aead,const PacketNumberCipher & headerCipher,QuicVersion version)29 uint64_t writeProbingDataToSocketForTest(
30     folly::AsyncUDPSocket& sock,
31     QuicConnectionStateBase& conn,
32     uint8_t probesToSend,
33     const Aead& aead,
34     const PacketNumberCipher& headerCipher,
35     QuicVersion version) {
36   FrameScheduler scheduler = std::move(FrameScheduler::Builder(
37                                            conn,
38                                            EncryptionLevel::AppData,
39                                            PacketNumberSpace::AppData,
40                                            "test")
41                                            .streamFrames()
42                                            .cryptoFrames())
43                                  .build();
44   return writeProbingDataToSocket(
45       sock,
46       conn,
47       *conn.clientConnectionId,
48       *conn.serverConnectionId,
49       ShortHeaderBuilder(),
50       EncryptionLevel::AppData,
51       PacketNumberSpace::AppData,
52       scheduler,
53       probesToSend,
54       aead,
55       headerCipher,
56       version);
57 }
58 
writeCryptoDataProbesToSocketForTest(folly::AsyncUDPSocket & sock,QuicConnectionStateBase & conn,uint8_t probesToSend,const Aead & aead,const PacketNumberCipher & headerCipher,QuicVersion version,LongHeader::Types type=LongHeader::Types::Initial)59 void writeCryptoDataProbesToSocketForTest(
60     folly::AsyncUDPSocket& sock,
61     QuicConnectionStateBase& conn,
62     uint8_t probesToSend,
63     const Aead& aead,
64     const PacketNumberCipher& headerCipher,
65     QuicVersion version,
66     LongHeader::Types type = LongHeader::Types::Initial) {
67   auto encryptionLevel =
68       protectionTypeToEncryptionLevel(longHeaderTypeToProtectionType(type));
69   auto pnSpace = LongHeader::typeToPacketNumberSpace(type);
70   auto scheduler = std::move(FrameScheduler::Builder(
71                                  conn, encryptionLevel, pnSpace, "Crypto")
72                                  .cryptoFrames())
73                        .build();
74   writeProbingDataToSocket(
75       sock,
76       conn,
77       *conn.clientConnectionId,
78       *conn.serverConnectionId,
79       LongHeaderBuilder(type),
80       protectionTypeToEncryptionLevel(longHeaderTypeToProtectionType(type)),
81       LongHeader::typeToPacketNumberSpace(type),
82       scheduler,
83       probesToSend,
84       aead,
85       headerCipher,
86       version);
87 }
88 
buildEmptyPacket(QuicServerConnectionState & conn,PacketNumberSpace pnSpace,bool shortHeader=false)89 auto buildEmptyPacket(
90     QuicServerConnectionState& conn,
91     PacketNumberSpace pnSpace,
92     bool shortHeader = false) {
93   folly::Optional<PacketHeader> header;
94   if (shortHeader) {
95     header = ShortHeader(
96         ProtectionType::KeyPhaseZero,
97         *conn.clientConnectionId,
98         conn.ackStates.appDataAckState.nextPacketNum);
99   } else {
100     if (pnSpace == PacketNumberSpace::Initial) {
101       header = LongHeader(
102           LongHeader::Types::Initial,
103           *conn.clientConnectionId,
104           *conn.serverConnectionId,
105           conn.ackStates.initialAckState.nextPacketNum,
106           *conn.version);
107     } else if (pnSpace == PacketNumberSpace::Handshake) {
108       header = LongHeader(
109           LongHeader::Types::Handshake,
110           *conn.clientConnectionId,
111           *conn.serverConnectionId,
112           conn.ackStates.handshakeAckState.nextPacketNum,
113           *conn.version);
114     } else if (pnSpace == PacketNumberSpace::AppData) {
115       header = LongHeader(
116           LongHeader::Types::ZeroRtt,
117           *conn.clientConnectionId,
118           *conn.serverConnectionId,
119           conn.ackStates.appDataAckState.nextPacketNum,
120           *conn.version);
121     }
122   }
123   RegularQuicPacketBuilder builder(
124       conn.udpSendPacketLen,
125       std::move(*header),
126       getAckState(conn, pnSpace).largestAckedByPeer.value_or(0));
127   builder.encodePacketHeader();
128   DCHECK(builder.canBuildPacket());
129   return std::move(builder).buildPacket();
130 }
131 
getEncodedSize(const RegularQuicPacketBuilder::Packet & packet)132 uint64_t getEncodedSize(const RegularQuicPacketBuilder::Packet& packet) {
133   // calculate size as the plaintext size
134   uint32_t encodedSize = 0;
135   if (packet.header) {
136     encodedSize += packet.header->computeChainDataLength();
137   }
138   if (packet.body) {
139     encodedSize += packet.body->computeChainDataLength();
140   }
141   return encodedSize;
142 }
143 
getEncodedBodySize(const RegularQuicPacketBuilder::Packet & packet)144 uint64_t getEncodedBodySize(const RegularQuicPacketBuilder::Packet& packet) {
145   // calculate size as the plaintext size
146   uint32_t encodedBodySize = 0;
147   if (packet.body) {
148     encodedBodySize += packet.body->computeChainDataLength();
149   }
150   return encodedBodySize;
151 }
152 
153 class QuicTransportFunctionsTest : public Test {
154  public:
SetUp()155   void SetUp() override {
156     aead = test::createNoOpAead();
157     headerCipher = test::createNoOpHeaderCipher();
158     transportInfoCb_ = std::make_unique<NiceMock<MockQuicStats>>();
159   }
160 
createConn()161   std::unique_ptr<QuicServerConnectionState> createConn() {
162     auto conn = std::make_unique<QuicServerConnectionState>(
163         FizzServerQuicHandshakeContext::Builder().build());
164     conn->serverConnectionId = getTestConnectionId();
165     conn->clientConnectionId = getTestConnectionId();
166     conn->version = QuicVersion::MVFST;
167     conn->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal =
168         kDefaultStreamWindowSize;
169     conn->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiRemote =
170         kDefaultStreamWindowSize;
171     conn->flowControlState.peerAdvertisedInitialMaxStreamOffsetUni =
172         kDefaultStreamWindowSize;
173     conn->flowControlState.peerAdvertisedMaxOffset =
174         kDefaultConnectionWindowSize;
175     conn->statsCallback = transportInfoCb_.get();
176     conn->initialWriteCipher = createNoOpAead();
177     conn->initialHeaderCipher = createNoOpHeaderCipher();
178     conn->streamManager->setMaxLocalBidirectionalStreams(
179         kDefaultMaxStreamsBidirectional);
180     conn->streamManager->setMaxLocalUnidirectionalStreams(
181         kDefaultMaxStreamsUnidirectional);
182     return conn;
183   }
184 
getVersion(QuicServerConnectionState & conn)185   QuicVersion getVersion(QuicServerConnectionState& conn) {
186     return conn.version.value_or(*conn.originalVersion);
187   }
188 
189   std::unique_ptr<Aead> aead;
190   std::unique_ptr<PacketNumberCipher> headerCipher;
191   std::unique_ptr<MockQuicStats> transportInfoCb_;
192 };
193 
TEST_F(QuicTransportFunctionsTest,PingPacketGoesToOPList)194 TEST_F(QuicTransportFunctionsTest, PingPacketGoesToOPList) {
195   auto conn = createConn();
196   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
197   packet.packet.frames.push_back(PingFrame());
198   EXPECT_EQ(0, conn->outstandings.packets.size());
199   updateConnection(
200       *conn,
201       folly::none,
202       packet.packet,
203       Clock::now(),
204       50,
205       0,
206       false /* isDSRPacket */);
207   EXPECT_EQ(1, conn->outstandings.packets.size());
208   // But it won't set loss detection alarm
209   EXPECT_FALSE(conn->pendingEvents.setLossDetectionAlarm);
210 }
211 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnection)212 TEST_F(QuicTransportFunctionsTest, TestUpdateConnection) {
213   auto conn = createConn();
214   auto mockCongestionController =
215       std::make_unique<NiceMock<MockCongestionController>>();
216   auto rawCongestionController = mockCongestionController.get();
217   conn->congestionController = std::move(mockCongestionController);
218   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
219   // Builds a fake packet to test with.
220   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
221 
222   auto stream1Id =
223       conn->streamManager->createNextBidirectionalStream().value()->id;
224   auto stream2Id =
225       conn->streamManager->createNextBidirectionalStream().value()->id;
226   auto stream1 = conn->streamManager->findStream(stream1Id);
227   auto stream2 = conn->streamManager->findStream(stream2Id);
228 
229   auto buf = IOBuf::copyBuffer("hey whats up");
230   EXPECT_CALL(*transportInfoCb_, onPacketRetransmission()).Times(2);
231   writeDataToQuicStream(*stream1, buf->clone(), true);
232   writeDataToQuicStream(*stream2, buf->clone(), true);
233 
234   WriteStreamFrame writeStreamFrame1(stream1->id, 0, 5, false);
235   WriteStreamFrame writeStreamFrame2(stream2->id, 0, 12, true);
236   packet.packet.frames.push_back(std::move(writeStreamFrame1));
237   packet.packet.frames.push_back(std::move(writeStreamFrame2));
238 
239   auto currentNextInitialPacketNum =
240       conn->ackStates.initialAckState.nextPacketNum;
241   auto currentNextHandshakePacketNum =
242       conn->ackStates.handshakeAckState.nextPacketNum;
243   auto currentNextAppDataPacketNum =
244       conn->ackStates.appDataAckState.nextPacketNum;
245   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
246   EXPECT_CALL(*rawCongestionController, isAppLimited())
247       .Times(1)
248       .WillOnce(Return(true));
249   updateConnection(
250       *conn,
251       folly::none,
252       packet.packet,
253       TimePoint{},
254       getEncodedSize(packet),
255       getEncodedBodySize(packet),
256       false /* isDSRPacket */);
257 
258   EXPECT_EQ(
259       conn->ackStates.initialAckState.nextPacketNum,
260       currentNextInitialPacketNum);
261   EXPECT_GT(
262       conn->ackStates.handshakeAckState.nextPacketNum,
263       currentNextHandshakePacketNum);
264   EXPECT_EQ(
265       conn->ackStates.appDataAckState.nextPacketNum,
266       currentNextAppDataPacketNum);
267   EXPECT_TRUE(conn->outstandings.packets.back().isAppLimited);
268 
269   EXPECT_EQ(stream1->currentWriteOffset, 5);
270   EXPECT_EQ(stream2->currentWriteOffset, 13);
271   EXPECT_EQ(conn->flowControlState.sumCurWriteOffset, 17);
272 
273   IOBufEqualTo eq;
274 
275   EXPECT_EQ(stream1->retransmissionBuffer.size(), 1);
276   auto& rt1 = *stream1->retransmissionBuffer.at(0);
277   EXPECT_EQ(rt1.offset, 0);
278   EXPECT_TRUE(eq(*IOBuf::copyBuffer("hey w"), *rt1.data.front()));
279 
280   EXPECT_EQ(stream2->retransmissionBuffer.size(), 1);
281   auto& rt2 = *stream2->retransmissionBuffer.at(0);
282   EXPECT_EQ(rt2.offset, 0);
283   EXPECT_TRUE(eq(*buf, *rt2.data.front()));
284   EXPECT_TRUE(rt2.eof);
285 
286   // Testing retransmission
287   stream1->lossBuffer.push_back(std::move(rt1));
288   stream1->retransmissionBuffer.clear();
289   stream2->lossBuffer.push_back(std::move(rt2));
290   stream2->retransmissionBuffer.clear();
291   conn->streamManager->addLoss(stream1->id);
292   conn->streamManager->addLoss(stream2->id);
293 
294   // Write the remainder of the data with retransmission
295   auto packet2 = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
296   WriteStreamFrame writeStreamFrame3(stream1->id, 5, 7, true);
297   WriteStreamFrame writeStreamFrame4(stream1->id, 0, 5, false);
298   WriteStreamFrame writeStreamFrame5(stream2->id, 0, 6, false);
299   packet2.packet.frames.push_back(std::move(writeStreamFrame3));
300   packet2.packet.frames.push_back(std::move(writeStreamFrame4));
301   packet2.packet.frames.push_back(std::move(writeStreamFrame5));
302 
303   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
304   currentNextInitialPacketNum = conn->ackStates.initialAckState.nextPacketNum;
305   currentNextHandshakePacketNum =
306       conn->ackStates.handshakeAckState.nextPacketNum;
307   currentNextAppDataPacketNum = conn->ackStates.appDataAckState.nextPacketNum;
308   EXPECT_CALL(*rawCongestionController, isAppLimited())
309       .Times(1)
310       .WillOnce(Return(false));
311   updateConnection(
312       *conn,
313       folly::none,
314       packet2.packet,
315       TimePoint(),
316       getEncodedSize(packet2),
317       getEncodedBodySize(packet2),
318       false /* isDSRPacket */);
319   EXPECT_EQ(
320       conn->ackStates.initialAckState.nextPacketNum,
321       currentNextInitialPacketNum);
322   EXPECT_GT(
323       conn->ackStates.handshakeAckState.nextPacketNum,
324       currentNextHandshakePacketNum);
325   EXPECT_EQ(
326       conn->ackStates.appDataAckState.nextPacketNum,
327       currentNextAppDataPacketNum);
328   EXPECT_FALSE(conn->outstandings.packets.back().isAppLimited);
329 
330   EXPECT_EQ(stream1->currentWriteOffset, 13);
331   EXPECT_EQ(stream2->currentWriteOffset, 13);
332   EXPECT_EQ(conn->flowControlState.sumCurWriteOffset, 24);
333 
334   EXPECT_EQ(stream1->lossBuffer.size(), 0);
335   EXPECT_EQ(stream1->retransmissionBuffer.size(), 2);
336   auto& rt3 = *stream1->retransmissionBuffer.at(5);
337   EXPECT_TRUE(eq(IOBuf::copyBuffer("hats up"), rt3.data.move()));
338 
339   auto& rt4 = *stream1->retransmissionBuffer.at(0);
340   EXPECT_TRUE(eq(*IOBuf::copyBuffer("hey w"), *rt4.data.front()));
341 
342   // loss buffer should be split into 2. Part in retransmission buffer and
343   // part remains in loss buffer.
344   EXPECT_EQ(stream2->lossBuffer.size(), 1);
345   EXPECT_EQ(stream2->retransmissionBuffer.size(), 1);
346   auto& rt5 = *stream2->retransmissionBuffer.at(0);
347   EXPECT_TRUE(eq(*IOBuf::copyBuffer("hey wh"), *rt5.data.front()));
348   EXPECT_EQ(rt5.offset, 0);
349   EXPECT_EQ(rt5.eof, 0);
350 
351   auto& rt6 = stream2->lossBuffer.front();
352   EXPECT_TRUE(eq(*IOBuf::copyBuffer("ats up"), *rt6.data.front()));
353   EXPECT_EQ(rt6.offset, 6);
354   EXPECT_EQ(rt6.eof, 1);
355 
356   // verify handshake packets stored in QLogger
357   std::shared_ptr<quic::FileQLogger> qLogger =
358       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
359   std::vector<int> indices =
360       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
361   EXPECT_EQ(indices.size(), 2);
362 
363   for (int i = 0; i < 2; ++i) {
364     auto p1 = std::move(qLogger->logs[indices[i]]);
365     auto event = dynamic_cast<QLogPacketEvent*>(p1.get());
366     EXPECT_EQ(event->packetType, toQlogString(LongHeader::Types::Handshake));
367     EXPECT_EQ(event->packetSize, getEncodedSize(packet));
368     EXPECT_EQ(event->eventType, QLogEventType::PacketSent);
369 
370     if (i == 0) {
371       EXPECT_EQ(event->frames.size(), 2);
372       auto frame = static_cast<StreamFrameLog*>(event->frames[0].get());
373       EXPECT_EQ(frame->streamId, stream1->id);
374       EXPECT_EQ(frame->offset, 0);
375       EXPECT_EQ(frame->len, 5);
376       EXPECT_FALSE(frame->fin);
377     } else if (i == 1) {
378       EXPECT_EQ(event->frames.size(), 3);
379       auto frame = static_cast<StreamFrameLog*>(event->frames[0].get());
380       EXPECT_EQ(frame->streamId, stream1->id);
381       EXPECT_EQ(frame->offset, 5);
382       EXPECT_EQ(frame->len, 7);
383       EXPECT_TRUE(frame->fin);
384     }
385   }
386 }
387 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionPacketRetrans)388 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPacketRetrans) {
389   const IOBufEqualTo eq;
390 
391   auto conn = createConn();
392   auto mockCongestionController =
393       std::make_unique<NiceMock<MockCongestionController>>();
394   auto rawCongestionController = mockCongestionController.get();
395   conn->congestionController = std::move(mockCongestionController);
396   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
397 
398   // two streams, both writing "hey whats up"
399   auto stream1Id =
400       conn->streamManager->createNextBidirectionalStream().value()->id;
401   auto stream2Id =
402       conn->streamManager->createNextBidirectionalStream().value()->id;
403   auto stream1 = conn->streamManager->findStream(stream1Id);
404   auto stream2 = conn->streamManager->findStream(stream2Id);
405   auto buf = IOBuf::copyBuffer("hey whats up");
406   writeDataToQuicStream(*stream1, buf->clone(), true /* eof */);
407   writeDataToQuicStream(*stream2, buf->clone(), true /* eof */);
408   WriteStreamFrame writeStreamFrame1(stream1->id, 0, 12, true /* eom */);
409   WriteStreamFrame writeStreamFrame2(stream2->id, 0, 12, true /* eom */);
410   EXPECT_EQ(stream1->currentWriteOffset, 0);
411   EXPECT_EQ(stream2->currentWriteOffset, 0);
412   EXPECT_EQ(conn->flowControlState.sumCurWriteOffset, 0);
413 
414   // add both stream frames into AppData packet1
415   auto packet1 = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
416   packet1.packet.frames.push_back(writeStreamFrame1);
417   packet1.packet.frames.push_back(writeStreamFrame2);
418 
419   // mimic send, call updateConnection
420   auto currentNextInitialPacketNum =
421       conn->ackStates.initialAckState.nextPacketNum;
422   auto currentNextHandshakePacketNum =
423       conn->ackStates.handshakeAckState.nextPacketNum;
424   auto currentNextAppDataPacketNum =
425       conn->ackStates.appDataAckState.nextPacketNum;
426   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
427   EXPECT_CALL(*rawCongestionController, isAppLimited())
428       .Times(1)
429       .WillOnce(Return(true));
430   updateConnection(
431       *conn,
432       folly::none,
433       packet1.packet,
434       TimePoint{},
435       getEncodedSize(packet1),
436       getEncodedBodySize(packet1),
437       false /* isDSRPacket */);
438 
439   // appData packet number should increase
440   EXPECT_EQ(
441       conn->ackStates.initialAckState.nextPacketNum,
442       currentNextInitialPacketNum); // no change
443   EXPECT_EQ(
444       conn->ackStates.handshakeAckState.nextPacketNum,
445       currentNextHandshakePacketNum); // no change
446   EXPECT_GT(
447       conn->ackStates.appDataAckState.nextPacketNum,
448       currentNextAppDataPacketNum); // increased
449   EXPECT_TRUE(conn->outstandings.packets.back().isAppLimited);
450 
451   // offsets should be 13 (len + EOF) and 24 (bytes without EOF)
452   EXPECT_EQ(stream1->currentWriteOffset, 13); // len (12) + EOF (1)
453   EXPECT_EQ(stream2->currentWriteOffset, 13); // len (12) + EOF (1)
454   EXPECT_EQ(conn->flowControlState.sumCurWriteOffset, 24); // sum(len)
455 
456   // verify retransmission buffer and mark stream bytes in packet1 lost
457   {
458     ASSERT_EQ(stream1->retransmissionBuffer.size(), 1);
459     auto& rt = *stream1->retransmissionBuffer.at(0);
460     EXPECT_EQ(rt.offset, 0);
461     EXPECT_TRUE(eq(*buf, *rt.data.front()));
462     EXPECT_TRUE(rt.eof);
463     stream1->lossBuffer.push_back(std::move(rt));
464   }
465   {
466     ASSERT_EQ(stream2->retransmissionBuffer.size(), 1);
467     auto& rt = *stream2->retransmissionBuffer.at(0);
468     EXPECT_EQ(rt.offset, 0);
469     EXPECT_TRUE(eq(*buf, *rt.data.front()));
470     EXPECT_TRUE(rt.eof);
471     stream2->lossBuffer.push_back(std::move(rt));
472   }
473   stream1->retransmissionBuffer.clear();
474   stream2->retransmissionBuffer.clear();
475   conn->streamManager->addLoss(stream1->id);
476   conn->streamManager->addLoss(stream2->id);
477 
478   // retransmit the lost frames in AppData packet2
479   auto packet2 = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
480   packet2.packet.frames.push_back(writeStreamFrame1);
481   packet2.packet.frames.push_back(writeStreamFrame2);
482 
483   // mimic send, call updateConnection
484   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
485   currentNextInitialPacketNum = conn->ackStates.initialAckState.nextPacketNum;
486   currentNextHandshakePacketNum =
487       conn->ackStates.handshakeAckState.nextPacketNum;
488   currentNextAppDataPacketNum = conn->ackStates.appDataAckState.nextPacketNum;
489   EXPECT_CALL(*rawCongestionController, isAppLimited())
490       .Times(1)
491       .WillOnce(Return(false));
492   updateConnection(
493       *conn,
494       folly::none,
495       packet2.packet,
496       TimePoint(),
497       getEncodedSize(packet2),
498       getEncodedBodySize(packet2),
499       false /* isDSRPacket */);
500   EXPECT_EQ(
501       conn->ackStates.initialAckState.nextPacketNum,
502       currentNextInitialPacketNum); // no change
503   EXPECT_EQ(
504       conn->ackStates.handshakeAckState.nextPacketNum,
505       currentNextHandshakePacketNum); // no change
506   EXPECT_GT(
507       conn->ackStates.appDataAckState.nextPacketNum,
508       currentNextAppDataPacketNum); // increased
509   EXPECT_FALSE(conn->outstandings.packets.back().isAppLimited);
510 
511   // since retransmission with no new data, no change in offsets
512   EXPECT_EQ(stream1->currentWriteOffset, 13); // len (12) + EOF (1)
513   EXPECT_EQ(stream2->currentWriteOffset, 13); // len (12) + EOF (1)
514   EXPECT_EQ(conn->flowControlState.sumCurWriteOffset, 24); // sum(len)
515 
516   // check loss state
517   CHECK_EQ(
518       conn->lossState.totalBytesSent,
519       getEncodedSize(packet1) + getEncodedSize(packet2));
520   CHECK_EQ(
521       conn->lossState.totalBodyBytesSent,
522       getEncodedBodySize(packet1) + getEncodedBodySize(packet2));
523   CHECK_EQ(conn->lossState.totalPacketsSent, 2);
524 
525   // totalStreamBytesSent:
526   //   the first packet contained 12 + 12
527   //   the second packet contained 12 + 12
528   //   total = 48
529   EXPECT_EQ(conn->lossState.totalStreamBytesSent, 48); // sum(len)
530 
531   // totalNewStreamBytesSent: just sum(len)
532   EXPECT_EQ(conn->lossState.totalNewStreamBytesSent, 24);
533   EXPECT_EQ(
534       conn->lossState.totalNewStreamBytesSent,
535       conn->flowControlState.sumCurWriteOffset);
536 }
537 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionPacketRetransWithNewData)538 TEST_F(
539     QuicTransportFunctionsTest,
540     TestUpdateConnectionPacketRetransWithNewData) {
541   const IOBufEqualTo eq;
542 
543   auto conn = createConn();
544   auto mockCongestionController =
545       std::make_unique<NiceMock<MockCongestionController>>();
546   auto rawCongestionController = mockCongestionController.get();
547   conn->congestionController = std::move(mockCongestionController);
548   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
549 
550   // three streams, all writing "hey whats up"
551   //
552   // streams1 and 2 EOF after writing buffer, stream3 does not
553   //
554   // frames:
555   //   stream1,frame1 contains the entire string with EOM
556   //   stream2,frame1 contains "hey w", and thus no EOM
557   //   stream3,frame1 contains the entire string, but no EOM given no EOF yet
558   //
559   // we'll write additional data to stream3 later
560   auto stream1Id =
561       conn->streamManager->createNextBidirectionalStream().value()->id;
562   auto stream2Id =
563       conn->streamManager->createNextBidirectionalStream().value()->id;
564   auto stream3Id =
565       conn->streamManager->createNextBidirectionalStream().value()->id;
566   auto stream1 = conn->streamManager->findStream(stream1Id);
567   auto stream2 = conn->streamManager->findStream(stream2Id);
568   auto stream3 = conn->streamManager->findStream(stream3Id);
569   auto buf = IOBuf::copyBuffer("hey whats up");
570   writeDataToQuicStream(*stream1, buf->clone(), true /* eof */);
571   writeDataToQuicStream(*stream2, buf->clone(), true /* eof */);
572   writeDataToQuicStream(*stream3, buf->clone(), false /* eof */);
573   WriteStreamFrame writeStreamFrame1(stream1->id, 0, 12, true /* eom */);
574   WriteStreamFrame writeStreamFrame2(stream2->id, 0, 5, false /* eom */);
575   WriteStreamFrame writeStreamFrame3(stream3->id, 0, 12, false /* eom */);
576   EXPECT_EQ(stream1->currentWriteOffset, 0);
577   EXPECT_EQ(stream2->currentWriteOffset, 0);
578   EXPECT_EQ(stream3->currentWriteOffset, 0);
579   EXPECT_EQ(conn->flowControlState.sumCurWriteOffset, 0);
580 
581   // add all stream frames into AppData packet1
582   auto packet1 = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
583   packet1.packet.frames.push_back(writeStreamFrame1);
584   packet1.packet.frames.push_back(writeStreamFrame2);
585   packet1.packet.frames.push_back(writeStreamFrame3);
586 
587   // mimic send, call updateConnection
588   auto currentNextInitialPacketNum =
589       conn->ackStates.initialAckState.nextPacketNum;
590   auto currentNextHandshakePacketNum =
591       conn->ackStates.handshakeAckState.nextPacketNum;
592   auto currentNextAppDataPacketNum =
593       conn->ackStates.appDataAckState.nextPacketNum;
594   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
595   EXPECT_CALL(*rawCongestionController, isAppLimited())
596       .Times(1)
597       .WillOnce(Return(true));
598   updateConnection(
599       *conn,
600       folly::none,
601       packet1.packet,
602       TimePoint{},
603       getEncodedSize(packet1),
604       getEncodedBodySize(packet1),
605       false /* isDSRPacket */);
606 
607   // appData packet number should increase
608   EXPECT_EQ(
609       conn->ackStates.initialAckState.nextPacketNum,
610       currentNextInitialPacketNum); // no change
611   EXPECT_EQ(
612       conn->ackStates.handshakeAckState.nextPacketNum,
613       currentNextHandshakePacketNum); // no change
614   EXPECT_GT(
615       conn->ackStates.appDataAckState.nextPacketNum,
616       currentNextAppDataPacketNum); // increased
617   EXPECT_TRUE(conn->outstandings.packets.back().isAppLimited);
618 
619   // check offsets
620   EXPECT_EQ(stream1->currentWriteOffset, 13); // len (12) + EOF (1)
621   EXPECT_EQ(stream2->currentWriteOffset, 5); // len (5)
622   EXPECT_EQ(stream3->currentWriteOffset, 12); // len (12)
623   EXPECT_EQ(conn->flowControlState.sumCurWriteOffset, 29); // sum(len)
624 
625   // verify retransmission buffer and mark stream bytes in packet1 lost
626   {
627     ASSERT_EQ(stream1->retransmissionBuffer.size(), 1);
628     auto& rt = *stream1->retransmissionBuffer.at(0);
629     EXPECT_EQ(rt.offset, 0);
630     EXPECT_TRUE(eq(*buf, *rt.data.front()));
631     EXPECT_TRUE(rt.eof);
632     stream1->lossBuffer.push_back(std::move(rt));
633   }
634   {
635     ASSERT_EQ(stream2->retransmissionBuffer.size(), 1);
636     auto& rt = *stream2->retransmissionBuffer.at(0);
637     EXPECT_EQ(rt.offset, 0);
638     EXPECT_TRUE(eq(*IOBuf::copyBuffer("hey w"), *rt.data.front()));
639     EXPECT_FALSE(rt.eof);
640     stream2->lossBuffer.push_back(std::move(rt));
641   }
642   {
643     ASSERT_EQ(stream3->retransmissionBuffer.size(), 1);
644     auto& rt = *stream3->retransmissionBuffer.at(0);
645     EXPECT_EQ(rt.offset, 0);
646     EXPECT_TRUE(eq(*buf, *rt.data.front()));
647     EXPECT_FALSE(rt.eof);
648     stream3->lossBuffer.push_back(std::move(rt));
649   }
650   stream1->retransmissionBuffer.clear();
651   stream2->retransmissionBuffer.clear();
652   stream3->retransmissionBuffer.clear();
653   conn->streamManager->addLoss(stream1->id);
654   conn->streamManager->addLoss(stream2->id);
655   conn->streamManager->addLoss(stream3->id);
656 
657   // add some additional data
658   // write a "?" to stream3 and set eof
659   auto buf2 = IOBuf::copyBuffer("?");
660   writeDataToQuicStream(*stream3, buf->clone(), true /* eof */);
661 
662   // packet2 contains orignally transmitted frames + new data frames
663   auto packet2 = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
664   packet2.packet.frames.push_back(writeStreamFrame1);
665   packet2.packet.frames.push_back(writeStreamFrame2);
666   packet2.packet.frames.push_back(writeStreamFrame3);
667   packet2.packet.frames.push_back(WriteStreamFrame(
668       stream2->id, 5 /* offset */, 7 /* len */, true /* eom */));
669   packet2.packet.frames.push_back(WriteStreamFrame(
670       stream3->id, 12 /* offset */, 1 /* len */, true /* eom */));
671 
672   // mimic send, call updateConnection
673   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
674   currentNextInitialPacketNum = conn->ackStates.initialAckState.nextPacketNum;
675   currentNextHandshakePacketNum =
676       conn->ackStates.handshakeAckState.nextPacketNum;
677   currentNextAppDataPacketNum = conn->ackStates.appDataAckState.nextPacketNum;
678   EXPECT_CALL(*rawCongestionController, isAppLimited())
679       .Times(1)
680       .WillOnce(Return(false));
681   updateConnection(
682       *conn,
683       folly::none,
684       packet2.packet,
685       TimePoint(),
686       getEncodedSize(packet2),
687       getEncodedBodySize(packet2),
688       false /* isDSRPacket */);
689   EXPECT_EQ(
690       conn->ackStates.initialAckState.nextPacketNum,
691       currentNextInitialPacketNum); // no change
692   EXPECT_EQ(
693       conn->ackStates.handshakeAckState.nextPacketNum,
694       currentNextHandshakePacketNum); // no change
695   EXPECT_GT(
696       conn->ackStates.appDataAckState.nextPacketNum,
697       currentNextAppDataPacketNum); // increased
698   EXPECT_FALSE(conn->outstandings.packets.back().isAppLimited);
699 
700   // check offsets
701   EXPECT_EQ(stream1->currentWriteOffset, 13); // len (12) + EOF (1)
702   EXPECT_EQ(stream2->currentWriteOffset, 13); // len (12) + EOF (1)
703   EXPECT_EQ(stream3->currentWriteOffset, 14); // len (13) + EOF (1)
704   EXPECT_EQ(conn->flowControlState.sumCurWriteOffset, 37); // sum(len)
705 
706   // check loss state
707   CHECK_EQ(
708       conn->lossState.totalBytesSent,
709       getEncodedSize(packet1) + getEncodedSize(packet2));
710   CHECK_EQ(
711       conn->lossState.totalBodyBytesSent,
712       getEncodedBodySize(packet1) + getEncodedBodySize(packet2));
713   CHECK_EQ(conn->lossState.totalPacketsSent, 2);
714 
715   // totalStreamBytesSent:
716   //   the first packet contained 12 + 5 + 12 stream bytes
717   //   the second packet contained 12 + 12 + 13 stream bytes
718   //   total = 66
719   EXPECT_EQ(conn->lossState.totalStreamBytesSent, 66); // sum(len)
720 
721   // totalNewStreamBytesSent: just sum(len)
722   EXPECT_EQ(conn->lossState.totalNewStreamBytesSent, 37);
723   EXPECT_EQ(
724       conn->lossState.totalNewStreamBytesSent,
725       conn->flowControlState.sumCurWriteOffset);
726 }
727 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionD6DNotConsumeSendPing)728 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionD6DNotConsumeSendPing) {
729   auto conn = createConn();
730   conn->pendingEvents.sendPing = true; // Simulate application sendPing()
731   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
732   packet.packet.frames.push_back(PingFrame());
733   auto packetNum = packet.packet.header.getPacketSequenceNum();
734   conn->d6d.lastProbe = D6DProbePacket(packetNum, 50);
735   updateConnection(
736       *conn,
737       folly::none,
738       packet.packet,
739       Clock::now(),
740       50,
741       0,
742       false /* isDSRPacket */);
743   EXPECT_EQ(1, conn->outstandings.packets.size());
744   EXPECT_TRUE(conn->outstandings.packets.front().metadata.isD6DProbe);
745   EXPECT_EQ(1, conn->d6d.outstandingProbes);
746   // sendPing should still be active since d6d probe should be "hidden" from
747   // application
748   EXPECT_TRUE(conn->pendingEvents.sendPing);
749 }
750 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionD6DNeedsAppDataPNSpace)751 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionD6DNeedsAppDataPNSpace) {
752   auto conn = createConn();
753   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
754   packet.packet.frames.push_back(PingFrame());
755   auto packetNum = packet.packet.header.getPacketSequenceNum();
756   conn->d6d.lastProbe = D6DProbePacket(packetNum, 50);
757   updateConnection(
758       *conn,
759       folly::none,
760       packet.packet,
761       Clock::now(),
762       50,
763       0,
764       false /* isDSRPacket */);
765   EXPECT_EQ(1, conn->outstandings.packets.size());
766   EXPECT_FALSE(conn->outstandings.packets.front().metadata.isD6DProbe);
767   EXPECT_EQ(0, conn->d6d.outstandingProbes);
768 }
769 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionPacketSorting)770 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPacketSorting) {
771   auto conn = createConn();
772   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
773   conn->ackStates.initialAckState.nextPacketNum = 0;
774   conn->ackStates.handshakeAckState.nextPacketNum = 1;
775   conn->ackStates.appDataAckState.nextPacketNum = 2;
776   auto initialPacket = buildEmptyPacket(*conn, PacketNumberSpace::Initial);
777   auto handshakePacket = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
778   auto appDataPacket = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
779 
780   auto stream = conn->streamManager->createNextBidirectionalStream().value();
781   writeDataToQuicStream(
782       *stream,
783       folly::IOBuf::copyBuffer("The sun is cold and the rain is hard."),
784       true);
785   WriteStreamFrame writeStreamFrame(stream->id, 0, 5, false);
786   initialPacket.packet.frames.push_back(writeStreamFrame);
787   handshakePacket.packet.frames.push_back(writeStreamFrame);
788   appDataPacket.packet.frames.push_back(writeStreamFrame);
789 
790   updateConnection(
791       *conn,
792       folly::none,
793       handshakePacket.packet,
794       TimePoint{},
795       getEncodedSize(handshakePacket),
796       getEncodedBodySize(handshakePacket),
797       false /* isDSRPacket */);
798   updateConnection(
799       *conn,
800       folly::none,
801       initialPacket.packet,
802       TimePoint{},
803       getEncodedSize(initialPacket),
804       getEncodedBodySize(initialPacket),
805       false /* isDSRPacket */);
806   updateConnection(
807       *conn,
808       folly::none,
809       appDataPacket.packet,
810       TimePoint{},
811       getEncodedSize(appDataPacket),
812       getEncodedBodySize(appDataPacket),
813       false /* isDSRPacket */);
814   // verify qLogger added correct logs
815   std::shared_ptr<quic::FileQLogger> qLogger =
816       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
817   std::vector<int> indices =
818       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
819   EXPECT_EQ(indices.size(), 3);
820 
821   auto l1 = std::move(qLogger->logs[indices[0]]);
822   auto l2 = std::move(qLogger->logs[indices[1]]);
823   auto l3 = std::move(qLogger->logs[indices[2]]);
824   auto event1 = dynamic_cast<QLogPacketEvent*>(l1.get());
825   auto event2 = dynamic_cast<QLogPacketEvent*>(l2.get());
826   auto event3 = dynamic_cast<QLogPacketEvent*>(l3.get());
827 
828   EXPECT_EQ(event1->packetType, toQlogString(LongHeader::Types::Handshake));
829   EXPECT_EQ(event2->packetType, toQlogString(LongHeader::Types::Initial));
830   EXPECT_EQ(event3->packetType, toQlogString(LongHeader::Types::ZeroRtt));
831 
832   EXPECT_EQ(3, conn->outstandings.packets.size());
833   auto& firstHeader = conn->outstandings.packets.front().packet.header;
834   auto firstPacketNum = firstHeader.getPacketSequenceNum();
835   EXPECT_EQ(0, firstPacketNum);
836   EXPECT_EQ(1, event1->packetNum);
837 
838   EXPECT_EQ(PacketNumberSpace::Initial, firstHeader.getPacketNumberSpace());
839 
840   auto& lastHeader = conn->outstandings.packets.back().packet.header;
841 
842   auto lastPacketNum = lastHeader.getPacketSequenceNum();
843 
844   EXPECT_EQ(2, lastPacketNum);
845   EXPECT_EQ(2, event3->packetNum);
846 
847   EXPECT_EQ(PacketNumberSpace::AppData, lastHeader.getPacketNumberSpace());
848 }
849 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionFinOnly)850 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionFinOnly) {
851   auto conn = createConn();
852   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
853   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
854   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
855 
856   writeDataToQuicStream(*stream1, nullptr, true);
857   packet.packet.frames.push_back(WriteStreamFrame(stream1->id, 0, 0, true));
858   updateConnection(
859       *conn,
860       folly::none,
861       packet.packet,
862       TimePoint(),
863       getEncodedSize(packet),
864       getEncodedBodySize(packet),
865       false /* isDSRPacket */);
866 
867   // verify QLogger contains correct packet information
868   std::shared_ptr<quic::FileQLogger> qLogger =
869       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
870   std::vector<int> indices =
871       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
872   EXPECT_EQ(indices.size(), 1);
873   auto tmp = std::move(qLogger->logs[indices[0]]);
874 
875   auto event = dynamic_cast<QLogPacketEvent*>(tmp.get());
876   EXPECT_EQ(event->packetType, toQlogString(LongHeader::Types::Handshake));
877   EXPECT_EQ(event->packetSize, getEncodedSize(packet));
878   EXPECT_EQ(event->eventType, QLogEventType::PacketSent);
879 
880   // verify QLogger contains correct frame information
881   EXPECT_EQ(event->frames.size(), 1);
882   auto frame = static_cast<StreamFrameLog*>(event->frames[0].get());
883   EXPECT_EQ(frame->streamId, stream1->id);
884   EXPECT_EQ(frame->offset, 0);
885   EXPECT_EQ(frame->len, 0);
886   EXPECT_TRUE(frame->fin);
887 
888   EXPECT_EQ(stream1->retransmissionBuffer.size(), 1);
889   auto& rt1 = *stream1->retransmissionBuffer.at(0);
890 
891   EXPECT_EQ(stream1->currentWriteOffset, 1);
892   EXPECT_EQ(rt1.offset, 0);
893   EXPECT_EQ(rt1.data.front()->computeChainDataLength(), 0);
894   EXPECT_TRUE(rt1.eof);
895 }
896 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionAllBytesExceptFin)897 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionAllBytesExceptFin) {
898   auto conn = createConn();
899   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
900   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
901 
902   auto stream1 = conn->streamManager->createNextUnidirectionalStream().value();
903 
904   auto buf = IOBuf::copyBuffer("Bluberries are purple");
905   writeDataToQuicStream(*stream1, buf->clone(), true);
906 
907   packet.packet.frames.push_back(
908       WriteStreamFrame(stream1->id, 0, buf->computeChainDataLength(), false));
909   updateConnection(
910       *conn,
911       folly::none,
912       packet.packet,
913       TimePoint(),
914       getEncodedSize(packet),
915       getEncodedBodySize(packet),
916       false /* isDSRPacket */);
917 
918   // verify QLogger contains correct packet information
919   std::shared_ptr<quic::FileQLogger> qLogger =
920       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
921   std::vector<int> indices =
922       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
923   EXPECT_EQ(indices.size(), 1);
924   auto tmp = std::move(qLogger->logs[indices[0]]);
925   auto event = dynamic_cast<QLogPacketEvent*>(tmp.get());
926 
927   EXPECT_EQ(event->packetType, toQlogString(LongHeader::Types::Handshake));
928   EXPECT_EQ(event->packetSize, getEncodedSize(packet));
929   EXPECT_EQ(event->eventType, QLogEventType::PacketSent);
930 
931   // verify QLogger contains correct frame information
932   EXPECT_EQ(event->frames.size(), 1);
933   auto frame = static_cast<StreamFrameLog*>(event->frames[0].get());
934   EXPECT_EQ(frame->streamId, stream1->id);
935   EXPECT_EQ(frame->offset, 0);
936   EXPECT_EQ(frame->len, buf->computeChainDataLength());
937   EXPECT_FALSE(frame->fin);
938 
939   EXPECT_EQ(stream1->currentWriteOffset, buf->computeChainDataLength());
940 
941   EXPECT_EQ(stream1->retransmissionBuffer.size(), 1);
942   auto& rt1 = *stream1->retransmissionBuffer.at(0);
943   EXPECT_EQ(rt1.offset, 0);
944   EXPECT_EQ(
945       rt1.data.front()->computeChainDataLength(),
946       buf->computeChainDataLength());
947   EXPECT_FALSE(rt1.eof);
948 }
949 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionEmptyAckWriteResult)950 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionEmptyAckWriteResult) {
951   auto conn = createConn();
952   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
953   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
954   // None of the largestAckScheduled should be changed. But since
955   // buildEmptyPacket() builds a Handshake packet, we use handshakeAckState to
956   // verify.
957   auto currentPendingLargestAckScheduled =
958       conn->ackStates.handshakeAckState.largestAckScheduled;
959   updateConnection(
960       *conn,
961       folly::none,
962       packet.packet,
963       TimePoint(),
964       getEncodedSize(packet),
965       getEncodedBodySize(packet),
966       false /* isDSRPacket */);
967 
968   // verify QLogger contains correct packet information
969   std::shared_ptr<quic::FileQLogger> qLogger =
970       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
971   std::vector<int> indices =
972       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
973   EXPECT_EQ(indices.size(), 1);
974   auto tmp = std::move(qLogger->logs[indices[0]]);
975   auto event = dynamic_cast<QLogPacketEvent*>(tmp.get());
976   EXPECT_EQ(event->packetType, toQlogString(LongHeader::Types::Handshake));
977   EXPECT_EQ(event->packetSize, getEncodedSize(packet));
978   EXPECT_EQ(event->eventType, QLogEventType::PacketSent);
979 
980   EXPECT_EQ(
981       currentPendingLargestAckScheduled,
982       conn->ackStates.handshakeAckState.largestAckScheduled);
983 }
984 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionPureAckCounter)985 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPureAckCounter) {
986   auto conn = createConn();
987   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
988   auto stream = conn->streamManager->createNextBidirectionalStream().value();
989   writeDataToQuicStream(*stream, nullptr, true);
990   EXPECT_EQ(0, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
991 
992   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
993   auto packetEncodedSize =
994       packet.header ? packet.header->computeChainDataLength() : 0;
995   packetEncodedSize += packet.body ? packet.body->computeChainDataLength() : 0;
996 
997   WriteAckFrame ackFrame;
998   ackFrame.ackBlocks.emplace_back(0, 100);
999   packet.packet.frames.push_back(std::move(ackFrame));
1000   updateConnection(
1001       *conn,
1002       folly::none,
1003       packet.packet,
1004       TimePoint(),
1005       getEncodedSize(packet),
1006       getEncodedBodySize(packet),
1007       false /* isDSRPacket */);
1008 
1009   auto nonHandshake = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
1010   packetEncodedSize =
1011       nonHandshake.header ? nonHandshake.header->computeChainDataLength() : 0;
1012   packetEncodedSize +=
1013       nonHandshake.body ? nonHandshake.body->computeChainDataLength() : 0;
1014   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
1015   writeDataToQuicStream(*stream1, nullptr, true);
1016 
1017   conn->pendingEvents.resets.emplace(
1018       1, RstStreamFrame(1, GenericApplicationErrorCode::UNKNOWN, 0));
1019   auto packet2 = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
1020   RstStreamFrame rstFrame(1, GenericApplicationErrorCode::UNKNOWN, 0);
1021   packet2.packet.frames.push_back(std::move(rstFrame));
1022 
1023   updateConnection(
1024       *conn,
1025       folly::none,
1026       packet2.packet,
1027       TimePoint(),
1028       getEncodedSize(packet),
1029       getEncodedBodySize(packet),
1030       false /* isDSRPacket */);
1031 
1032   //  verify QLogger contains correct packet and frame information
1033   std::shared_ptr<quic::FileQLogger> qLogger =
1034       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
1035   std::vector<int> indices =
1036       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
1037   EXPECT_EQ(indices.size(), 2);
1038   for (int i = 0; i < 2; ++i) {
1039     auto tmp = std::move(qLogger->logs[indices[i]]);
1040     auto event = dynamic_cast<QLogPacketEvent*>(tmp.get());
1041     EXPECT_EQ(event->packetType, toQlogString(LongHeader::Types::Handshake));
1042     EXPECT_EQ(event->packetSize, getEncodedSize(packet));
1043     EXPECT_EQ(event->frames.size(), 1);
1044   }
1045 }
1046 
TEST_F(QuicTransportFunctionsTest,TestPaddingPureAckPacketIsStillPureAck)1047 TEST_F(QuicTransportFunctionsTest, TestPaddingPureAckPacketIsStillPureAck) {
1048   auto conn = createConn();
1049   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
1050   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
1051   auto packetEncodedSize =
1052       packet.header ? packet.header->computeChainDataLength() : 0;
1053   packetEncodedSize += packet.body ? packet.body->computeChainDataLength() : 0;
1054 
1055   WriteAckFrame ackFrame;
1056   ackFrame.ackBlocks.emplace_back(0, 100);
1057   packet.packet.frames.push_back(std::move(ackFrame));
1058   packet.packet.frames.push_back(PaddingFrame());
1059   updateConnection(
1060       *conn,
1061       folly::none,
1062       packet.packet,
1063       TimePoint(),
1064       getEncodedSize(packet),
1065       getEncodedBodySize(packet),
1066       false /* isDSRPacket */);
1067 
1068   // verify QLogger contains correct packet and frames information
1069   std::shared_ptr<quic::FileQLogger> qLogger =
1070       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
1071   std::vector<int> indices =
1072       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
1073   EXPECT_EQ(indices.size(), 1);
1074   auto tmp = std::move(qLogger->logs[indices[0]]);
1075 
1076   auto event = dynamic_cast<QLogPacketEvent*>(tmp.get());
1077   EXPECT_EQ(event->packetType, toQlogString(LongHeader::Types::Handshake));
1078   EXPECT_EQ(event->packetSize, getEncodedSize(packet));
1079   EXPECT_EQ(event->eventType, QLogEventType::PacketSent);
1080   EXPECT_EQ(event->frames.size(), 2);
1081 }
1082 
TEST_F(QuicTransportFunctionsTest,TestImplicitAck)1083 TEST_F(QuicTransportFunctionsTest, TestImplicitAck) {
1084   auto conn = createConn();
1085   auto data = IOBuf::copyBuffer("totally real crypto data");
1086   data->coalesce();
1087 
1088   auto initialStream =
1089       getCryptoStream(*conn->cryptoState, EncryptionLevel::Initial);
1090   ASSERT_TRUE(initialStream->writeBuffer.empty());
1091   ASSERT_TRUE(initialStream->retransmissionBuffer.empty());
1092   ASSERT_TRUE(initialStream->lossBuffer.empty());
1093   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Initial);
1094   packet.packet.frames.push_back(WriteCryptoFrame(0, data->length()));
1095   initialStream->writeBuffer.append(data->clone());
1096   updateConnection(
1097       *conn,
1098       folly::none,
1099       packet.packet,
1100       TimePoint(),
1101       getEncodedSize(packet),
1102       getEncodedBodySize(packet),
1103       false /* isDSRPacket */);
1104   EXPECT_EQ(1, conn->outstandings.packetCount[PacketNumberSpace::Initial]);
1105   EXPECT_EQ(0, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1106   EXPECT_EQ(1, conn->outstandings.packets.size());
1107   EXPECT_EQ(1, initialStream->retransmissionBuffer.size());
1108 
1109   packet = buildEmptyPacket(*conn, PacketNumberSpace::Initial);
1110   packet.packet.frames.push_back(
1111       WriteCryptoFrame(data->length(), data->length()));
1112   packet.packet.frames.push_back(
1113       WriteCryptoFrame(data->length() * 2, data->length()));
1114   initialStream->writeBuffer.append(data->clone());
1115   initialStream->writeBuffer.append(data->clone());
1116   updateConnection(
1117       *conn,
1118       folly::none,
1119       packet.packet,
1120       TimePoint(),
1121       getEncodedSize(packet),
1122       getEncodedBodySize(packet),
1123       false /* isDSRPacket */);
1124   EXPECT_EQ(2, conn->outstandings.packetCount[PacketNumberSpace::Initial]);
1125   EXPECT_EQ(0, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1126   EXPECT_EQ(2, conn->outstandings.packets.size());
1127   EXPECT_EQ(3, initialStream->retransmissionBuffer.size());
1128   EXPECT_TRUE(initialStream->writeBuffer.empty());
1129   EXPECT_TRUE(initialStream->lossBuffer.empty());
1130 
1131   // Fake loss.
1132   Buf firstBuf =
1133       initialStream->retransmissionBuffer.find(0)->second->data.move();
1134   initialStream->retransmissionBuffer.erase(0);
1135   initialStream->lossBuffer.emplace_back(std::move(firstBuf), 0, false);
1136   conn->outstandings.packets.pop_front();
1137   conn->outstandings.packetCount[PacketNumberSpace::Initial]--;
1138 
1139   auto handshakeStream =
1140       getCryptoStream(*conn->cryptoState, EncryptionLevel::Handshake);
1141   ASSERT_TRUE(handshakeStream->writeBuffer.empty());
1142   ASSERT_TRUE(handshakeStream->retransmissionBuffer.empty());
1143   ASSERT_TRUE(handshakeStream->lossBuffer.empty());
1144   packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
1145   packet.packet.frames.push_back(WriteCryptoFrame(0, data->length()));
1146   handshakeStream->writeBuffer.append(data->clone());
1147   updateConnection(
1148       *conn,
1149       folly::none,
1150       packet.packet,
1151       TimePoint(),
1152       getEncodedSize(packet),
1153       getEncodedBodySize(packet),
1154       false /* isDSRPacket */);
1155   EXPECT_EQ(1, conn->outstandings.packetCount[PacketNumberSpace::Initial]);
1156   EXPECT_EQ(1, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1157   EXPECT_EQ(2, conn->outstandings.packets.size());
1158   EXPECT_EQ(1, handshakeStream->retransmissionBuffer.size());
1159 
1160   packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
1161   packet.packet.frames.push_back(
1162       WriteCryptoFrame(data->length(), data->length()));
1163   handshakeStream->writeBuffer.append(data->clone());
1164   updateConnection(
1165       *conn,
1166       folly::none,
1167       packet.packet,
1168       TimePoint(),
1169       getEncodedSize(packet),
1170       getEncodedBodySize(packet),
1171       false /* isDSRPacket */);
1172   EXPECT_EQ(1, conn->outstandings.packetCount[PacketNumberSpace::Initial]);
1173   EXPECT_EQ(2, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1174   EXPECT_EQ(3, conn->outstandings.packets.size());
1175   EXPECT_EQ(2, handshakeStream->retransmissionBuffer.size());
1176   EXPECT_TRUE(handshakeStream->writeBuffer.empty());
1177   EXPECT_TRUE(handshakeStream->lossBuffer.empty());
1178 
1179   // Fake loss.
1180   firstBuf = handshakeStream->retransmissionBuffer.find(0)->second->data.move();
1181   handshakeStream->retransmissionBuffer.erase(0);
1182   handshakeStream->lossBuffer.emplace_back(std::move(firstBuf), 0, false);
1183   auto& op = conn->outstandings.packets.front();
1184   ASSERT_EQ(
1185       op.packet.header.getPacketNumberSpace(), PacketNumberSpace::Handshake);
1186   auto frame = op.packet.frames[0].asWriteCryptoFrame();
1187   EXPECT_EQ(frame->offset, 0);
1188   conn->outstandings.packets.pop_front();
1189   conn->outstandings.packetCount[PacketNumberSpace::Handshake]--;
1190 
1191   implicitAckCryptoStream(*conn, EncryptionLevel::Initial);
1192   EXPECT_EQ(0, conn->outstandings.packetCount[PacketNumberSpace::Initial]);
1193   EXPECT_EQ(1, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1194   EXPECT_EQ(1, conn->outstandings.packets.size());
1195   EXPECT_TRUE(initialStream->retransmissionBuffer.empty());
1196   EXPECT_TRUE(initialStream->writeBuffer.empty());
1197   EXPECT_TRUE(initialStream->lossBuffer.empty());
1198 
1199   implicitAckCryptoStream(*conn, EncryptionLevel::Handshake);
1200   EXPECT_EQ(0, conn->outstandings.packetCount[PacketNumberSpace::Initial]);
1201   EXPECT_EQ(0, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1202   EXPECT_TRUE(conn->outstandings.packets.empty());
1203   EXPECT_TRUE(handshakeStream->retransmissionBuffer.empty());
1204   EXPECT_TRUE(handshakeStream->writeBuffer.empty());
1205   EXPECT_TRUE(handshakeStream->lossBuffer.empty());
1206 }
1207 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionHandshakeCounter)1208 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionHandshakeCounter) {
1209   auto conn = createConn();
1210   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
1211   auto stream = conn->streamManager->createNextBidirectionalStream().value();
1212   writeDataToQuicStream(*stream, nullptr, true);
1213   EXPECT_EQ(0, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1214 
1215   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
1216   auto packetEncodedSize =
1217       packet.header ? packet.header->computeChainDataLength() : 0;
1218   packetEncodedSize += packet.body ? packet.body->computeChainDataLength() : 0;
1219 
1220   packet.packet.frames.push_back(WriteCryptoFrame(0, 0));
1221   updateConnection(
1222       *conn,
1223       folly::none,
1224       packet.packet,
1225       TimePoint(),
1226       getEncodedSize(packet),
1227       getEncodedBodySize(packet),
1228       false /* isDSRPacket */);
1229   EXPECT_EQ(1, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1230 
1231   auto nonHandshake = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
1232   packetEncodedSize =
1233       nonHandshake.header ? nonHandshake.header->computeChainDataLength() : 0;
1234   packetEncodedSize +=
1235       nonHandshake.body ? nonHandshake.body->computeChainDataLength() : 0;
1236   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
1237   writeDataToQuicStream(*stream1, nullptr, true);
1238 
1239   nonHandshake.packet.frames.push_back(
1240       WriteStreamFrame(stream1->id, 0, 0, true));
1241   updateConnection(
1242       *conn,
1243       folly::none,
1244       nonHandshake.packet,
1245       TimePoint(),
1246       getEncodedSize(packet),
1247       getEncodedBodySize(packet),
1248       false /* isDSRPacket */);
1249 
1250   // verify QLogger contains correct packet information
1251   std::shared_ptr<quic::FileQLogger> qLogger =
1252       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
1253   std::vector<int> indices =
1254       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
1255   EXPECT_EQ(indices.size(), 2);
1256   std::vector<std::string> packetTypes = {
1257       std::string(toQlogString(LongHeader::Types::Handshake)),
1258       std::string(toQlogString(LongHeader::Types::ZeroRtt))};
1259   for (int i = 0; i < 2; ++i) {
1260     auto tmp = std::move(qLogger->logs[indices[i]]);
1261     auto event = dynamic_cast<QLogPacketEvent*>(tmp.get());
1262     EXPECT_EQ(event->packetType, packetTypes[i]);
1263     EXPECT_EQ(event->packetSize, packetEncodedSize);
1264     EXPECT_EQ(event->eventType, QLogEventType::PacketSent);
1265 
1266     if (i == 0) {
1267       EXPECT_EQ(event->frames.size(), 1);
1268       auto gotFrame = static_cast<CryptoFrameLog*>(event->frames[0].get());
1269       gotFrame->offset = 0;
1270       gotFrame->len = 0;
1271     } else if (i == 1) {
1272       EXPECT_EQ(event->frames.size(), 1);
1273       auto gotFrame = static_cast<StreamFrameLog*>(event->frames[0].get());
1274       EXPECT_EQ(gotFrame->streamId, stream1->id);
1275       EXPECT_EQ(gotFrame->offset, 0);
1276       EXPECT_EQ(gotFrame->len, 0);
1277       EXPECT_TRUE(gotFrame->fin);
1278       EXPECT_EQ(
1279           1, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1280     }
1281   }
1282 }
1283 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionForOneRttCryptoData)1284 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionForOneRttCryptoData) {
1285   auto conn = createConn();
1286   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
1287   auto stream = conn->streamManager->createNextBidirectionalStream().value();
1288   writeDataToQuicStream(*stream, nullptr, true);
1289   EXPECT_EQ(0, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1290 
1291   // Packet with CryptoFrame in AppData pn space
1292   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData, true);
1293   auto packetEncodedSize =
1294       packet.header ? packet.header->computeChainDataLength() : 0;
1295   packetEncodedSize += packet.body ? packet.body->computeChainDataLength() : 0;
1296 
1297   packet.packet.frames.push_back(WriteCryptoFrame(0, 0));
1298   updateConnection(
1299       *conn,
1300       folly::none,
1301       packet.packet,
1302       TimePoint(),
1303       getEncodedSize(packet),
1304       getEncodedBodySize(packet),
1305       false /* isDSRPacket */);
1306 
1307   EXPECT_EQ(0, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1308   EXPECT_EQ(1, conn->outstandings.packets.size());
1309 
1310   auto nonHandshake = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
1311   packetEncodedSize =
1312       nonHandshake.header ? nonHandshake.header->computeChainDataLength() : 0;
1313   packetEncodedSize +=
1314       nonHandshake.body ? nonHandshake.body->computeChainDataLength() : 0;
1315   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
1316   writeDataToQuicStream(*stream1, nullptr, true);
1317 
1318   nonHandshake.packet.frames.push_back(
1319       WriteStreamFrame(stream1->id, 0, 0, true));
1320   updateConnection(
1321       *conn,
1322       folly::none,
1323       nonHandshake.packet,
1324       TimePoint(),
1325       getEncodedSize(packet),
1326       getEncodedBodySize(packet),
1327       false /* isDSRPacket */);
1328 
1329   // verify QLogger contains correct packet information
1330   std::shared_ptr<quic::FileQLogger> qLogger =
1331       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
1332   std::vector<int> indices =
1333       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
1334   EXPECT_EQ(indices.size(), 2);
1335   std::vector<std::string> packetTypes = {
1336       kShortHeaderPacketType.str(),
1337       std::string(toQlogString(LongHeader::Types::ZeroRtt))};
1338   for (int i = 0; i < 2; ++i) {
1339     auto tmp = std::move(qLogger->logs[indices[i]]);
1340     auto event = dynamic_cast<QLogPacketEvent*>(tmp.get());
1341     EXPECT_EQ(event->packetType, packetTypes[i]);
1342     EXPECT_EQ(event->packetSize, getEncodedSize(packet));
1343     EXPECT_EQ(event->eventType, QLogEventType::PacketSent);
1344 
1345     if (i == 0) {
1346       EXPECT_EQ(event->frames.size(), 1);
1347       auto frame = static_cast<CryptoFrameLog*>(event->frames[0].get());
1348       EXPECT_EQ(frame->offset, 0);
1349       EXPECT_EQ(frame->len, 0);
1350     } else if (i == 1) {
1351       EXPECT_EQ(event->frames.size(), 1);
1352       auto frame = static_cast<StreamFrameLog*>(event->frames[0].get());
1353       EXPECT_EQ(frame->streamId, stream1->id);
1354       EXPECT_EQ(frame->offset, 0);
1355       EXPECT_EQ(frame->len, 0);
1356       EXPECT_TRUE(frame->fin);
1357     }
1358   }
1359 
1360   EXPECT_EQ(0, conn->outstandings.packetCount[PacketNumberSpace::Handshake]);
1361   EXPECT_EQ(2, conn->outstandings.packets.size());
1362 }
1363 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionWithPureAck)1364 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithPureAck) {
1365   auto conn = createConn();
1366   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
1367   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
1368   auto mockPacer = std::make_unique<NiceMock<MockPacer>>();
1369   auto rawPacer = mockPacer.get();
1370   conn->pacer = std::move(mockPacer);
1371   auto mockCongestionController =
1372       std::make_unique<NiceMock<MockCongestionController>>();
1373   auto rawController = mockCongestionController.get();
1374   conn->congestionController = std::move(mockCongestionController);
1375   EXPECT_EQ(0, conn->lossState.totalPacketsSent);
1376   EXPECT_EQ(0, conn->lossState.totalAckElicitingPacketsSent);
1377   EXPECT_EQ(0, conn->outstandings.packets.size());
1378   ASSERT_EQ(0, conn->lossState.totalBytesAcked);
1379   WriteAckFrame ackFrame;
1380   ackFrame.ackBlocks.emplace_back(0, 10);
1381   packet.packet.frames.push_back(std::move(ackFrame));
1382   EXPECT_CALL(*rawController, onPacketSent(_)).Times(0);
1383   EXPECT_CALL(*rawPacer, onPacketSent()).Times(0);
1384   updateConnection(
1385       *conn,
1386       folly::none,
1387       packet.packet,
1388       TimePoint(),
1389       getEncodedSize(packet),
1390       getEncodedBodySize(packet),
1391       false /* isDSRPacket */);
1392   EXPECT_EQ(1, conn->lossState.totalPacketsSent);
1393   EXPECT_EQ(0, conn->lossState.totalAckElicitingPacketsSent);
1394   EXPECT_EQ(0, conn->outstandings.packets.size());
1395   EXPECT_EQ(0, conn->lossState.totalBytesAcked);
1396   std::shared_ptr<quic::FileQLogger> qLogger =
1397       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
1398   // verify QLogger contains correct packet information
1399   std::vector<int> indices =
1400       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
1401   EXPECT_EQ(indices.size(), 1);
1402   auto tmp = std::move(qLogger->logs[indices[0]]);
1403   auto event = dynamic_cast<QLogPacketEvent*>(tmp.get());
1404   EXPECT_EQ(event->packetType, toQlogString(LongHeader::Types::Handshake));
1405   EXPECT_EQ(event->packetSize, getEncodedSize(packet));
1406   EXPECT_EQ(event->eventType, QLogEventType::PacketSent);
1407   // verify QLogger contains correct frame information
1408   EXPECT_EQ(event->frames.size(), 1);
1409   auto frame = static_cast<WriteAckFrameLog*>(event->frames[0].get());
1410   EXPECT_EQ(frame->ackBlocks.size(), 1);
1411 }
1412 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionWithBytesStats)1413 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithBytesStats) {
1414   auto conn = createConn();
1415   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
1416   auto stream = conn->streamManager->createNextBidirectionalStream().value();
1417   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
1418   // This is clearly not 555 bytes. I just need some data inside the packet.
1419   writeDataToQuicStream(
1420       *stream, folly::IOBuf::copyBuffer("Im gonna cut your hair."), true);
1421   WriteStreamFrame writeStreamFrame(stream->id, 0, 5, false);
1422   packet.packet.frames.push_back(std::move(writeStreamFrame));
1423   conn->lossState.totalBytesSent = 13579;
1424   conn->lossState.totalBodyBytesSent = 13000;
1425   conn->lossState.inflightBytes = 16000;
1426   auto currentTime = Clock::now();
1427   conn->lossState.lastAckedTime = currentTime - 123s;
1428   conn->lossState.adjustedLastAckedTime = currentTime - 123s;
1429   conn->lossState.lastAckedPacketSentTime = currentTime - 234s;
1430   conn->lossState.totalBytesSentAtLastAck = 10000;
1431   conn->lossState.totalBytesAckedAtLastAck = 5000;
1432   conn->lossState.totalPacketsSent = 20;
1433   conn->lossState.totalAckElicitingPacketsSent = 15;
1434   updateConnection(
1435       *conn,
1436       folly::none,
1437       packet.packet,
1438       TimePoint(),
1439       555,
1440       500,
1441       false /* isDSRPacket */);
1442   EXPECT_EQ(21, conn->lossState.totalPacketsSent);
1443   EXPECT_EQ(16, conn->lossState.totalAckElicitingPacketsSent);
1444 
1445   // verify QLogger contains correct packet information
1446   std::shared_ptr<quic::FileQLogger> qLogger =
1447       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
1448   std::vector<int> indices =
1449       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
1450   EXPECT_EQ(indices.size(), 1);
1451   auto tmp = std::move(qLogger->logs[indices[0]]);
1452   auto event = dynamic_cast<QLogPacketEvent*>(tmp.get());
1453 
1454   EXPECT_EQ(event->packetType, toQlogString(LongHeader::Types::Handshake));
1455   EXPECT_EQ(event->packetSize, 555);
1456   EXPECT_EQ(event->eventType, QLogEventType::PacketSent);
1457 
1458   EXPECT_EQ(
1459       13579 + 555,
1460       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1461           ->metadata.totalBytesSent);
1462   EXPECT_EQ(
1463       13000 + 500,
1464       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1465           ->metadata.totalBodyBytesSent);
1466   EXPECT_EQ(
1467       16000 + 555,
1468       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1469           ->metadata.inflightBytes);
1470   EXPECT_EQ(
1471       1,
1472       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1473           ->metadata.packetsInflight);
1474   EXPECT_EQ(
1475       555,
1476       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1477           ->metadata.encodedSize);
1478   EXPECT_EQ(
1479       500,
1480       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1481           ->metadata.encodedBodySize);
1482   EXPECT_EQ(
1483       20 + 1,
1484       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1485           ->metadata.totalPacketsSent);
1486   EXPECT_EQ(
1487       15 + 1,
1488       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1489           ->metadata.totalAckElicitingPacketsSent);
1490 
1491   EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1492                   ->lastAckedPacketInfo.has_value());
1493   EXPECT_EQ(
1494       currentTime - 123s,
1495       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1496           ->lastAckedPacketInfo->ackTime);
1497   EXPECT_EQ(
1498       currentTime -= 234s,
1499       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1500           ->lastAckedPacketInfo->sentTime);
1501   EXPECT_EQ(
1502       10000,
1503       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1504           ->lastAckedPacketInfo->totalBytesSent);
1505   EXPECT_EQ(
1506       5000,
1507       getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
1508           ->lastAckedPacketInfo->totalBytesAcked);
1509 }
1510 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionWithCloneResult)1511 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithCloneResult) {
1512   auto conn = createConn();
1513   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
1514   auto mockCongestionController =
1515       std::make_unique<NiceMock<MockCongestionController>>();
1516   auto rawCongestionController = mockCongestionController.get();
1517   conn->congestionController = std::move(mockCongestionController);
1518   ShortHeader shortHeader(
1519       ProtectionType::KeyPhaseZero,
1520       *conn->clientConnectionId,
1521       conn->ackStates.appDataAckState.nextPacketNum);
1522   auto thisMoment = Clock::now();
1523   MockClock::mockNow = [=]() { return thisMoment; };
1524   RegularQuicWritePacket writePacket(std::move(shortHeader));
1525   // Add a dummy frame into the packet so we don't treat it as pureAck
1526   auto maxDataAmt = 1000 + conn->flowControlState.advertisedMaxOffset;
1527   MaxDataFrame maxDataFrame(maxDataAmt);
1528   conn->pendingEvents.connWindowUpdate = true;
1529   writePacket.frames.push_back(std::move(maxDataFrame));
1530   PacketEvent event(PacketNumberSpace::AppData, 1);
1531   conn->outstandings.packetEvents.insert(event);
1532   auto futureMoment = thisMoment + 50ms;
1533   MockClock::mockNow = [=]() { return futureMoment; };
1534   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
1535   updateConnection(
1536       *conn,
1537       event,
1538       std::move(writePacket),
1539       MockClock::now(),
1540       1500,
1541       1400,
1542       false /* isDSRPacket */);
1543   // verify QLogger contains correct packet information
1544   std::shared_ptr<quic::FileQLogger> qLogger =
1545       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
1546 
1547   std::vector<int> indices =
1548       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
1549   EXPECT_EQ(indices.size(), 1);
1550   auto tmp = std::move(qLogger->logs[indices[0]]);
1551   auto qLogEvent = dynamic_cast<QLogPacketEvent*>(tmp.get());
1552   EXPECT_EQ(qLogEvent->packetType, kShortHeaderPacketType.str());
1553   EXPECT_EQ(qLogEvent->packetSize, 1500);
1554   EXPECT_EQ(qLogEvent->eventType, QLogEventType::PacketSent);
1555 
1556   // verify QLogger contains correct frame information
1557   EXPECT_EQ(qLogEvent->frames.size(), 1);
1558   auto frame = static_cast<MaxDataFrameLog*>(qLogEvent->frames[0].get());
1559   EXPECT_EQ(frame->maximumData, maxDataAmt);
1560   EXPECT_EQ(
1561       futureMoment,
1562       getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
1563           ->metadata.time);
1564   EXPECT_EQ(
1565       1500,
1566       getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
1567           ->metadata.encodedSize);
1568   EXPECT_EQ(
1569       1400,
1570       getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
1571           ->metadata.encodedBodySize);
1572   EXPECT_EQ(
1573       event,
1574       *getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
1575            ->associatedEvent);
1576   EXPECT_TRUE(conn->pendingEvents.setLossDetectionAlarm);
1577 }
1578 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionStreamWindowUpdate)1579 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionStreamWindowUpdate) {
1580   auto conn = createConn();
1581   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
1582   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
1583   auto stream = conn->streamManager->createNextBidirectionalStream().value();
1584   MaxStreamDataFrame streamWindowUpdate(stream->id, 0);
1585   conn->streamManager->queueWindowUpdate(stream->id);
1586   packet.packet.frames.push_back(std::move(streamWindowUpdate));
1587   updateConnection(
1588       *conn,
1589       folly::none,
1590       packet.packet,
1591       TimePoint(),
1592       getEncodedSize(packet),
1593       getEncodedBodySize(packet),
1594       false /* isDSRPacket */);
1595 
1596   // verify QLogger contains correct packet information
1597   std::shared_ptr<quic::FileQLogger> qLogger =
1598       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
1599   std::vector<int> indices =
1600       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
1601   EXPECT_EQ(indices.size(), 1);
1602   auto tmp = std::move(qLogger->logs[indices[0]]);
1603   auto event = dynamic_cast<QLogPacketEvent*>(tmp.get());
1604 
1605   EXPECT_EQ(event->packetType, toQlogString(LongHeader::Types::Handshake));
1606   EXPECT_EQ(event->packetSize, getEncodedSize(packet));
1607   EXPECT_EQ(event->eventType, QLogEventType::PacketSent);
1608 
1609   // verify QLogger contains correct frame information
1610   EXPECT_EQ(event->frames.size(), 1);
1611   auto frame = static_cast<MaxStreamDataFrameLog*>(event->frames[0].get());
1612   EXPECT_EQ(frame->streamId, stream->id);
1613   EXPECT_EQ(frame->maximumData, 0);
1614 }
1615 
TEST_F(QuicTransportFunctionsTest,TestUpdateConnectionConnWindowUpdate)1616 TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionConnWindowUpdate) {
1617   auto conn = createConn();
1618   conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
1619   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
1620   conn->pendingEvents.connWindowUpdate = true;
1621   MaxDataFrame connWindowUpdate(conn->flowControlState.advertisedMaxOffset);
1622   packet.packet.frames.push_back(std::move(connWindowUpdate));
1623   updateConnection(
1624       *conn,
1625       folly::none,
1626       packet.packet,
1627       TimePoint(),
1628       getEncodedSize(packet),
1629       getEncodedBodySize(packet),
1630       false /* isDSRPacket */);
1631 
1632   // verify QLogger contains correct packet information
1633   std::shared_ptr<quic::FileQLogger> qLogger =
1634       std::dynamic_pointer_cast<quic::FileQLogger>(conn->qLogger);
1635   std::vector<int> indices =
1636       getQLogEventIndices(QLogEventType::PacketSent, qLogger);
1637   EXPECT_EQ(indices.size(), 1);
1638   auto tmp = std::move(qLogger->logs[indices[0]]);
1639   auto event = dynamic_cast<QLogPacketEvent*>(tmp.get());
1640 
1641   EXPECT_EQ(event->packetType, toQlogString(LongHeader::Types::Handshake));
1642   EXPECT_EQ(event->packetSize, getEncodedSize(packet));
1643   EXPECT_EQ(event->eventType, QLogEventType::PacketSent);
1644   // verify QLogger contains correct frame information
1645   EXPECT_EQ(event->frames.size(), 1);
1646   auto frame = static_cast<MaxDataFrameLog*>(event->frames[0].get());
1647   EXPECT_EQ(frame->maximumData, conn->flowControlState.advertisedMaxOffset);
1648 }
1649 
TEST_F(QuicTransportFunctionsTest,TestStreamDetailsEmptyPacket)1650 TEST_F(QuicTransportFunctionsTest, TestStreamDetailsEmptyPacket) {
1651   auto conn = createConn();
1652   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
1653   updateConnection(
1654       *conn,
1655       folly::none,
1656       packet.packet,
1657       TimePoint(),
1658       getEncodedSize(packet),
1659       getEncodedBodySize(packet),
1660       false /* isDSRPacket */);
1661   // Since there is no ACK eliciting frame in this packet, it is not included as
1662   // an outstanding packet
1663   EXPECT_EQ(0, conn->outstandings.packets.size());
1664 }
1665 
TEST_F(QuicTransportFunctionsTest,TestStreamDetailsControlPacket)1666 TEST_F(QuicTransportFunctionsTest, TestStreamDetailsControlPacket) {
1667   auto conn = createConn();
1668   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
1669   auto stream = conn->streamManager->createNextBidirectionalStream().value();
1670   StreamDataBlockedFrame blockedFrame(stream->id, 1000);
1671   packet.packet.frames.push_back(blockedFrame);
1672   packet.packet.frames.push_back(PingFrame());
1673   updateConnection(
1674       *conn,
1675       folly::none,
1676       packet.packet,
1677       TimePoint(),
1678       getEncodedSize(packet),
1679       getEncodedBodySize(packet),
1680       false /* isDSRPacket */);
1681   // If we have only control frames sent, there should be no stream data in the
1682   // outstanding packet.
1683   ASSERT_EQ(1, conn->outstandings.packets.size());
1684   auto detailsPerStream =
1685       getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)
1686           ->metadata.maybeDetailsPerStream;
1687   EXPECT_EQ(true, detailsPerStream.has_value());
1688   EXPECT_EQ(0, detailsPerStream->getDetails().size());
1689 }
1690 
TEST_F(QuicTransportFunctionsTest,TestStreamDetailsAppDataPacketSingleStream)1691 TEST_F(QuicTransportFunctionsTest, TestStreamDetailsAppDataPacketSingleStream) {
1692   auto conn = createConn();
1693   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
1694   auto stream = conn->streamManager->createNextBidirectionalStream().value();
1695   writeDataToQuicStream(*stream, folly::IOBuf::copyBuffer("abcdefghij"), true);
1696   WriteStreamFrame writeStreamFrame(
1697       stream->id, 0 /* offset */, 10 /* length */, false /* fin */);
1698   packet.packet.frames.push_back(writeStreamFrame);
1699   updateConnection(
1700       *conn,
1701       folly::none,
1702       packet.packet,
1703       TimePoint(),
1704       getEncodedSize(packet),
1705       getEncodedBodySize(packet),
1706       false /* isDSRPacket */);
1707 
1708   ASSERT_EQ(1, conn->outstandings.packets.size());
1709   auto detailsPerStream =
1710       getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)
1711           ->metadata.maybeDetailsPerStream->getDetails();
1712   EXPECT_EQ(1, detailsPerStream.size());
1713   auto streamDetail = detailsPerStream[stream->id];
1714   EXPECT_EQ(false, streamDetail.finObserved);
1715   EXPECT_EQ(10, streamDetail.streamBytesSent);
1716   EXPECT_EQ(10, streamDetail.newStreamBytesSent);
1717   EXPECT_EQ(0, streamDetail.maybeFirstNewStreamByteOffset.value());
1718 }
1719 
TEST_F(QuicTransportFunctionsTest,TestStreamDetailsAppDataPacketSingleStreamMultipleFrames)1720 TEST_F(
1721     QuicTransportFunctionsTest,
1722     TestStreamDetailsAppDataPacketSingleStreamMultipleFrames) {
1723   auto conn = createConn();
1724   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
1725   auto stream = conn->streamManager->createNextBidirectionalStream().value();
1726   writeDataToQuicStream(
1727       *stream, folly::IOBuf::copyBuffer("abcdefghijklmno"), true);
1728   WriteStreamFrame writeStreamFrame1(
1729       stream->id, 0 /* offset */, 10 /* length */, false /* fin */);
1730   WriteStreamFrame writeStreamFrame2(
1731       stream->id, 10 /* offset */, 5 /* length */, true /* fin */);
1732   packet.packet.frames.push_back(writeStreamFrame1);
1733   packet.packet.frames.push_back(writeStreamFrame2);
1734   updateConnection(
1735       *conn,
1736       folly::none,
1737       packet.packet,
1738       TimePoint(),
1739       getEncodedSize(packet),
1740       getEncodedBodySize(packet),
1741       false /* isDSRPacket */);
1742 
1743   ASSERT_EQ(1, conn->outstandings.packets.size());
1744   auto detailsPerStream =
1745       getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)
1746           ->metadata.maybeDetailsPerStream->getDetails();
1747   EXPECT_EQ(1, detailsPerStream.size());
1748   auto streamDetail = detailsPerStream[stream->id];
1749   EXPECT_EQ(true, streamDetail.finObserved);
1750   EXPECT_EQ(15, streamDetail.streamBytesSent);
1751   EXPECT_EQ(15, streamDetail.newStreamBytesSent);
1752   EXPECT_EQ(0, streamDetail.maybeFirstNewStreamByteOffset.value());
1753 }
1754 
TEST_F(QuicTransportFunctionsTest,TestStreamDetailsAppDataPacketSingleStreamRetransmit)1755 TEST_F(
1756     QuicTransportFunctionsTest,
1757     TestStreamDetailsAppDataPacketSingleStreamRetransmit) {
1758   auto conn = createConn();
1759   auto stream = conn->streamManager->createNextBidirectionalStream().value();
1760 
1761   writeDataToQuicStream(*stream, folly::IOBuf::copyBuffer("abcdefghij"), true);
1762   uint64_t frame1Offset = 0;
1763   uint64_t frame1Len = 10;
1764   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
1765   WriteStreamFrame frame1(stream->id, frame1Offset, frame1Len, false /* fin */);
1766   packet.packet.frames.push_back(frame1);
1767   updateConnection(
1768       *conn,
1769       folly::none,
1770       packet.packet,
1771       TimePoint(),
1772       getEncodedSize(packet),
1773       getEncodedBodySize(packet),
1774       false /* isDSRPacket */);
1775 
1776   ASSERT_EQ(1, conn->outstandings.packets.size());
1777 
1778   // The first outstanding packet is the one with new data
1779   auto detailsPerStream =
1780       getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)
1781           ->metadata.maybeDetailsPerStream->getDetails();
1782   EXPECT_EQ(1, detailsPerStream.size());
1783   auto streamDetail = detailsPerStream[stream->id];
1784   EXPECT_EQ(false, streamDetail.finObserved);
1785   EXPECT_EQ(frame1Len, streamDetail.streamBytesSent);
1786   EXPECT_EQ(frame1Len, streamDetail.newStreamBytesSent);
1787   EXPECT_EQ(frame1Offset, streamDetail.maybeFirstNewStreamByteOffset.value());
1788 
1789   // retransmit the same frame1 again.
1790   packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
1791   packet.packet.frames.push_back(frame1);
1792   updateConnection(
1793       *conn,
1794       folly::none,
1795       packet.packet,
1796       TimePoint(),
1797       getEncodedSize(packet),
1798       getEncodedBodySize(packet),
1799       false /* isDSRPacket */);
1800 
1801   ASSERT_EQ(2, conn->outstandings.packets.size());
1802 
1803   // The second outstanding packet is the one with retransmit data
1804   detailsPerStream = getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
1805                          ->metadata.maybeDetailsPerStream->getDetails();
1806   EXPECT_EQ(1, detailsPerStream.size());
1807   streamDetail = detailsPerStream[stream->id];
1808   EXPECT_EQ(false, streamDetail.finObserved);
1809   EXPECT_EQ(frame1Len, streamDetail.streamBytesSent);
1810   EXPECT_EQ(0, streamDetail.newStreamBytesSent);
1811   EXPECT_FALSE(streamDetail.maybeFirstNewStreamByteOffset.has_value());
1812 
1813   // Retransmit frame1 and send new data in frame2.
1814   writeDataToQuicStream(
1815       *stream, folly::IOBuf::copyBuffer("klmnopqrstuvwxy"), true);
1816   uint64_t frame2Offset = 10;
1817   uint64_t frame2Len = 15;
1818   packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
1819   WriteStreamFrame frame2(stream->id, frame2Offset, frame2Len, false /* fin */);
1820   packet.packet.frames.push_back(frame1);
1821   packet.packet.frames.push_back(frame2);
1822   updateConnection(
1823       *conn,
1824       folly::none,
1825       packet.packet,
1826       TimePoint(),
1827       getEncodedSize(packet),
1828       getEncodedBodySize(packet),
1829       false /* isDSRPacket */);
1830 
1831   ASSERT_EQ(3, conn->outstandings.packets.size());
1832 
1833   // The third outstanding packet will have both new and retransmitted data.
1834   detailsPerStream = getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
1835                          ->metadata.maybeDetailsPerStream->getDetails();
1836   EXPECT_EQ(1, detailsPerStream.size());
1837   streamDetail = detailsPerStream[stream->id];
1838   EXPECT_EQ(false, streamDetail.finObserved);
1839   EXPECT_EQ(frame1Len + frame2Len, streamDetail.streamBytesSent);
1840   EXPECT_EQ(frame2Len, streamDetail.newStreamBytesSent);
1841   EXPECT_EQ(frame2Offset, streamDetail.maybeFirstNewStreamByteOffset.value());
1842 
1843   // Retransmit frame1 aand frame2.
1844   packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
1845   packet.packet.frames.push_back(frame1);
1846   packet.packet.frames.push_back(frame2);
1847   updateConnection(
1848       *conn,
1849       folly::none,
1850       packet.packet,
1851       TimePoint(),
1852       getEncodedSize(packet),
1853       getEncodedBodySize(packet),
1854       false /* isDSRPacket */);
1855 
1856   ASSERT_EQ(4, conn->outstandings.packets.size());
1857 
1858   // The forth outstanding packet will have only retransmit data.
1859   detailsPerStream = getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
1860                          ->metadata.maybeDetailsPerStream->getDetails();
1861   EXPECT_EQ(1, detailsPerStream.size());
1862   streamDetail = detailsPerStream[stream->id];
1863   EXPECT_EQ(false, streamDetail.finObserved);
1864   EXPECT_EQ(frame1Len + frame2Len, streamDetail.streamBytesSent);
1865   EXPECT_EQ(0, streamDetail.newStreamBytesSent);
1866   EXPECT_FALSE(streamDetail.maybeFirstNewStreamByteOffset.has_value());
1867 }
1868 
TEST_F(QuicTransportFunctionsTest,TestStreamDetailsAppDataPacketMultipleStreams)1869 TEST_F(
1870     QuicTransportFunctionsTest,
1871     TestStreamDetailsAppDataPacketMultipleStreams) {
1872   auto conn = createConn();
1873   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
1874   auto stream1Id =
1875       conn->streamManager->createNextBidirectionalStream().value()->id;
1876   auto stream2Id =
1877       conn->streamManager->createNextBidirectionalStream().value()->id;
1878   auto stream1 = conn->streamManager->findStream(stream1Id);
1879   auto stream2 = conn->streamManager->findStream(stream2Id);
1880   EXPECT_NE(nullptr, stream1);
1881   EXPECT_NE(nullptr, stream2);
1882 
1883   auto buf = IOBuf::copyBuffer("hey whats up");
1884   writeDataToQuicStream(*stream1, buf->clone(), true);
1885   writeDataToQuicStream(*stream2, buf->clone(), true);
1886 
1887   WriteStreamFrame writeStreamFrame1(stream1->id, 0, 5, false),
1888       writeStreamFrame2(stream2->id, 0, 12, true);
1889   packet.packet.frames.push_back(writeStreamFrame1);
1890   packet.packet.frames.push_back(writeStreamFrame2);
1891 
1892   updateConnection(
1893       *conn,
1894       folly::none,
1895       packet.packet,
1896       TimePoint(),
1897       getEncodedSize(packet),
1898       getEncodedBodySize(packet),
1899       false /* isDSRPacket */);
1900 
1901   ASSERT_EQ(1, conn->outstandings.packets.size());
1902   auto detailsPerStream =
1903       getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)
1904           ->metadata.maybeDetailsPerStream->getDetails();
1905   EXPECT_EQ(2, detailsPerStream.size());
1906   auto stream1Detail = detailsPerStream[stream1Id];
1907   auto stream2Detail = detailsPerStream[stream2Id];
1908 
1909   EXPECT_EQ(false, stream1Detail.finObserved);
1910   EXPECT_EQ(5, stream1Detail.streamBytesSent);
1911   EXPECT_EQ(5, stream1Detail.newStreamBytesSent);
1912   EXPECT_EQ(0, stream1Detail.maybeFirstNewStreamByteOffset.value());
1913 
1914   EXPECT_EQ(true, stream2Detail.finObserved);
1915   EXPECT_EQ(12, stream2Detail.streamBytesSent);
1916   EXPECT_EQ(12, stream2Detail.newStreamBytesSent);
1917   EXPECT_EQ(0, stream2Detail.maybeFirstNewStreamByteOffset.value());
1918 }
1919 
TEST_F(QuicTransportFunctionsTest,WriteQuicDataToSocketWithCC)1920 TEST_F(QuicTransportFunctionsTest, WriteQuicDataToSocketWithCC) {
1921   auto conn = createConn();
1922   conn->udpSendPacketLen = 30;
1923   auto mockCongestionController =
1924       std::make_unique<NiceMock<MockCongestionController>>();
1925   auto rawCongestionController = mockCongestionController.get();
1926   conn->congestionController = std::move(mockCongestionController);
1927 
1928   EventBase evb;
1929   auto socket =
1930       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
1931   auto rawSocket = socket.get();
1932 
1933   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
1934   auto buf =
1935       IOBuf::copyBuffer("0123456789012012345678901201234567890120123456789012");
1936   writeDataToQuicStream(*stream1, buf->clone(), true);
1937 
1938   uint64_t writableBytes = 30;
1939   EXPECT_CALL(*rawCongestionController, getWritableBytes())
1940       .WillRepeatedly(
1941           InvokeWithoutArgs([&writableBytes]() { return writableBytes; }));
1942   EXPECT_CALL(*rawSocket, write(_, _))
1943       .WillRepeatedly(Invoke([&](const SocketAddress&,
1944                                  const std::unique_ptr<folly::IOBuf>& iobuf) {
1945         EXPECT_LE(iobuf->computeChainDataLength(), 30);
1946         writableBytes -= iobuf->computeChainDataLength();
1947         return iobuf->computeChainDataLength();
1948       }));
1949   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
1950   EXPECT_CALL(*transportInfoCb_, onWrite(_));
1951   writeQuicDataToSocket(
1952       *rawSocket,
1953       *conn,
1954       *conn->clientConnectionId,
1955       *conn->serverConnectionId,
1956       *aead,
1957       *headerCipher,
1958       getVersion(*conn),
1959       conn->transportSettings.writeConnectionDataPacketsLimit);
1960 }
1961 
TEST_F(QuicTransportFunctionsTest,WriteQuicdataToSocketWithPacer)1962 TEST_F(QuicTransportFunctionsTest, WriteQuicdataToSocketWithPacer) {
1963   auto conn = createConn();
1964   auto mockPacer = std::make_unique<NiceMock<MockPacer>>();
1965   auto rawPacer = mockPacer.get();
1966   conn->pacer = std::move(mockPacer);
1967 
1968   EventBase evb;
1969   auto socket =
1970       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
1971   auto rawSocket = socket.get();
1972 
1973   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
1974   auto buf =
1975       IOBuf::copyBuffer("0123456789012012345678901201234567890120123456789012");
1976   writeDataToQuicStream(*stream1, buf->clone(), true);
1977 
1978   EXPECT_CALL(*rawPacer, onPacketSent()).Times(1);
1979   EXPECT_CALL(*transportInfoCb_, onWrite(_));
1980   writeQuicDataToSocket(
1981       *rawSocket,
1982       *conn,
1983       *conn->clientConnectionId,
1984       *conn->serverConnectionId,
1985       *aead,
1986       *headerCipher,
1987       getVersion(*conn),
1988       conn->transportSettings.writeConnectionDataPacketsLimit);
1989 }
1990 
TEST_F(QuicTransportFunctionsTest,WriteQuicDataToSocketLimitTest)1991 TEST_F(QuicTransportFunctionsTest, WriteQuicDataToSocketLimitTest) {
1992   auto conn = createConn();
1993   auto mockCongestionController =
1994       std::make_unique<NiceMock<MockCongestionController>>();
1995   auto rawCongestionController = mockCongestionController.get();
1996   conn->congestionController = std::move(mockCongestionController);
1997   conn->udpSendPacketLen = aead->getCipherOverhead() + 50;
1998 
1999   EventBase evb;
2000   auto socket =
2001       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2002   auto rawSocket = socket.get();
2003   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
2004   // ~50 bytes
2005   auto buf =
2006       IOBuf::copyBuffer("0123456789012012345678901201234567890120123456789012");
2007   writeDataToQuicStream(*stream1, buf->clone(), false);
2008   uint64_t writableBytes = 30;
2009   EXPECT_CALL(*rawCongestionController, getWritableBytes())
2010       .WillRepeatedly(
2011           InvokeWithoutArgs([&writableBytes]() { return writableBytes; }));
2012 
2013   // Limit to zero
2014   conn->transportSettings.writeConnectionDataPacketsLimit = 0;
2015   EXPECT_CALL(*rawSocket, write(_, _)).Times(0);
2016   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(0);
2017   EXPECT_CALL(*transportInfoCb_, onWrite(_)).Times(0);
2018   auto res = writeQuicDataToSocket(
2019       *rawSocket,
2020       *conn,
2021       *conn->clientConnectionId,
2022       *conn->serverConnectionId,
2023       *aead,
2024       *headerCipher,
2025       getVersion(*conn),
2026       conn->transportSettings.writeConnectionDataPacketsLimit);
2027   EXPECT_EQ(0, res.packetsWritten);
2028   EXPECT_EQ(0, res.probesWritten);
2029 
2030   // Normal limit
2031   conn->pendingEvents.numProbePackets[PacketNumberSpace::Initial] = 0;
2032   conn->pendingEvents.numProbePackets[PacketNumberSpace::Handshake] = 0;
2033   conn->pendingEvents.numProbePackets[PacketNumberSpace::AppData] = 0;
2034   conn->transportSettings.writeConnectionDataPacketsLimit =
2035       kDefaultWriteConnectionDataPacketLimit;
2036   EXPECT_CALL(*rawSocket, write(_, _))
2037       .Times(1)
2038       .WillOnce(Invoke([&](const SocketAddress&,
2039                            const std::unique_ptr<folly::IOBuf>& iobuf) {
2040         writableBytes -= iobuf->computeChainDataLength();
2041         return iobuf->computeChainDataLength();
2042       }));
2043   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
2044   EXPECT_CALL(*transportInfoCb_, onWrite(_)).Times(1);
2045   res = writeQuicDataToSocket(
2046       *rawSocket,
2047       *conn,
2048       *conn->clientConnectionId,
2049       *conn->serverConnectionId,
2050       *aead,
2051       *headerCipher,
2052       getVersion(*conn),
2053       conn->transportSettings.writeConnectionDataPacketsLimit);
2054 
2055   EXPECT_EQ(1, res.packetsWritten);
2056   EXPECT_EQ(0, res.probesWritten);
2057 
2058   // Probing can exceed packet limit. In practice we limit it to
2059   // kPacketToSendForPTO
2060   conn->pendingEvents.numProbePackets[PacketNumberSpace::AppData] =
2061       kDefaultWriteConnectionDataPacketLimit * 2;
2062   writeDataToQuicStream(*stream1, buf->clone(), true);
2063   writableBytes = 10000;
2064   EXPECT_CALL(*rawCongestionController, getWritableBytes())
2065       .WillRepeatedly(
2066           InvokeWithoutArgs([&writableBytes]() { return writableBytes; }));
2067   EXPECT_CALL(*rawSocket, write(_, _))
2068       .Times(kDefaultWriteConnectionDataPacketLimit * 2)
2069       .WillRepeatedly(Invoke([&](const SocketAddress&,
2070                                  const std::unique_ptr<folly::IOBuf>& iobuf) {
2071         return iobuf->computeChainDataLength();
2072       }));
2073   EXPECT_CALL(*rawCongestionController, onPacketSent(_))
2074       .Times(kDefaultWriteConnectionDataPacketLimit * 2);
2075   EXPECT_CALL(*transportInfoCb_, onWrite(_))
2076       .Times(kDefaultWriteConnectionDataPacketLimit * 2);
2077   res = writeQuicDataToSocket(
2078       *rawSocket,
2079       *conn,
2080       *conn->clientConnectionId,
2081       *conn->serverConnectionId,
2082       *aead,
2083       *headerCipher,
2084       getVersion(*conn),
2085       conn->transportSettings.writeConnectionDataPacketsLimit);
2086 
2087   EXPECT_EQ(0, res.packetsWritten);
2088   EXPECT_EQ(kDefaultWriteConnectionDataPacketLimit * 2, res.probesWritten);
2089 }
2090 
TEST_F(QuicTransportFunctionsTest,WriteQuicDataToSocketWhenInFlightBytesAreLimited)2091 TEST_F(
2092     QuicTransportFunctionsTest,
2093     WriteQuicDataToSocketWhenInFlightBytesAreLimited) {
2094   auto conn = createConn();
2095   conn->oneRttWriteCipher = test::createNoOpAead();
2096   auto mockCongestionController =
2097       std::make_unique<NiceMock<MockCongestionController>>();
2098   auto rawCongestionController = mockCongestionController.get();
2099   conn->congestionController = std::move(mockCongestionController);
2100 
2101   EventBase evb;
2102   auto socket =
2103       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2104   auto rawSocket = socket.get();
2105 
2106   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
2107   auto buf =
2108       IOBuf::copyBuffer("0123456789012012345678901201234567890120123456789012");
2109   writeDataToQuicStream(*stream1, buf->clone(), true);
2110 
2111   conn->writableBytesLimit = 100;
2112   uint64_t writableBytes = 5 * *conn->writableBytesLimit;
2113 
2114   EXPECT_CALL(*rawCongestionController, getWritableBytes())
2115       .WillRepeatedly(
2116           InvokeWithoutArgs([&writableBytes]() { return writableBytes; }));
2117   EXPECT_CALL(*rawSocket, write(_, _))
2118       .WillRepeatedly(Invoke([&](const SocketAddress&,
2119                                  const std::unique_ptr<folly::IOBuf>& iobuf) {
2120         EXPECT_LE(
2121             iobuf->computeChainDataLength(),
2122             *conn->writableBytesLimit - conn->lossState.totalBytesSent);
2123         writableBytes -= iobuf->computeChainDataLength();
2124         return iobuf->computeChainDataLength();
2125       }));
2126   EXPECT_NE(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2127   writeQuicDataToSocket(
2128       *rawSocket,
2129       *conn,
2130       *conn->clientConnectionId,
2131       *conn->serverConnectionId,
2132       *aead,
2133       *headerCipher,
2134       getVersion(*conn),
2135       conn->transportSettings.writeConnectionDataPacketsLimit);
2136   EXPECT_EQ(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2137 }
2138 
TEST_F(QuicTransportFunctionsTest,WriteQuicDataToSocketWithNoBytesForHeader)2139 TEST_F(QuicTransportFunctionsTest, WriteQuicDataToSocketWithNoBytesForHeader) {
2140   auto conn = createConn();
2141   auto mockCongestionController =
2142       std::make_unique<NiceMock<MockCongestionController>>();
2143   auto rawCongestionController = mockCongestionController.get();
2144   conn->congestionController = std::move(mockCongestionController);
2145 
2146   EventBase evb;
2147   auto socket =
2148       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2149   auto rawSocket = socket.get();
2150 
2151   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
2152   auto buf = IOBuf::copyBuffer("0123456789012");
2153   writeDataToQuicStream(*stream1, buf->clone(), true);
2154 
2155   EXPECT_CALL(*rawCongestionController, getWritableBytes())
2156       .WillRepeatedly(Return(0));
2157   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(0);
2158   writeQuicDataToSocket(
2159       *rawSocket,
2160       *conn,
2161       *conn->clientConnectionId,
2162       *conn->serverConnectionId,
2163       *aead,
2164       *headerCipher,
2165       getVersion(*conn),
2166       conn->transportSettings.writeConnectionDataPacketsLimit);
2167   // No header space left. Should send nothing.
2168   EXPECT_TRUE(conn->outstandings.packets.empty());
2169 }
2170 
TEST_F(QuicTransportFunctionsTest,WriteQuicDataToSocketRetxBufferSorted)2171 TEST_F(QuicTransportFunctionsTest, WriteQuicDataToSocketRetxBufferSorted) {
2172   EventBase evb;
2173   NiceMock<folly::test::MockAsyncUDPSocket> socket(&evb);
2174   auto conn = createConn();
2175   auto stream = conn->streamManager->createNextBidirectionalStream().value();
2176   auto buf1 = IOBuf::copyBuffer("Whatsapp");
2177   writeDataToQuicStream(*stream, std::move(buf1), false);
2178   writeQuicDataToSocket(
2179       socket,
2180       *conn,
2181       *conn->clientConnectionId,
2182       *conn->serverConnectionId,
2183       *aead,
2184       *headerCipher,
2185       getVersion(*conn),
2186       conn->transportSettings.writeConnectionDataPacketsLimit);
2187   EXPECT_EQ(1, stream->retransmissionBuffer.size());
2188 
2189   auto buf2 = IOBuf::copyBuffer("Google Buzz");
2190   writeDataToQuicStream(*stream, std::move(buf2), false);
2191   writeQuicDataToSocket(
2192       socket,
2193       *conn,
2194       *conn->clientConnectionId,
2195       *conn->serverConnectionId,
2196       *aead,
2197       *headerCipher,
2198       getVersion(*conn),
2199       conn->transportSettings.writeConnectionDataPacketsLimit);
2200   EXPECT_EQ(2, stream->retransmissionBuffer.size());
2201 }
2202 
TEST_F(QuicTransportFunctionsTest,NothingWritten)2203 TEST_F(QuicTransportFunctionsTest, NothingWritten) {
2204   auto conn = createConn();
2205   auto mockCongestionController =
2206       std::make_unique<NiceMock<MockCongestionController>>();
2207   auto rawCongestionController = mockCongestionController.get();
2208   conn->congestionController = std::move(mockCongestionController);
2209 
2210   EventBase evb;
2211   auto socket =
2212       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2213   auto rawSocket = socket.get();
2214 
2215   // 18 isn't enough to write 3 ack blocks, but is enough to write a pure
2216   // header packet, which we shouldn't write
2217   EXPECT_CALL(*rawCongestionController, getWritableBytes())
2218       .WillRepeatedly(Return(18));
2219 
2220   addAckStatesWithCurrentTimestamps(conn->ackStates.initialAckState, 0, 1000);
2221   addAckStatesWithCurrentTimestamps(
2222       conn->ackStates.initialAckState, 1500, 2000);
2223   addAckStatesWithCurrentTimestamps(
2224       conn->ackStates.initialAckState, 2500, 3000);
2225   auto res = writeQuicDataToSocket(
2226       *rawSocket,
2227       *conn,
2228       *conn->clientConnectionId,
2229       *conn->serverConnectionId,
2230       *aead,
2231       *headerCipher,
2232       getVersion(*conn),
2233       conn->transportSettings.writeConnectionDataPacketsLimit);
2234   EXPECT_EQ(0, res.packetsWritten);
2235   EXPECT_EQ(0, res.probesWritten);
2236 }
2237 
getFirstFrameInOutstandingPackets(const std::deque<OutstandingPacket> & outstandingPackets,QuicWriteFrame::Type frameType)2238 const QuicWriteFrame& getFirstFrameInOutstandingPackets(
2239     const std::deque<OutstandingPacket>& outstandingPackets,
2240     QuicWriteFrame::Type frameType) {
2241   for (const auto& packet : outstandingPackets) {
2242     for (const auto& frame : packet.packet.frames) {
2243       if (frame.type() == frameType) {
2244         return frame;
2245       }
2246     }
2247   }
2248   throw std::runtime_error("Frame not present");
2249 }
2250 
TEST_F(QuicTransportFunctionsTest,WriteBlockedFrameWhenBlocked)2251 TEST_F(QuicTransportFunctionsTest, WriteBlockedFrameWhenBlocked) {
2252   auto conn = createConn();
2253   EventBase evb;
2254   auto socket =
2255       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2256   auto rawSocket = socket.get();
2257   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
2258   auto buf = buildRandomInputData(200);
2259   writeDataToQuicStream(*stream1, buf->clone(), true);
2260 
2261   auto originalNextSeq = conn->ackStates.appDataAckState.nextPacketNum;
2262   uint64_t sentBytes = 0;
2263   EXPECT_CALL(*rawSocket, write(_, _))
2264       .WillRepeatedly(Invoke([&](const SocketAddress&,
2265                                  const std::unique_ptr<folly::IOBuf>& iobuf) {
2266         auto len = iobuf->computeChainDataLength();
2267         sentBytes += len;
2268         return len;
2269       }));
2270 
2271   // Artificially Block the stream
2272   stream1->flowControlState.peerAdvertisedMaxOffset = 10;
2273   // writes blocked frame in additionally
2274   EXPECT_CALL(*transportInfoCb_, onWrite(_)).Times(2);
2275   writeQuicDataToSocket(
2276       *rawSocket,
2277       *conn,
2278       *conn->clientConnectionId,
2279       *conn->serverConnectionId,
2280       *aead,
2281       *headerCipher,
2282       getVersion(*conn),
2283       conn->transportSettings.writeConnectionDataPacketsLimit);
2284   EXPECT_LT(sentBytes, 200);
2285 
2286   EXPECT_GT(conn->ackStates.appDataAckState.nextPacketNum, originalNextSeq);
2287   auto blocked = *getFirstFrameInOutstandingPackets(
2288                       conn->outstandings.packets,
2289                       QuicWriteFrame::Type::StreamDataBlockedFrame)
2290                       .asStreamDataBlockedFrame();
2291   EXPECT_EQ(blocked.streamId, stream1->id);
2292 
2293   // Since everything is blocked, we shouldn't write a blocked again, so we
2294   // won't have any new packets to write if we trigger a write.
2295   auto previousPackets = conn->outstandings.packets.size();
2296   EXPECT_CALL(*transportInfoCb_, onWrite(_)).Times(0);
2297   writeQuicDataToSocket(
2298       *rawSocket,
2299       *conn,
2300       *conn->clientConnectionId,
2301       *conn->serverConnectionId,
2302       *aead,
2303       *headerCipher,
2304       getVersion(*conn),
2305       conn->transportSettings.writeConnectionDataPacketsLimit);
2306   EXPECT_EQ(previousPackets, conn->outstandings.packets.size());
2307 }
2308 
TEST_F(QuicTransportFunctionsTest,WriteProbingNewData)2309 TEST_F(QuicTransportFunctionsTest, WriteProbingNewData) {
2310   auto conn = createConn();
2311   // writeProbingDataToSocketForTest writes ShortHeader, thus it writes at
2312   // AppTraffic level
2313   auto currentPacketSeqNum = conn->ackStates.appDataAckState.nextPacketNum;
2314   auto mockCongestionController =
2315       std::make_unique<NiceMock<MockCongestionController>>();
2316   auto rawCongestionController = mockCongestionController.get();
2317   conn->congestionController = std::move(mockCongestionController);
2318   EventBase evb;
2319   auto socket =
2320       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2321   auto rawSocket = socket.get();
2322   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
2323   auto buf = buildRandomInputData(conn->udpSendPacketLen * 2);
2324   writeDataToQuicStream(*stream1, buf->clone(), true /* eof */);
2325 
2326   auto currentStreamWriteOffset = stream1->currentWriteOffset;
2327   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
2328   EXPECT_CALL(*rawSocket, write(_, _))
2329       .WillOnce(Invoke([&](const SocketAddress&,
2330                            const std::unique_ptr<folly::IOBuf>& iobuf) {
2331         auto len = iobuf->computeChainDataLength();
2332         EXPECT_EQ(conn->udpSendPacketLen - aead->getCipherOverhead(), len);
2333         return len;
2334       }));
2335   writeProbingDataToSocketForTest(
2336       *rawSocket, *conn, 1, *aead, *headerCipher, getVersion(*conn));
2337   EXPECT_LT(currentPacketSeqNum, conn->ackStates.appDataAckState.nextPacketNum);
2338   EXPECT_FALSE(conn->outstandings.packets.empty());
2339   EXPECT_EQ(
2340       conn->outstandings.packets.back().packet.header.getPacketSequenceNum(),
2341       currentPacketSeqNum + 1);
2342   EXPECT_TRUE(conn->pendingEvents.setLossDetectionAlarm);
2343   EXPECT_GT(stream1->currentWriteOffset, currentStreamWriteOffset);
2344   EXPECT_FALSE(stream1->retransmissionBuffer.empty());
2345 }
2346 
TEST_F(QuicTransportFunctionsTest,WriteProbingOldData)2347 TEST_F(QuicTransportFunctionsTest, WriteProbingOldData) {
2348   auto conn = createConn();
2349   conn->congestionController.reset();
2350   EventBase evb;
2351   auto socket =
2352       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2353   auto rawSocket = socket.get();
2354   EXPECT_CALL(*rawSocket, write(_, _)).WillRepeatedly(Return(100));
2355   auto capturingAead = std::make_unique<MockAead>();
2356   auto stream = conn->streamManager->createNextBidirectionalStream().value();
2357   auto buf = folly::IOBuf::copyBuffer("Where you wanna go");
2358   writeDataToQuicStream(*stream, buf->clone(), true);
2359 
2360   folly::IOBuf pktBodyCaptured;
2361   EXPECT_CALL(*capturingAead, _inplaceEncrypt(_, _, _))
2362       .WillRepeatedly(Invoke([&](auto& buf, auto, auto) {
2363         if (buf) {
2364           pktBodyCaptured.prependChain(buf->clone());
2365           return buf->clone();
2366         } else {
2367           return folly::IOBuf::create(0);
2368         }
2369       }));
2370   EXPECT_EQ(
2371       1,
2372       writeProbingDataToSocketForTest(
2373           *rawSocket, *conn, 1, *aead, *headerCipher, getVersion(*conn)));
2374   // Now we have no new data, let's probe again, and verify the same old data
2375   // is sent.
2376   folly::IOBuf secondBodyCaptured;
2377   EXPECT_CALL(*capturingAead, _inplaceEncrypt(_, _, _))
2378       .WillRepeatedly(Invoke([&](auto& buf, auto, auto) {
2379         if (buf) {
2380           secondBodyCaptured.prependChain(buf->clone());
2381           return buf->clone();
2382         } else {
2383           return folly::IOBuf::create(0);
2384         }
2385       }));
2386   EXPECT_EQ(
2387       1,
2388       writeProbingDataToSocketForTest(
2389           *rawSocket, *conn, 1, *aead, *headerCipher, getVersion(*conn)));
2390   // Verify two pacekts have the same body
2391   EXPECT_TRUE(folly::IOBufEqualTo()(pktBodyCaptured, secondBodyCaptured));
2392 }
2393 
TEST_F(QuicTransportFunctionsTest,WriteProbingCryptoData)2394 TEST_F(QuicTransportFunctionsTest, WriteProbingCryptoData) {
2395   QuicServerConnectionState conn(
2396       FizzServerQuicHandshakeContext::Builder().build());
2397   conn.serverConnectionId = getTestConnectionId();
2398   conn.clientConnectionId = getTestConnectionId();
2399   // writeCryptoDataProbesToSocketForTest writes Initial LongHeader, thus it
2400   // writes at Initial level.
2401   auto currentPacketSeqNum = conn.ackStates.initialAckState.nextPacketNum;
2402   // Replace real congestionController with MockCongestionController:
2403   auto mockCongestionController =
2404       std::make_unique<NiceMock<MockCongestionController>>();
2405   auto rawCongestionController = mockCongestionController.get();
2406   conn.congestionController = std::move(mockCongestionController);
2407   EventBase evb;
2408   auto socket =
2409       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2410   auto rawSocket = socket.get();
2411   auto cryptoStream = &conn.cryptoState->initialStream;
2412   auto buf = buildRandomInputData(conn.udpSendPacketLen * 2);
2413   writeDataToQuicStream(*cryptoStream, buf->clone());
2414 
2415   auto currentStreamWriteOffset = cryptoStream->currentWriteOffset;
2416   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
2417   EXPECT_CALL(*rawSocket, write(_, _))
2418       .WillOnce(Invoke([&](const SocketAddress&,
2419                            const std::unique_ptr<folly::IOBuf>& iobuf) {
2420         auto len = iobuf->computeChainDataLength();
2421         EXPECT_EQ(conn.udpSendPacketLen - aead->getCipherOverhead(), len);
2422         return len;
2423       }));
2424   writeCryptoDataProbesToSocketForTest(
2425       *rawSocket, conn, 1, *aead, *headerCipher, getVersion(conn));
2426   EXPECT_LT(currentPacketSeqNum, conn.ackStates.initialAckState.nextPacketNum);
2427   EXPECT_FALSE(conn.outstandings.packets.empty());
2428   EXPECT_TRUE(conn.pendingEvents.setLossDetectionAlarm);
2429   EXPECT_GT(cryptoStream->currentWriteOffset, currentStreamWriteOffset);
2430   EXPECT_FALSE(cryptoStream->retransmissionBuffer.empty());
2431 }
2432 
TEST_F(QuicTransportFunctionsTest,ProbingNotFallbackToPingWhenNoQuota)2433 TEST_F(QuicTransportFunctionsTest, ProbingNotFallbackToPingWhenNoQuota) {
2434   auto conn = createConn();
2435   auto mockCongestionController =
2436       std::make_unique<NiceMock<MockCongestionController>>();
2437   auto rawCongestionController = mockCongestionController.get();
2438   conn->congestionController = std::move(mockCongestionController);
2439   EventBase evb;
2440   auto socket =
2441       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2442   auto rawSocket = socket.get();
2443   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(0);
2444   EXPECT_CALL(*rawSocket, write(_, _)).Times(0);
2445   uint8_t probesToSend = 0;
2446   EXPECT_EQ(
2447       0,
2448       writeProbingDataToSocketForTest(
2449           *rawSocket,
2450           *conn,
2451           probesToSend,
2452           *aead,
2453           *headerCipher,
2454           getVersion(*conn)));
2455 }
2456 
TEST_F(QuicTransportFunctionsTest,ProbingFallbackToPing)2457 TEST_F(QuicTransportFunctionsTest, ProbingFallbackToPing) {
2458   auto conn = createConn();
2459   EventBase evb;
2460   auto socket =
2461       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2462   auto rawSocket = socket.get();
2463   EXPECT_CALL(*rawSocket, write(_, _))
2464       .Times(1)
2465       .WillOnce(Invoke([&](const SocketAddress&,
2466                            const std::unique_ptr<folly::IOBuf>& iobuf) {
2467         return iobuf->computeChainDataLength();
2468       }));
2469   uint8_t probesToSend = 1;
2470   EXPECT_EQ(
2471       1,
2472       writeProbingDataToSocketForTest(
2473           *rawSocket,
2474           *conn,
2475           probesToSend,
2476           *aead,
2477           *headerCipher,
2478           getVersion(*conn)));
2479   // Ping is the only non-retransmittable packet that will go into OP list
2480   EXPECT_EQ(1, conn->outstandings.packets.size());
2481 }
2482 
TEST_F(QuicTransportFunctionsTest,TestCryptoWritingIsHandshakeInOutstanding)2483 TEST_F(QuicTransportFunctionsTest, TestCryptoWritingIsHandshakeInOutstanding) {
2484   auto conn = createConn();
2485   auto cryptoStream = &conn->cryptoState->initialStream;
2486   auto buf = buildRandomInputData(200);
2487   writeDataToQuicStream(*cryptoStream, buf->clone());
2488   EventBase evb;
2489   auto socket =
2490       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2491   auto rawSocket = socket.get();
2492   auto res = writeCryptoAndAckDataToSocket(
2493       *rawSocket,
2494       *conn,
2495       *conn->clientConnectionId,
2496       *conn->serverConnectionId,
2497       LongHeader::Types::Initial,
2498       *conn->initialWriteCipher,
2499       *conn->initialHeaderCipher,
2500       getVersion(*conn),
2501       conn->transportSettings.writeConnectionDataPacketsLimit);
2502 
2503   EXPECT_EQ(1, res.packetsWritten);
2504   EXPECT_EQ(0, res.probesWritten);
2505   ASSERT_EQ(1, conn->outstandings.packets.size());
2506   EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Initial)
2507                   ->metadata.isHandshake);
2508 }
2509 
TEST_F(QuicTransportFunctionsTest,NoCryptoProbeWriteIfNoProbeCredit)2510 TEST_F(QuicTransportFunctionsTest, NoCryptoProbeWriteIfNoProbeCredit) {
2511   auto conn = createConn();
2512   auto cryptoStream = &conn->cryptoState->initialStream;
2513   auto buf = buildRandomInputData(200);
2514   writeDataToQuicStream(*cryptoStream, buf->clone());
2515   EventBase evb;
2516   auto socket =
2517       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2518   auto rawSocket = socket.get();
2519   auto res = writeCryptoAndAckDataToSocket(
2520       *rawSocket,
2521       *conn,
2522       *conn->clientConnectionId,
2523       *conn->serverConnectionId,
2524       LongHeader::Types::Initial,
2525       *conn->initialWriteCipher,
2526       *conn->initialHeaderCipher,
2527       getVersion(*conn),
2528       conn->transportSettings.writeConnectionDataPacketsLimit);
2529 
2530   EXPECT_EQ(1, res.packetsWritten);
2531   EXPECT_EQ(0, res.probesWritten);
2532   ASSERT_EQ(1, conn->outstandings.packets.size());
2533   EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Initial)
2534                   ->metadata.isHandshake);
2535   ASSERT_EQ(1, cryptoStream->retransmissionBuffer.size());
2536   ASSERT_TRUE(cryptoStream->writeBuffer.empty());
2537 
2538   conn->pendingEvents.numProbePackets[PacketNumberSpace::Initial] = 0;
2539   conn->pendingEvents.numProbePackets[PacketNumberSpace::Handshake] = 0;
2540   conn->pendingEvents.numProbePackets[PacketNumberSpace::AppData] = 0;
2541   res = writeCryptoAndAckDataToSocket(
2542       *rawSocket,
2543       *conn,
2544       *conn->clientConnectionId,
2545       *conn->serverConnectionId,
2546       LongHeader::Types::Initial,
2547       *conn->initialWriteCipher,
2548       *conn->initialHeaderCipher,
2549       getVersion(*conn),
2550       conn->transportSettings.writeConnectionDataPacketsLimit);
2551 
2552   EXPECT_EQ(0, res.packetsWritten);
2553   EXPECT_EQ(0, res.probesWritten);
2554 }
2555 
TEST_F(QuicTransportFunctionsTest,ResetNumProbePackets)2556 TEST_F(QuicTransportFunctionsTest, ResetNumProbePackets) {
2557   auto conn = createConn();
2558   EventBase evb;
2559   auto socket =
2560       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2561   auto rawSocket = socket.get();
2562 
2563   conn->pendingEvents.numProbePackets[PacketNumberSpace::Initial] = 2;
2564   writeCryptoAndAckDataToSocket(
2565       *rawSocket,
2566       *conn,
2567       *conn->clientConnectionId,
2568       *conn->serverConnectionId,
2569       LongHeader::Types::Initial,
2570       *conn->initialWriteCipher,
2571       *conn->initialHeaderCipher,
2572       getVersion(*conn),
2573       conn->transportSettings.writeConnectionDataPacketsLimit);
2574   EXPECT_FALSE(conn->pendingEvents.anyProbePackets());
2575 
2576   conn->handshakeWriteCipher = createNoOpAead();
2577   conn->handshakeWriteHeaderCipher = createNoOpHeaderCipher();
2578   conn->pendingEvents.numProbePackets[PacketNumberSpace::Handshake] = 2;
2579   writeCryptoAndAckDataToSocket(
2580       *rawSocket,
2581       *conn,
2582       *conn->clientConnectionId,
2583       *conn->serverConnectionId,
2584       LongHeader::Types::Handshake,
2585       *conn->handshakeWriteCipher,
2586       *conn->handshakeWriteHeaderCipher,
2587       getVersion(*conn),
2588       conn->transportSettings.writeConnectionDataPacketsLimit);
2589   EXPECT_FALSE(conn->pendingEvents.anyProbePackets());
2590 
2591   conn->oneRttWriteCipher = createNoOpAead();
2592   conn->oneRttWriteHeaderCipher = createNoOpHeaderCipher();
2593   conn->pendingEvents.numProbePackets[PacketNumberSpace::AppData] = 2;
2594   writeQuicDataToSocket(
2595       *rawSocket,
2596       *conn,
2597       *conn->clientConnectionId,
2598       *conn->serverConnectionId,
2599       *conn->oneRttWriteCipher,
2600       *conn->oneRttWriteHeaderCipher,
2601       getVersion(*conn),
2602       conn->transportSettings.writeConnectionDataPacketsLimit);
2603   EXPECT_FALSE(conn->pendingEvents.anyProbePackets());
2604 }
2605 
TEST_F(QuicTransportFunctionsTest,WritePureAckWhenNoWritableBytes)2606 TEST_F(QuicTransportFunctionsTest, WritePureAckWhenNoWritableBytes) {
2607   auto conn = createConn();
2608   auto mockCongestionController =
2609       std::make_unique<NiceMock<MockCongestionController>>();
2610   auto rawCongestionController = mockCongestionController.get();
2611   conn->congestionController = std::move(mockCongestionController);
2612 
2613   EventBase evb;
2614   auto socket =
2615       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2616   auto rawSocket = socket.get();
2617 
2618   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
2619   auto buf = IOBuf::copyBuffer("0123456789012");
2620   writeDataToQuicStream(*stream1, buf->clone(), true);
2621 
2622   addAckStatesWithCurrentTimestamps(conn->ackStates.appDataAckState, 0, 100);
2623   conn->ackStates.appDataAckState.needsToSendAckImmediately = true;
2624   conn->ackStates.appDataAckState.largestAckScheduled = 50;
2625 
2626   EXPECT_CALL(*rawCongestionController, getWritableBytes())
2627       .WillRepeatedly(Return(0));
2628 
2629   EXPECT_CALL(*rawSocket, write(_, _))
2630       .WillRepeatedly(Invoke([&](const SocketAddress&,
2631                                  const std::unique_ptr<folly::IOBuf>& iobuf) {
2632         EXPECT_LE(iobuf->computeChainDataLength(), 30);
2633         return iobuf->computeChainDataLength();
2634       }));
2635   EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(0);
2636   auto res = writeQuicDataToSocket(
2637       *rawSocket,
2638       *conn,
2639       *conn->clientConnectionId,
2640       *conn->serverConnectionId,
2641       *aead,
2642       *headerCipher,
2643       getVersion(*conn),
2644       conn->transportSettings.writeConnectionDataPacketsLimit);
2645   EXPECT_GT(res.packetsWritten, 0);
2646   EXPECT_EQ(0, conn->outstandings.packets.size());
2647 }
2648 
TEST_F(QuicTransportFunctionsTest,ShouldWriteDataTest)2649 TEST_F(QuicTransportFunctionsTest, ShouldWriteDataTest) {
2650   auto conn = createConn();
2651 
2652   auto mockCongestionController =
2653       std::make_unique<NiceMock<MockCongestionController>>();
2654   auto rawCongestionController = mockCongestionController.get();
2655   EXPECT_CALL(*rawCongestionController, getWritableBytes())
2656       .WillRepeatedly(Return(1500));
2657   conn->congestionController = std::move(mockCongestionController);
2658 
2659   EventBase evb;
2660   auto socket =
2661       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
2662   auto rawSocket = socket.get();
2663 
2664   // Pure acks without an oneRttCipher
2665   CHECK(!conn->oneRttWriteCipher);
2666   conn->ackStates.appDataAckState.needsToSendAckImmediately = true;
2667   addAckStatesWithCurrentTimestamps(conn->ackStates.appDataAckState, 1, 20);
2668   EXPECT_EQ(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2669 
2670   conn->oneRttWriteCipher = test::createNoOpAead();
2671   EXPECT_CALL(*transportInfoCb_, onCwndBlocked()).Times(0);
2672   EXPECT_NE(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2673 
2674   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
2675   auto buf = IOBuf::copyBuffer("0123456789");
2676   writeDataToQuicStream(*stream1, buf->clone(), false);
2677   EXPECT_NE(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2678 
2679   writeQuicDataToSocket(
2680       *rawSocket,
2681       *conn,
2682       *conn->clientConnectionId,
2683       *conn->serverConnectionId,
2684       *aead,
2685       *headerCipher,
2686       getVersion(*conn),
2687       conn->transportSettings.writeConnectionDataPacketsLimit);
2688   EXPECT_EQ(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2689 
2690   // Congestion control
2691   EXPECT_CALL(*rawCongestionController, getWritableBytes())
2692       .WillRepeatedly(Return(0));
2693   EXPECT_CALL(*transportInfoCb_, onCwndBlocked());
2694   writeDataToQuicStream(*stream1, buf->clone(), true);
2695   EXPECT_EQ(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2696 
2697   EXPECT_CALL(*transportInfoCb_, onCwndBlocked());
2698   writeQuicDataToSocket(
2699       *rawSocket,
2700       *conn,
2701       *conn->clientConnectionId,
2702       *conn->serverConnectionId,
2703       *aead,
2704       *headerCipher,
2705       getVersion(*conn),
2706       conn->transportSettings.writeConnectionDataPacketsLimit);
2707   EXPECT_EQ(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2708 }
2709 
TEST_F(QuicTransportFunctionsTest,ShouldWriteDataTestDuringPathValidation)2710 TEST_F(QuicTransportFunctionsTest, ShouldWriteDataTestDuringPathValidation) {
2711   auto conn = createConn();
2712 
2713   // Create the CC.
2714   auto mockCongestionController =
2715       std::make_unique<NiceMock<MockCongestionController>>();
2716   auto rawCongestionController = mockCongestionController.get();
2717   conn->congestionController = std::move(mockCongestionController);
2718   conn->oneRttWriteCipher = test::createNoOpAead();
2719 
2720   // Create an outstandingPathValidation + limiter so this will be applied.
2721   auto pathValidationLimiter = std::make_unique<MockPendingPathRateLimiter>();
2722   MockPendingPathRateLimiter* rawLimiter = pathValidationLimiter.get();
2723   conn->pathValidationLimiter = std::move(pathValidationLimiter);
2724   conn->outstandingPathValidation = PathChallengeFrame(1000);
2725 
2726   // Have stream data queued up during the test so there's something TO write.
2727   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
2728   auto buf = IOBuf::copyBuffer("0123456789");
2729   writeDataToQuicStream(*stream1, buf->clone(), false);
2730 
2731   // Only case that we allow the write; both CC / PathLimiter have
2732   // writablebytes
2733   EXPECT_CALL(*rawCongestionController, getWritableBytes()).WillOnce(Return(1));
2734   EXPECT_CALL(*rawLimiter, currentCredit(_, _)).WillOnce(Return(1));
2735 
2736   EXPECT_CALL(*transportInfoCb_, onCwndBlocked()).Times(0);
2737   EXPECT_NE(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2738 
2739   // CC has writableBytes, but PathLimiter doesn't.
2740   EXPECT_CALL(*rawCongestionController, getWritableBytes()).WillOnce(Return(1));
2741   EXPECT_CALL(*rawLimiter, currentCredit(_, _)).WillOnce(Return(0));
2742 
2743   EXPECT_CALL(*transportInfoCb_, onCwndBlocked());
2744   EXPECT_EQ(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2745 
2746   // PathLimiter has writableBytes, CC doesn't
2747   EXPECT_CALL(*rawCongestionController, getWritableBytes()).WillOnce(Return(0));
2748   EXPECT_CALL(*rawLimiter, currentCredit(_, _)).WillOnce(Return(1));
2749 
2750   EXPECT_CALL(*transportInfoCb_, onCwndBlocked());
2751   EXPECT_EQ(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2752 
2753   // Neither PathLimiter or CC have writablebytes
2754   EXPECT_CALL(*rawCongestionController, getWritableBytes()).WillOnce(Return(0));
2755   EXPECT_CALL(*rawLimiter, currentCredit(_, _)).WillOnce(Return(0));
2756 
2757   EXPECT_CALL(*transportInfoCb_, onCwndBlocked());
2758   EXPECT_EQ(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2759 }
2760 
TEST_F(QuicTransportFunctionsTest,ShouldWriteStreamsNoCipher)2761 TEST_F(QuicTransportFunctionsTest, ShouldWriteStreamsNoCipher) {
2762   auto conn = createConn();
2763   auto mockCongestionController =
2764       std::make_unique<NiceMock<MockCongestionController>>();
2765   auto rawCongestionController = mockCongestionController.get();
2766   EXPECT_CALL(*rawCongestionController, getWritableBytes())
2767       .WillRepeatedly(Return(1500));
2768   conn->congestionController = std::move(mockCongestionController);
2769 
2770   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
2771   auto buf = IOBuf::copyBuffer("0123456789");
2772   writeDataToQuicStream(*stream1, buf->clone(), false);
2773   EXPECT_EQ(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2774 }
2775 
TEST_F(QuicTransportFunctionsTest,ShouldWritePureAcksNoCipher)2776 TEST_F(QuicTransportFunctionsTest, ShouldWritePureAcksNoCipher) {
2777   auto conn = createConn();
2778   auto mockCongestionController =
2779       std::make_unique<NiceMock<MockCongestionController>>();
2780   auto rawCongestionController = mockCongestionController.get();
2781   EXPECT_CALL(*rawCongestionController, getWritableBytes())
2782       .WillRepeatedly(Return(1500));
2783   conn->congestionController = std::move(mockCongestionController);
2784 
2785   conn->ackStates.appDataAckState.needsToSendAckImmediately = true;
2786   addAckStatesWithCurrentTimestamps(conn->ackStates.appDataAckState, 1, 20);
2787   EXPECT_EQ(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2788 }
2789 
TEST_F(QuicTransportFunctionsTest,ShouldWriteDataNoConnFlowControl)2790 TEST_F(QuicTransportFunctionsTest, ShouldWriteDataNoConnFlowControl) {
2791   auto conn = createConn();
2792   conn->oneRttWriteCipher = test::createNoOpAead();
2793   auto mockCongestionController =
2794       std::make_unique<NiceMock<MockCongestionController>>();
2795   auto rawCongestionController = mockCongestionController.get();
2796   EXPECT_CALL(*rawCongestionController, getWritableBytes())
2797       .WillRepeatedly(Return(1500));
2798   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
2799   auto buf = IOBuf::copyBuffer("0123456789");
2800   writeDataToQuicStream(*stream1, buf->clone(), false);
2801   EXPECT_NE(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2802   // Artificially limit the connection flow control.
2803   conn->flowControlState.peerAdvertisedMaxOffset = 0;
2804   EXPECT_EQ(WriteDataReason::NO_WRITE, shouldWriteData(*conn));
2805 }
2806 
TEST_F(QuicTransportFunctionsTest,HasAckDataToWriteCipherAndAckStateMatch)2807 TEST_F(QuicTransportFunctionsTest, HasAckDataToWriteCipherAndAckStateMatch) {
2808   auto conn = createConn();
2809   EXPECT_FALSE(hasAckDataToWrite(*conn));
2810   conn->initialWriteCipher = test::createNoOpAead();
2811   EXPECT_FALSE(hasAckDataToWrite(*conn));
2812   conn->ackStates.appDataAckState.needsToSendAckImmediately = true;
2813   conn->ackStates.appDataAckState.acks.insert(0, 100);
2814   EXPECT_FALSE(hasAckDataToWrite(*conn));
2815   conn->ackStates.initialAckState.needsToSendAckImmediately = true;
2816   conn->ackStates.initialAckState.acks.insert(0, 100);
2817   EXPECT_TRUE(hasAckDataToWrite(*conn));
2818 }
2819 
TEST_F(QuicTransportFunctionsTest,HasAckDataToWriteNoImmediateAcks)2820 TEST_F(QuicTransportFunctionsTest, HasAckDataToWriteNoImmediateAcks) {
2821   auto conn = createConn();
2822   conn->oneRttWriteCipher = test::createNoOpAead();
2823   conn->ackStates.appDataAckState.acks.insert(0, 100);
2824   conn->ackStates.appDataAckState.needsToSendAckImmediately = false;
2825   EXPECT_FALSE(hasAckDataToWrite(*conn));
2826   conn->ackStates.appDataAckState.needsToSendAckImmediately = true;
2827   EXPECT_TRUE(hasAckDataToWrite(*conn));
2828 }
2829 
TEST_F(QuicTransportFunctionsTest,HasAckDataToWriteNoAcksScheduled)2830 TEST_F(QuicTransportFunctionsTest, HasAckDataToWriteNoAcksScheduled) {
2831   auto conn = createConn();
2832   conn->oneRttWriteCipher = test::createNoOpAead();
2833   conn->ackStates.initialAckState.needsToSendAckImmediately = true;
2834   EXPECT_FALSE(hasAckDataToWrite(*conn));
2835 }
2836 
TEST_F(QuicTransportFunctionsTest,HasAckDataToWrite)2837 TEST_F(QuicTransportFunctionsTest, HasAckDataToWrite) {
2838   auto conn = createConn();
2839   conn->oneRttWriteCipher = test::createNoOpAead();
2840   conn->ackStates.initialAckState.needsToSendAckImmediately = true;
2841   conn->ackStates.initialAckState.acks.insert(0);
2842   EXPECT_TRUE(hasAckDataToWrite(*conn));
2843 }
2844 
TEST_F(QuicTransportFunctionsTest,HasAckDataToWriteMismatch)2845 TEST_F(QuicTransportFunctionsTest, HasAckDataToWriteMismatch) {
2846   // When one ack space has needsToSendAckImmediately = true and another has
2847   // hasAckToSchedule = true, but no ack space has both of them to true, we
2848   // should not send.
2849   auto conn = createConn();
2850   EXPECT_FALSE(hasAckDataToWrite(*conn));
2851   conn->ackStates.initialAckState.needsToSendAckImmediately = true;
2852   EXPECT_FALSE(hasAckDataToWrite(*conn));
2853   conn->ackStates.handshakeAckState.acks.insert(0, 10);
2854   conn->handshakeWriteCipher = test::createNoOpAead();
2855   EXPECT_FALSE(hasAckDataToWrite(*conn));
2856 }
2857 
TEST_F(QuicTransportFunctionsTest,HasCryptoDataToWrite)2858 TEST_F(QuicTransportFunctionsTest, HasCryptoDataToWrite) {
2859   auto conn = createConn();
2860   conn->cryptoState->initialStream.lossBuffer.emplace_back(
2861       folly::IOBuf::copyBuffer("Grab your coat and get your hat"), 0, false);
2862   EXPECT_EQ(WriteDataReason::CRYPTO_STREAM, hasNonAckDataToWrite(*conn));
2863   conn->initialWriteCipher.reset();
2864   EXPECT_EQ(WriteDataReason::NO_WRITE, hasNonAckDataToWrite(*conn));
2865 }
2866 
TEST_F(QuicTransportFunctionsTest,HasControlFramesToWrite)2867 TEST_F(QuicTransportFunctionsTest, HasControlFramesToWrite) {
2868   auto conn = createConn();
2869   conn->streamManager->queueBlocked(1, 100);
2870   EXPECT_EQ(WriteDataReason::NO_WRITE, hasNonAckDataToWrite(*conn));
2871 
2872   conn->oneRttWriteCipher = test::createNoOpAead();
2873   EXPECT_EQ(WriteDataReason::BLOCKED, hasNonAckDataToWrite(*conn));
2874 }
2875 
TEST_F(QuicTransportFunctionsTest,FlowControlBlocked)2876 TEST_F(QuicTransportFunctionsTest, FlowControlBlocked) {
2877   auto conn = createConn();
2878   conn->flowControlState.peerAdvertisedMaxOffset = 1000;
2879   conn->flowControlState.sumCurWriteOffset = 1000;
2880   EXPECT_EQ(WriteDataReason::NO_WRITE, hasNonAckDataToWrite(*conn));
2881 }
2882 
TEST_F(QuicTransportFunctionsTest,HasAppDataToWrite)2883 TEST_F(QuicTransportFunctionsTest, HasAppDataToWrite) {
2884   auto conn = createConn();
2885   conn->flowControlState.peerAdvertisedMaxOffset = 1000;
2886   conn->flowControlState.sumCurWriteOffset = 800;
2887   QuicStreamState stream(0, *conn);
2888   writeDataToQuicStream(stream, folly::IOBuf::copyBuffer("I'm a devil"), true);
2889   conn->streamManager->addWritable(stream);
2890   EXPECT_EQ(WriteDataReason::NO_WRITE, hasNonAckDataToWrite(*conn));
2891 
2892   conn->oneRttWriteCipher = test::createNoOpAead();
2893   EXPECT_EQ(WriteDataReason::STREAM, hasNonAckDataToWrite(*conn));
2894 }
2895 
TEST_F(QuicTransportFunctionsTest,HasDatagramsToWrite)2896 TEST_F(QuicTransportFunctionsTest, HasDatagramsToWrite) {
2897   auto conn = createConn();
2898   conn->oneRttWriteCipher = test::createNoOpAead();
2899   EXPECT_EQ(WriteDataReason::NO_WRITE, hasNonAckDataToWrite(*conn));
2900   conn->datagramState.writeBuffer.emplace_back(
2901       folly::IOBuf::copyBuffer("I'm an unreliable Datagram"));
2902   EXPECT_EQ(WriteDataReason::DATAGRAM, hasNonAckDataToWrite(*conn));
2903 }
2904 
TEST_F(QuicTransportFunctionsTest,UpdateConnectionCloneCounterAppData)2905 TEST_F(QuicTransportFunctionsTest, UpdateConnectionCloneCounterAppData) {
2906   auto conn = createConn();
2907   ASSERT_EQ(
2908       0, conn->outstandings.clonedPacketCount[PacketNumberSpace::AppData]);
2909   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
2910   auto connWindowUpdate =
2911       MaxDataFrame(conn->flowControlState.advertisedMaxOffset);
2912   conn->pendingEvents.connWindowUpdate = true;
2913   packet.packet.frames.emplace_back(connWindowUpdate);
2914   PacketEvent packetEvent(PacketNumberSpace::AppData, 100);
2915   conn->outstandings.packetEvents.insert(packetEvent);
2916   updateConnection(
2917       *conn,
2918       packetEvent,
2919       packet.packet,
2920       TimePoint(),
2921       123,
2922       100,
2923       false /* isDSRPacket */);
2924   EXPECT_EQ(
2925       0, conn->outstandings.clonedPacketCount[PacketNumberSpace::Initial]);
2926   EXPECT_EQ(
2927       0, conn->outstandings.clonedPacketCount[PacketNumberSpace::Handshake]);
2928   EXPECT_EQ(
2929       1, conn->outstandings.clonedPacketCount[PacketNumberSpace::AppData]);
2930 }
2931 
TEST_F(QuicTransportFunctionsTest,UpdateConnectionCloneCounterHandshake)2932 TEST_F(QuicTransportFunctionsTest, UpdateConnectionCloneCounterHandshake) {
2933   auto conn = createConn();
2934   ASSERT_EQ(
2935       0, conn->outstandings.clonedPacketCount[PacketNumberSpace::Handshake]);
2936   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
2937   auto connWindowUpdate =
2938       MaxDataFrame(conn->flowControlState.advertisedMaxOffset);
2939   conn->pendingEvents.connWindowUpdate = true;
2940   packet.packet.frames.emplace_back(connWindowUpdate);
2941   PacketEvent packetEvent(PacketNumberSpace::AppData, 100);
2942   conn->outstandings.packetEvents.insert(packetEvent);
2943   updateConnection(
2944       *conn,
2945       packetEvent,
2946       packet.packet,
2947       TimePoint(),
2948       123,
2949       123,
2950       false /* isDSRPacket */);
2951   EXPECT_EQ(
2952       0, conn->outstandings.clonedPacketCount[PacketNumberSpace::Initial]);
2953   EXPECT_EQ(
2954       1, conn->outstandings.clonedPacketCount[PacketNumberSpace::Handshake]);
2955   EXPECT_EQ(
2956       0, conn->outstandings.clonedPacketCount[PacketNumberSpace::AppData]);
2957 }
2958 
TEST_F(QuicTransportFunctionsTest,UpdateConnectionCloneCounterInitial)2959 TEST_F(QuicTransportFunctionsTest, UpdateConnectionCloneCounterInitial) {
2960   auto conn = createConn();
2961   ASSERT_EQ(
2962       0, conn->outstandings.clonedPacketCount[PacketNumberSpace::Initial]);
2963   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Initial);
2964   auto connWindowUpdate =
2965       MaxDataFrame(conn->flowControlState.advertisedMaxOffset);
2966   conn->pendingEvents.connWindowUpdate = true;
2967   packet.packet.frames.emplace_back(connWindowUpdate);
2968   PacketEvent packetEvent(PacketNumberSpace::AppData, 100);
2969   conn->outstandings.packetEvents.insert(packetEvent);
2970   updateConnection(
2971       *conn,
2972       packetEvent,
2973       packet.packet,
2974       TimePoint(),
2975       123,
2976       123,
2977       false /* isDSRPacket */);
2978   EXPECT_EQ(
2979       1, conn->outstandings.clonedPacketCount[PacketNumberSpace::Initial]);
2980   EXPECT_EQ(
2981       0, conn->outstandings.clonedPacketCount[PacketNumberSpace::Handshake]);
2982   EXPECT_EQ(
2983       0, conn->outstandings.clonedPacketCount[PacketNumberSpace::AppData]);
2984 }
2985 
TEST_F(QuicTransportFunctionsTest,ClearBlockedFromPendingEvents)2986 TEST_F(QuicTransportFunctionsTest, ClearBlockedFromPendingEvents) {
2987   auto conn = createConn();
2988   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
2989   auto stream = conn->streamManager->createNextBidirectionalStream().value();
2990   StreamDataBlockedFrame blockedFrame(stream->id, 1000);
2991   packet.packet.frames.push_back(blockedFrame);
2992   conn->streamManager->queueBlocked(stream->id, 1000);
2993   updateConnection(
2994       *conn,
2995       folly::none,
2996       packet.packet,
2997       TimePoint(),
2998       getEncodedSize(packet),
2999       getEncodedBodySize(packet),
3000       false /* isDSRPacket */);
3001   EXPECT_FALSE(conn->streamManager->hasBlocked());
3002   EXPECT_FALSE(conn->outstandings.packets.empty());
3003   EXPECT_EQ(0, conn->outstandings.numClonedPackets());
3004 }
3005 
TEST_F(QuicTransportFunctionsTest,ClonedBlocked)3006 TEST_F(QuicTransportFunctionsTest, ClonedBlocked) {
3007   auto conn = createConn();
3008   PacketEvent packetEvent(
3009       PacketNumberSpace::AppData,
3010       conn->ackStates.appDataAckState.nextPacketNum);
3011   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
3012   auto stream = conn->streamManager->createNextBidirectionalStream().value();
3013   StreamDataBlockedFrame blockedFrame(stream->id, 1000);
3014   packet.packet.frames.emplace_back(blockedFrame);
3015   conn->outstandings.packetEvents.insert(packetEvent);
3016   // This shall not crash
3017   updateConnection(
3018       *conn,
3019       packetEvent,
3020       packet.packet,
3021       TimePoint(),
3022       getEncodedSize(packet),
3023       getEncodedBodySize(packet),
3024       false /* isDSRPacket */);
3025   EXPECT_FALSE(conn->outstandings.packets.empty());
3026   EXPECT_EQ(
3027       1, conn->outstandings.clonedPacketCount[PacketNumberSpace::AppData]);
3028 }
3029 
TEST_F(QuicTransportFunctionsTest,TwoConnWindowUpdateWillCrash)3030 TEST_F(QuicTransportFunctionsTest, TwoConnWindowUpdateWillCrash) {
3031   auto conn = createConn();
3032   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
3033   MaxDataFrame connWindowUpdate(
3034       1000 + conn->flowControlState.advertisedMaxOffset);
3035   packet.packet.frames.emplace_back(connWindowUpdate);
3036   packet.packet.frames.emplace_back(connWindowUpdate);
3037   conn->pendingEvents.connWindowUpdate = true;
3038   EXPECT_DEATH(
3039       updateConnection(
3040           *conn,
3041           folly::none,
3042           packet.packet,
3043           TimePoint(),
3044           getEncodedSize(packet),
3045           getEncodedBodySize(packet),
3046           false /* isDSRPacket */),
3047       ".*Send more than one connection window update.*");
3048 }
3049 
TEST_F(QuicTransportFunctionsTest,WriteStreamFrameIsNotPureAck)3050 TEST_F(QuicTransportFunctionsTest, WriteStreamFrameIsNotPureAck) {
3051   auto conn = createConn();
3052   auto stream = conn->streamManager->createNextBidirectionalStream().value();
3053   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
3054   writeDataToQuicStream(
3055       *stream, folly::IOBuf::copyBuffer("I feel like a million bucks."), true);
3056   WriteStreamFrame writeStreamFrame(stream->id, 0, 5, false);
3057   packet.packet.frames.push_back(std::move(writeStreamFrame));
3058   updateConnection(
3059       *conn,
3060       folly::none,
3061       packet.packet,
3062       TimePoint(),
3063       getEncodedSize(packet),
3064       getEncodedBodySize(packet),
3065       false /* isDSRPacket */);
3066   EXPECT_FALSE(conn->outstandings.packets.empty());
3067 }
3068 
TEST_F(QuicTransportFunctionsTest,ClearRstFromPendingEvents)3069 TEST_F(QuicTransportFunctionsTest, ClearRstFromPendingEvents) {
3070   auto conn = createConn();
3071   auto stream = conn->streamManager->createNextBidirectionalStream().value();
3072   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
3073   RstStreamFrame rstStreamFrame(
3074       stream->id, GenericApplicationErrorCode::UNKNOWN, 0);
3075   packet.packet.frames.push_back(rstStreamFrame);
3076   conn->pendingEvents.resets.emplace(stream->id, rstStreamFrame);
3077   updateConnection(
3078       *conn,
3079       folly::none,
3080       packet.packet,
3081       TimePoint(),
3082       getEncodedSize(packet),
3083       getEncodedBodySize(packet),
3084       false /* isDSRPacket */);
3085   EXPECT_TRUE(conn->pendingEvents.resets.empty());
3086   EXPECT_FALSE(conn->outstandings.packets.empty());
3087   EXPECT_EQ(0, conn->outstandings.numClonedPackets());
3088 }
3089 
TEST_F(QuicTransportFunctionsTest,ClonedRst)3090 TEST_F(QuicTransportFunctionsTest, ClonedRst) {
3091   auto conn = createConn();
3092   PacketEvent packetEvent(
3093       PacketNumberSpace::AppData,
3094       conn->ackStates.appDataAckState.nextPacketNum);
3095   auto stream = conn->streamManager->createNextBidirectionalStream().value();
3096   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
3097   RstStreamFrame rstStreamFrame(
3098       stream->id, GenericApplicationErrorCode::UNKNOWN, 0);
3099   packet.packet.frames.emplace_back(std::move(rstStreamFrame));
3100   conn->outstandings.packetEvents.insert(packetEvent);
3101   // This shall not crash
3102   updateConnection(
3103       *conn,
3104       packetEvent,
3105       packet.packet,
3106       TimePoint(),
3107       getEncodedSize(packet),
3108       getEncodedBodySize(packet),
3109       false /* isDSRPacket */);
3110   EXPECT_FALSE(conn->outstandings.packets.empty());
3111   EXPECT_EQ(1, conn->outstandings.numClonedPackets());
3112 }
3113 
TEST_F(QuicTransportFunctionsTest,TotalBytesSentUpdate)3114 TEST_F(QuicTransportFunctionsTest, TotalBytesSentUpdate) {
3115   auto conn = createConn();
3116   conn->lossState.totalBytesSent = 1234;
3117   conn->lossState.totalBodyBytesSent = 1000;
3118   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
3119   updateConnection(
3120       *conn,
3121       folly::none,
3122       packet.packet,
3123       TimePoint{},
3124       4321,
3125       4000,
3126       false /* isDSRPacket */);
3127   EXPECT_EQ(5555, conn->lossState.totalBytesSent);
3128   EXPECT_EQ(5000, conn->lossState.totalBodyBytesSent);
3129 }
3130 
TEST_F(QuicTransportFunctionsTest,TotalPacketsSentUpdate)3131 TEST_F(QuicTransportFunctionsTest, TotalPacketsSentUpdate) {
3132   const auto startTotalPacketsSent = 1234;
3133   auto conn = createConn();
3134   conn->lossState.totalPacketsSent = startTotalPacketsSent;
3135   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
3136   updateConnection(
3137       *conn,
3138       folly::none,
3139       packet.packet,
3140       TimePoint{},
3141       4321,
3142       0,
3143       false /* isDSRPacket */);
3144   EXPECT_EQ(startTotalPacketsSent + 1, conn->lossState.totalPacketsSent);
3145 }
3146 
TEST_F(QuicTransportFunctionsTest,TimeoutBasedRetxCountUpdate)3147 TEST_F(QuicTransportFunctionsTest, TimeoutBasedRetxCountUpdate) {
3148   auto conn = createConn();
3149   auto stream = conn->streamManager->createNextBidirectionalStream().value();
3150   conn->lossState.timeoutBasedRtxCount = 246;
3151   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
3152   RstStreamFrame rstStreamFrame(
3153       stream->id, GenericApplicationErrorCode::UNKNOWN, 0);
3154   packet.packet.frames.push_back(rstStreamFrame);
3155   PacketEvent packetEvent(PacketNumberSpace::AppData, 100);
3156   conn->outstandings.packetEvents.insert(packetEvent);
3157   updateConnection(
3158       *conn,
3159       packetEvent,
3160       packet.packet,
3161       TimePoint(),
3162       0,
3163       0,
3164       false /* isDSRPacket */);
3165   EXPECT_EQ(247, conn->lossState.timeoutBasedRtxCount);
3166 }
3167 
TEST_F(QuicTransportFunctionsTest,WriteLimitBytRttFraction)3168 TEST_F(QuicTransportFunctionsTest, WriteLimitBytRttFraction) {
3169   auto conn = createConn();
3170   conn->lossState.srtt = 150ms;
3171   auto mockCongestionController =
3172       std::make_unique<NiceMock<MockCongestionController>>();
3173   auto rawCongestionController = mockCongestionController.get();
3174   conn->congestionController = std::move(mockCongestionController);
3175 
3176   EventBase evb;
3177   auto socket =
3178       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
3179   auto rawSocket = socket.get();
3180 
3181   auto stream1 = conn->streamManager->createNextBidirectionalStream().value();
3182   auto buf = buildRandomInputData(2048 * 1024);
3183   writeDataToQuicStream(*stream1, buf->clone(), true);
3184 
3185   EXPECT_CALL(*rawSocket, write(_, _)).WillRepeatedly(Return(1));
3186   EXPECT_CALL(*rawCongestionController, getWritableBytes())
3187       .WillRepeatedly(Return(50));
3188   auto res = writeQuicDataToSocket(
3189       *rawSocket,
3190       *conn,
3191       *conn->clientConnectionId,
3192       *conn->serverConnectionId,
3193       *aead,
3194       *headerCipher,
3195       getVersion(*conn),
3196       500 /* packetLimit */);
3197 
3198   EXPECT_GT(500, res.packetsWritten);
3199   EXPECT_EQ(res.probesWritten, 0);
3200 }
3201 
TEST_F(QuicTransportFunctionsTest,CongestionControlWritableBytesRoundUp)3202 TEST_F(QuicTransportFunctionsTest, CongestionControlWritableBytesRoundUp) {
3203   auto conn = createConn();
3204   conn->udpSendPacketLen = 2000;
3205   auto mockCongestionController =
3206       std::make_unique<NiceMock<MockCongestionController>>();
3207   auto rawCongestionController = mockCongestionController.get();
3208   conn->congestionController = std::move(mockCongestionController);
3209 
3210   EXPECT_CALL(*rawCongestionController, getWritableBytes()).WillOnce(Return(1));
3211   EXPECT_EQ(conn->udpSendPacketLen, congestionControlWritableBytes(*conn));
3212 
3213   EXPECT_CALL(*rawCongestionController, getWritableBytes())
3214       .WillOnce(Return(1000));
3215   EXPECT_EQ(conn->udpSendPacketLen, congestionControlWritableBytes(*conn));
3216 
3217   EXPECT_CALL(*rawCongestionController, getWritableBytes()).WillOnce(Return(0));
3218   EXPECT_EQ(0, congestionControlWritableBytes(*conn));
3219 
3220   EXPECT_CALL(*rawCongestionController, getWritableBytes())
3221       .WillOnce(Return(2000));
3222   EXPECT_EQ(conn->udpSendPacketLen, congestionControlWritableBytes(*conn));
3223 
3224   EXPECT_CALL(*rawCongestionController, getWritableBytes())
3225       .WillOnce(Return(2001));
3226   EXPECT_EQ(conn->udpSendPacketLen * 2, congestionControlWritableBytes(*conn));
3227 }
3228 
TEST_F(QuicTransportFunctionsTest,HandshakeConfirmedDropCipher)3229 TEST_F(QuicTransportFunctionsTest, HandshakeConfirmedDropCipher) {
3230   auto conn = createConn();
3231   conn->readCodec = std::make_unique<QuicReadCodec>(QuicNodeType::Server);
3232   EventBase evb;
3233   auto socket =
3234       std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
3235   auto initialStream =
3236       getCryptoStream(*conn->cryptoState, EncryptionLevel::Initial);
3237   auto handshakeStream =
3238       getCryptoStream(*conn->cryptoState, EncryptionLevel::Handshake);
3239   writeDataToQuicStream(
3240       *initialStream, folly::IOBuf::copyBuffer("LittleRemedies"));
3241   writeDataToQuicStream(
3242       *handshakeStream,
3243       folly::IOBuf::copyBuffer("Where should I join the meeting"));
3244   ASSERT_NE(nullptr, conn->initialWriteCipher);
3245   conn->handshakeWriteCipher = createNoOpAead();
3246   conn->readCodec->setInitialReadCipher(createNoOpAead());
3247   conn->readCodec->setInitialHeaderCipher(createNoOpHeaderCipher());
3248   conn->readCodec->setHandshakeReadCipher(createNoOpAead());
3249   conn->readCodec->setHandshakeHeaderCipher(createNoOpHeaderCipher());
3250   conn->oneRttWriteCipher = createNoOpAead();
3251   conn->oneRttWriteHeaderCipher = createNoOpHeaderCipher();
3252   conn->readCodec->setOneRttReadCipher(createNoOpAead());
3253   conn->readCodec->setOneRttHeaderCipher(createNoOpHeaderCipher());
3254   writeCryptoDataProbesToSocketForTest(
3255       *socket,
3256       *conn,
3257       1,
3258       *aead,
3259       *headerCipher,
3260       getVersion(*conn),
3261       LongHeader::Types::Initial);
3262   writeCryptoDataProbesToSocketForTest(
3263       *socket,
3264       *conn,
3265       1,
3266       *aead,
3267       *headerCipher,
3268       getVersion(*conn),
3269       LongHeader::Types::Handshake);
3270   ASSERT_FALSE(initialStream->retransmissionBuffer.empty());
3271   ASSERT_FALSE(handshakeStream->retransmissionBuffer.empty());
3272   initialStream->insertIntoLossBuffer(std::make_unique<StreamBuffer>(
3273       folly::IOBuf::copyBuffer(
3274           "I don't see the dialup info in the meeting invite"),
3275       0,
3276       false));
3277   handshakeStream->insertIntoLossBuffer(std::make_unique<StreamBuffer>(
3278       folly::IOBuf::copyBuffer("Traffic Protocol Weekly Sync"), 0, false));
3279 
3280   handshakeConfirmed(*conn);
3281   EXPECT_TRUE(initialStream->writeBuffer.empty());
3282   EXPECT_TRUE(initialStream->retransmissionBuffer.empty());
3283   EXPECT_TRUE(initialStream->lossBuffer.empty());
3284   EXPECT_TRUE(handshakeStream->writeBuffer.empty());
3285   EXPECT_TRUE(handshakeStream->retransmissionBuffer.empty());
3286   EXPECT_TRUE(handshakeStream->lossBuffer.empty());
3287   EXPECT_EQ(nullptr, conn->initialWriteCipher);
3288   EXPECT_EQ(nullptr, conn->handshakeWriteCipher);
3289   EXPECT_EQ(nullptr, conn->readCodec->getInitialCipher());
3290   EXPECT_EQ(nullptr, conn->readCodec->getInitialHeaderCipher());
3291   EXPECT_EQ(nullptr, conn->readCodec->getHandshakeReadCipher());
3292   EXPECT_EQ(nullptr, conn->readCodec->getHandshakeHeaderCipher());
3293 }
3294 
TEST_F(QuicTransportFunctionsTest,ProbeWriteNewFunctionalFrames)3295 TEST_F(QuicTransportFunctionsTest, ProbeWriteNewFunctionalFrames) {
3296   auto conn = createConn();
3297   conn->udpSendPacketLen = 1200;
3298   EventBase evb;
3299   auto sock = std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(&evb);
3300   auto rawSocket = sock.get();
3301 
3302   EXPECT_CALL(*rawSocket, write(_, _))
3303       .WillRepeatedly(Invoke([&](const SocketAddress&,
3304                                  const std::unique_ptr<folly::IOBuf>& iobuf) {
3305         return iobuf->computeChainDataLength();
3306       }));
3307 
3308   auto stream = conn->streamManager->createNextBidirectionalStream().value();
3309   auto buf = folly::IOBuf::copyBuffer("Drug facts");
3310   writeDataToQuicStream(*stream, buf->clone(), true);
3311   writeQuicDataToSocket(
3312       *rawSocket,
3313       *conn,
3314       *conn->clientConnectionId,
3315       *conn->serverConnectionId,
3316       *aead,
3317       *headerCipher,
3318       getVersion(*conn),
3319       conn->transportSettings.writeConnectionDataPacketsLimit);
3320   ASSERT_EQ(1, stream->retransmissionBuffer.size());
3321 
3322   conn->pendingEvents.numProbePackets[PacketNumberSpace::AppData] = 1;
3323   conn->flowControlState.windowSize *= 2;
3324   conn->flowControlState.timeOfLastFlowControlUpdate = Clock::now() - 20s;
3325   maybeSendConnWindowUpdate(*conn, Clock::now());
3326   writeQuicDataToSocket(
3327       *rawSocket,
3328       *conn,
3329       *conn->clientConnectionId,
3330       *conn->serverConnectionId,
3331       *aead,
3332       *headerCipher,
3333       getVersion(*conn),
3334       1 /* limit to 1 packet */);
3335   EXPECT_EQ(2, conn->outstandings.packets.size());
3336   EXPECT_EQ(1, conn->outstandings.packets[1].packet.frames.size());
3337   EXPECT_EQ(
3338       QuicWriteFrame::Type::MaxDataFrame,
3339       conn->outstandings.packets[1].packet.frames[0].type());
3340 }
3341 
TEST_F(QuicTransportFunctionsTest,WriteWithInplaceBuilder)3342 TEST_F(QuicTransportFunctionsTest, WriteWithInplaceBuilder) {
3343   auto conn = createConn();
3344   conn->transportSettings.dataPathType = DataPathType::ContinuousMemory;
3345   auto simpleBufAccessor =
3346       std::make_unique<SimpleBufAccessor>(conn->udpSendPacketLen * 16);
3347   auto outputBuf = simpleBufAccessor->obtain();
3348   auto bufPtr = outputBuf.get();
3349   simpleBufAccessor->release(std::move(outputBuf));
3350   conn->bufAccessor = simpleBufAccessor.get();
3351   conn->transportSettings.batchingMode = QuicBatchingMode::BATCHING_MODE_GSO;
3352   EventBase evb;
3353   folly::test::MockAsyncUDPSocket mockSock(&evb);
3354   EXPECT_CALL(mockSock, getGSO()).WillRepeatedly(Return(true));
3355   auto stream = conn->streamManager->createNextBidirectionalStream().value();
3356   auto buf = folly::IOBuf::copyBuffer("Andante in C minor");
3357   writeDataToQuicStream(*stream, buf->clone(), true);
3358   EXPECT_CALL(mockSock, write(_, _))
3359       .Times(1)
3360       .WillOnce(Invoke([&](const SocketAddress&,
3361                            const std::unique_ptr<folly::IOBuf>& sockBuf) {
3362         EXPECT_GT(bufPtr->length(), 0);
3363         EXPECT_GE(sockBuf->length(), buf->length());
3364         EXPECT_EQ(sockBuf.get(), bufPtr);
3365         EXPECT_TRUE(folly::IOBufEqualTo()(*sockBuf, *bufPtr));
3366         EXPECT_FALSE(sockBuf->isChained());
3367         return sockBuf->computeChainDataLength();
3368       }));
3369   writeQuicDataToSocket(
3370       mockSock,
3371       *conn,
3372       *conn->clientConnectionId,
3373       *conn->serverConnectionId,
3374       *aead,
3375       *headerCipher,
3376       getVersion(*conn),
3377       conn->transportSettings.writeConnectionDataPacketsLimit);
3378   EXPECT_EQ(0, bufPtr->length());
3379   EXPECT_EQ(0, bufPtr->headroom());
3380 }
3381 
TEST_F(QuicTransportFunctionsTest,WriteWithInplaceBuilderRollbackBuf)3382 TEST_F(QuicTransportFunctionsTest, WriteWithInplaceBuilderRollbackBuf) {
3383   auto conn = createConn();
3384   conn->transportSettings.dataPathType = DataPathType::ContinuousMemory;
3385   auto simpleBufAccessor =
3386       std::make_unique<SimpleBufAccessor>(conn->udpSendPacketLen * 16);
3387   auto outputBuf = simpleBufAccessor->obtain();
3388   auto bufPtr = outputBuf.get();
3389   simpleBufAccessor->release(std::move(outputBuf));
3390   conn->bufAccessor = simpleBufAccessor.get();
3391   conn->transportSettings.batchingMode = QuicBatchingMode::BATCHING_MODE_GSO;
3392   EventBase evb;
3393   folly::test::MockAsyncUDPSocket mockSock(&evb);
3394   EXPECT_CALL(mockSock, getGSO()).WillRepeatedly(Return(true));
3395   EXPECT_CALL(mockSock, write(_, _)).Times(0);
3396   writeQuicDataToSocket(
3397       mockSock,
3398       *conn,
3399       *conn->clientConnectionId,
3400       *conn->serverConnectionId,
3401       *aead,
3402       *headerCipher,
3403       getVersion(*conn),
3404       conn->transportSettings.writeConnectionDataPacketsLimit);
3405   EXPECT_EQ(0, bufPtr->length());
3406   EXPECT_EQ(0, bufPtr->headroom());
3407 }
3408 
TEST_F(QuicTransportFunctionsTest,WriteWithInplaceBuilderGSOMultiplePackets)3409 TEST_F(QuicTransportFunctionsTest, WriteWithInplaceBuilderGSOMultiplePackets) {
3410   auto conn = createConn();
3411   conn->transportSettings.dataPathType = DataPathType::ContinuousMemory;
3412   auto simpleBufAccessor =
3413       std::make_unique<SimpleBufAccessor>(conn->udpSendPacketLen * 16);
3414   auto outputBuf = simpleBufAccessor->obtain();
3415   auto bufPtr = outputBuf.get();
3416   simpleBufAccessor->release(std::move(outputBuf));
3417   conn->bufAccessor = simpleBufAccessor.get();
3418   conn->transportSettings.batchingMode = QuicBatchingMode::BATCHING_MODE_GSO;
3419   EventBase evb;
3420   folly::test::MockAsyncUDPSocket mockSock(&evb);
3421   EXPECT_CALL(mockSock, getGSO()).WillRepeatedly(Return(true));
3422   auto stream = conn->streamManager->createNextBidirectionalStream().value();
3423   auto buf = buildRandomInputData(conn->udpSendPacketLen * 10);
3424   writeDataToQuicStream(*stream, buf->clone(), true);
3425   EXPECT_CALL(mockSock, writeGSO(_, _, _))
3426       .Times(1)
3427       .WillOnce(Invoke([&](const folly::SocketAddress&,
3428                            const std::unique_ptr<folly::IOBuf>& sockBuf,
3429                            int gso) {
3430         EXPECT_LE(gso, conn->udpSendPacketLen);
3431         EXPECT_GT(bufPtr->length(), 0);
3432         EXPECT_EQ(sockBuf.get(), bufPtr);
3433         EXPECT_TRUE(folly::IOBufEqualTo()(*sockBuf, *bufPtr));
3434         EXPECT_FALSE(sockBuf->isChained());
3435         return sockBuf->length();
3436       }));
3437   writeQuicDataToSocket(
3438       mockSock,
3439       *conn,
3440       *conn->clientConnectionId,
3441       *conn->serverConnectionId,
3442       *aead,
3443       *headerCipher,
3444       getVersion(*conn),
3445       conn->transportSettings.writeConnectionDataPacketsLimit);
3446   EXPECT_EQ(0, bufPtr->length());
3447   EXPECT_EQ(0, bufPtr->headroom());
3448 }
3449 
TEST_F(QuicTransportFunctionsTest,WriteProbingWithInplaceBuilder)3450 TEST_F(QuicTransportFunctionsTest, WriteProbingWithInplaceBuilder) {
3451   auto conn = createConn();
3452   conn->transportSettings.dataPathType = DataPathType::ContinuousMemory;
3453   conn->transportSettings.batchingMode = QuicBatchingMode::BATCHING_MODE_GSO;
3454   EventBase evb;
3455   folly::test::MockAsyncUDPSocket mockSock(&evb);
3456   EXPECT_CALL(mockSock, getGSO()).WillRepeatedly(Return(true));
3457 
3458   SimpleBufAccessor bufAccessor(
3459       conn->udpSendPacketLen * conn->transportSettings.maxBatchSize);
3460   conn->bufAccessor = &bufAccessor;
3461   auto buf = bufAccessor.obtain();
3462   auto bufPtr = buf.get();
3463   bufAccessor.release(std::move(buf));
3464 
3465   auto stream = conn->streamManager->createNextBidirectionalStream().value();
3466   auto inputBuf = buildRandomInputData(
3467       conn->udpSendPacketLen *
3468       conn->transportSettings.writeConnectionDataPacketsLimit);
3469   writeDataToQuicStream(*stream, inputBuf->clone(), true);
3470   EXPECT_CALL(mockSock, writeGSO(_, _, _))
3471       .Times(1)
3472       .WillOnce(Invoke([&](const folly::SocketAddress&,
3473                            const std::unique_ptr<folly::IOBuf>& sockBuf,
3474                            int gso) {
3475         EXPECT_LE(gso, conn->udpSendPacketLen);
3476         EXPECT_GE(
3477             bufPtr->length(),
3478             conn->udpSendPacketLen *
3479                 conn->transportSettings.writeConnectionDataPacketsLimit);
3480         EXPECT_EQ(sockBuf.get(), bufPtr);
3481         EXPECT_TRUE(folly::IOBufEqualTo()(*sockBuf, *bufPtr));
3482         EXPECT_FALSE(sockBuf->isChained());
3483         return sockBuf->length();
3484       }));
3485   writeQuicDataToSocket(
3486       mockSock,
3487       *conn,
3488       *conn->clientConnectionId,
3489       *conn->serverConnectionId,
3490       *aead,
3491       *headerCipher,
3492       getVersion(*conn),
3493       conn->transportSettings.writeConnectionDataPacketsLimit + 1);
3494   ASSERT_EQ(0, bufPtr->length());
3495   ASSERT_EQ(0, bufPtr->headroom());
3496   EXPECT_GE(conn->outstandings.packets.size(), 5);
3497   // Make sure there no more new data to write:
3498   StreamFrameScheduler streamScheduler(*conn);
3499   ASSERT_FALSE(streamScheduler.hasPendingData());
3500 
3501   // The first packet has be a full packet
3502   auto firstPacketSize =
3503       conn->outstandings.packets.front().metadata.encodedSize;
3504   auto outstandingPacketsCount = conn->outstandings.packets.size();
3505   ASSERT_EQ(firstPacketSize, conn->udpSendPacketLen);
3506   EXPECT_CALL(mockSock, write(_, _))
3507       .Times(1)
3508       .WillOnce(Invoke([&](const folly::SocketAddress&,
3509                            const std::unique_ptr<folly::IOBuf>& buf) {
3510         EXPECT_FALSE(buf->isChained());
3511         EXPECT_EQ(buf->length(), firstPacketSize);
3512         return buf->length();
3513       }));
3514   writeProbingDataToSocketForTest(
3515       mockSock,
3516       *conn,
3517       1 /* probesToSend */,
3518       *aead,
3519       *headerCipher,
3520       getVersion(*conn));
3521   EXPECT_EQ(conn->outstandings.packets.size(), outstandingPacketsCount + 1);
3522   EXPECT_EQ(0, bufPtr->length());
3523   EXPECT_EQ(0, bufPtr->headroom());
3524 
3525   // Clone again, this time 2 pacckets.
3526   EXPECT_CALL(mockSock, writeGSO(_, _, _))
3527       .Times(1)
3528       .WillOnce(Invoke([&](const folly::SocketAddress&,
3529                            const std::unique_ptr<folly::IOBuf>& buf,
3530                            int gso) {
3531         EXPECT_FALSE(buf->isChained());
3532         EXPECT_EQ(conn->udpSendPacketLen, gso);
3533         EXPECT_EQ(buf->length(), conn->udpSendPacketLen * 2);
3534         return buf->length();
3535       }));
3536   writeProbingDataToSocketForTest(
3537       mockSock,
3538       *conn,
3539       2 /* probesToSend */,
3540       *aead,
3541       *headerCipher,
3542       getVersion(*conn));
3543   EXPECT_EQ(0, bufPtr->length());
3544   EXPECT_EQ(0, bufPtr->headroom());
3545   EXPECT_EQ(conn->outstandings.packets.size(), outstandingPacketsCount + 3);
3546 }
3547 
TEST_F(QuicTransportFunctionsTest,WriteD6DProbesWithInplaceBuilder)3548 TEST_F(QuicTransportFunctionsTest, WriteD6DProbesWithInplaceBuilder) {
3549   auto conn = createConn();
3550   conn->transportSettings.dataPathType = DataPathType::ContinuousMemory;
3551   conn->d6d.currentProbeSize = 1450;
3552   conn->pendingEvents.d6d.sendProbePacket = true;
3553   auto simpleBufAccessor =
3554       std::make_unique<SimpleBufAccessor>(kDefaultMaxUDPPayload * 16);
3555   auto outputBuf = simpleBufAccessor->obtain();
3556   auto bufPtr = outputBuf.get();
3557   simpleBufAccessor->release(std::move(outputBuf));
3558   conn->bufAccessor = simpleBufAccessor.get();
3559   conn->transportSettings.batchingMode = QuicBatchingMode::BATCHING_MODE_GSO;
3560   EventBase evb;
3561   folly::test::MockAsyncUDPSocket mockSock(&evb);
3562   EXPECT_CALL(mockSock, getGSO()).WillRepeatedly(Return(true));
3563   EXPECT_CALL(mockSock, write(_, _))
3564       .Times(1)
3565       .WillOnce(Invoke([&](const SocketAddress&,
3566                            const std::unique_ptr<folly::IOBuf>& sockBuf) {
3567         EXPECT_EQ(sockBuf->length(), conn->d6d.currentProbeSize);
3568         EXPECT_EQ(sockBuf.get(), bufPtr);
3569         EXPECT_TRUE(folly::IOBufEqualTo()(*sockBuf, *bufPtr));
3570         EXPECT_FALSE(sockBuf->isChained());
3571         return sockBuf->computeChainDataLength();
3572       }));
3573   writeD6DProbeToSocket(
3574       mockSock,
3575       *conn,
3576       *conn->clientConnectionId,
3577       *conn->serverConnectionId,
3578       *aead,
3579       *headerCipher,
3580       getVersion(*conn));
3581   EXPECT_EQ(0, bufPtr->length());
3582   EXPECT_EQ(0, bufPtr->headroom());
3583 }
3584 
TEST_F(QuicTransportFunctionsTest,UpdateConnectionWithBufferMeta)3585 TEST_F(QuicTransportFunctionsTest, UpdateConnectionWithBufferMeta) {
3586   auto conn = createConn();
3587   // Builds a fake packet to test with.
3588   auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
3589 
3590   auto streamId =
3591       conn->streamManager->createNextBidirectionalStream().value()->id;
3592   auto stream = conn->streamManager->findStream(streamId);
3593   EXPECT_TRUE(stream->retransmissionBufMetas.empty());
3594   writeDataToQuicStream(
3595       *stream, IOBuf::copyBuffer("Wear a face mask please!"), false /* eof */);
3596   BufferMeta bufMeta(2000);
3597   writeBufMetaToQuicStream(*stream, bufMeta, true /* eof */);
3598   EXPECT_TRUE(stream->writeBufMeta.eof);
3599   EXPECT_EQ(2000, stream->writeBufMeta.length);
3600   auto bufMetaStartingOffset = stream->writeBufMeta.offset;
3601   WriteStreamFrame writeStreamFrame(
3602       streamId, bufMetaStartingOffset, 1000, false /* fin */);
3603   writeStreamFrame.fromBufMeta = true;
3604   packet.packet.frames.push_back(writeStreamFrame);
3605 
3606   updateConnection(
3607       *conn,
3608       folly::none,
3609       packet.packet,
3610       TimePoint(),
3611       getEncodedSize(packet),
3612       getEncodedBodySize(packet),
3613       true /* dsr */);
3614   EXPECT_EQ(1000 + bufMetaStartingOffset, stream->writeBufMeta.offset);
3615   EXPECT_EQ(1000, stream->writeBufMeta.length);
3616   EXPECT_FALSE(stream->retransmissionBufMetas.empty());
3617   auto retxBufMetaIter =
3618       stream->retransmissionBufMetas.find(bufMetaStartingOffset);
3619   EXPECT_NE(retxBufMetaIter, stream->retransmissionBufMetas.end());
3620   EXPECT_EQ(bufMetaStartingOffset, retxBufMetaIter->second.offset);
3621   EXPECT_EQ(1000, retxBufMetaIter->second.length);
3622   EXPECT_FALSE(retxBufMetaIter->second.eof);
3623   EXPECT_TRUE(conn->outstandings.packets.back().isDSRPacket);
3624 
3625   // Manually lose this packet:
3626   stream->lossBufMetas.push_back(retxBufMetaIter->second);
3627   stream->retransmissionBufMetas.erase(retxBufMetaIter);
3628   ASSERT_FALSE(stream->lossBufMetas.empty());
3629   ASSERT_TRUE(stream->retransmissionBufMetas.empty());
3630 
3631   // Retransmit it:
3632   auto retxPacket = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
3633   // Retx of the stream looks exactly the same
3634   retxPacket.packet.frames.push_back(writeStreamFrame);
3635   updateConnection(
3636       *conn,
3637       folly::none,
3638       retxPacket.packet,
3639       TimePoint(),
3640       getEncodedSize(retxPacket),
3641       getEncodedBodySize(packet),
3642       true /* dsr */);
3643   EXPECT_TRUE(stream->lossBufMetas.empty());
3644   retxBufMetaIter = stream->retransmissionBufMetas.find(bufMetaStartingOffset);
3645   EXPECT_NE(retxBufMetaIter, stream->retransmissionBufMetas.end());
3646   EXPECT_EQ(bufMetaStartingOffset, retxBufMetaIter->second.offset);
3647   EXPECT_EQ(1000, retxBufMetaIter->second.length);
3648   EXPECT_FALSE(retxBufMetaIter->second.eof);
3649   EXPECT_TRUE(conn->outstandings.packets.back().isDSRPacket);
3650 }
3651 
3652 } // namespace test
3653 } // namespace quic
3654