blob: 0d891e021a3ad94f1a26c670c89c6423a2203758 [file] [log] [blame]
Eric Newberry185ab292017-03-28 06:45:39 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberry7b0071e2017-07-03 17:33:31 +00002/*
Davide Pesavento1b22a8c2022-03-07 21:23:23 -05003 * Copyright (c) 2014-2022, Regents of the University of California,
Eric Newberry185ab292017-03-28 06:45:39 +00004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "face/lp-reliability.hpp"
27#include "face/face.hpp"
Eric Newberry185ab292017-03-28 06:45:39 +000028#include "face/generic-link-service.hpp"
29
30#include "tests/test-common.hpp"
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040031#include "tests/daemon/global-io-fixture.hpp"
Eric Newberry185ab292017-03-28 06:45:39 +000032#include "dummy-face.hpp"
33#include "dummy-transport.hpp"
34
Eric Newberry7b0071e2017-07-03 17:33:31 +000035#include <cstring>
Davide Pesaventob7bfcb92022-05-22 23:55:23 -040036#include <unordered_set>
Eric Newberry7b0071e2017-07-03 17:33:31 +000037
Eric Newberry185ab292017-03-28 06:45:39 +000038namespace nfd {
39namespace face {
40namespace tests {
41
42using namespace nfd::tests;
43
Eric Newberry185ab292017-03-28 06:45:39 +000044class DummyLpReliabilityLinkService : public GenericLinkService
45{
46public:
47 LpReliability*
48 getLpReliability()
49 {
50 return &m_reliability;
51 }
52
53 void
54 sendLpPackets(std::vector<lp::Packet> frags)
55 {
56 if (frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -070057 Interest interest("/test/prefix");
58 lp::Packet pkt;
Davide Pesaventof190cfa2019-07-17 20:14:11 -040059 pkt.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
Eric Newberry32f7eac2020-02-07 14:40:17 -080060 assignSequences(frags);
Eric Newberry41aba102017-11-01 16:42:13 -070061 m_reliability.handleOutgoing(frags, std::move(pkt), true);
Eric Newberry185ab292017-03-28 06:45:39 +000062 }
63
Davide Pesaventof190cfa2019-07-17 20:14:11 -040064 for (auto frag : frags) {
Teng Liangf3bc3ae2020-06-08 10:19:25 -070065 this->sendLpPacket(std::move(frag));
Eric Newberry185ab292017-03-28 06:45:39 +000066 }
67 }
68
69private:
70 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070071 doSendInterest(const Interest&) final
Eric Newberry185ab292017-03-28 06:45:39 +000072 {
Davide Pesavento5a897692019-10-31 01:28:43 -040073 BOOST_FAIL("unexpected doSendInterest");
Eric Newberry185ab292017-03-28 06:45:39 +000074 }
75
76 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070077 doSendData(const Data&) final
Eric Newberry185ab292017-03-28 06:45:39 +000078 {
Davide Pesavento5a897692019-10-31 01:28:43 -040079 BOOST_FAIL("unexpected doSendData");
Eric Newberry185ab292017-03-28 06:45:39 +000080 }
81
82 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070083 doSendNack(const lp::Nack&) final
Eric Newberry185ab292017-03-28 06:45:39 +000084 {
Davide Pesavento5a897692019-10-31 01:28:43 -040085 BOOST_FAIL("unexpected doSendNack");
Eric Newberry185ab292017-03-28 06:45:39 +000086 }
87
88 void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040089 doReceivePacket(const Block&, const EndpointId&) final
Eric Newberry185ab292017-03-28 06:45:39 +000090 {
Davide Pesavento5a897692019-10-31 01:28:43 -040091 BOOST_FAIL("unexpected doReceivePacket");
Eric Newberry185ab292017-03-28 06:45:39 +000092 }
93};
94
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040095class LpReliabilityFixture : public GlobalIoTimeFixture
Eric Newberry185ab292017-03-28 06:45:39 +000096{
97public:
98 LpReliabilityFixture()
99 : linkService(make_unique<DummyLpReliabilityLinkService>())
100 , transport(make_unique<DummyTransport>())
101 , face(make_unique<DummyFace>())
102 {
103 linkService->setFaceAndTransport(*face, *transport);
104 transport->setFaceAndLinkService(*face, *linkService);
105
106 GenericLinkService::Options options;
107 options.reliabilityOptions.isEnabled = true;
108 linkService->setOptions(options);
109
110 reliability = linkService->getLpReliability();
Eric Newberry7b0071e2017-07-03 17:33:31 +0000111 reliability->m_lastTxSeqNo = 1;
112 }
113
114 static bool
115 netPktHasUnackedFrag(const shared_ptr<LpReliability::NetPkt>& netPkt, lp::Sequence txSeq)
116 {
117 return std::any_of(netPkt->unackedFrags.begin(), netPkt->unackedFrags.end(),
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400118 [txSeq] (auto fragIt) { return fragIt->first == txSeq; });
Eric Newberry7b0071e2017-07-03 17:33:31 +0000119 }
120
Eric Newberry7b0071e2017-07-03 17:33:31 +0000121 /** \brief make an LpPacket with fragment of specified size
Eric Newberry32f7eac2020-02-07 14:40:17 -0800122 * \param pktNum packet identifier, which can be extracted with \p getPktNum
Davide Pesaventob93fb6c2020-04-12 14:10:45 -0400123 * \param payloadSize total payload size; must be >= 4 and <= 255
Eric Newberry7b0071e2017-07-03 17:33:31 +0000124 */
125 static lp::Packet
Eric Newberry32f7eac2020-02-07 14:40:17 -0800126 makeFrag(uint32_t pktNum, size_t payloadSize = 4)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000127 {
Davide Pesaventob93fb6c2020-04-12 14:10:45 -0400128 BOOST_ASSERT(payloadSize >= 4 && payloadSize <= 255);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000129 lp::Packet pkt;
130 ndn::Buffer buf(payloadSize);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800131 std::memcpy(buf.data(), &pktNum, sizeof(pktNum));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400132 pkt.set<lp::FragmentField>({buf.cbegin(), buf.cend()});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000133 return pkt;
134 }
135
136 /** \brief extract packet identifier from LpPacket made with \p makeFrag
137 * \retval 0 packet identifier cannot be extracted
138 */
139 static uint32_t
Eric Newberry32f7eac2020-02-07 14:40:17 -0800140 getPktNum(const lp::Packet& pkt)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000141 {
Davide Pesaventob93fb6c2020-04-12 14:10:45 -0400142 BOOST_REQUIRE(pkt.has<lp::FragmentField>());
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400143 auto [begin, end] = pkt.get<lp::FragmentField>();
Eric Newberry7b0071e2017-07-03 17:33:31 +0000144 if (std::distance(begin, end) < 4) {
145 return 0;
146 }
147
148 uint32_t value = 0;
149 std::memcpy(&value, &*begin, sizeof(value));
150 return value;
Eric Newberry185ab292017-03-28 06:45:39 +0000151 }
152
Eric Newberry971d9622018-03-30 23:29:26 -0700153protected:
Eric Newberry185ab292017-03-28 06:45:39 +0000154 unique_ptr<DummyLpReliabilityLinkService> linkService;
155 unique_ptr<DummyTransport> transport;
156 unique_ptr<DummyFace> face;
157 LpReliability* reliability;
158};
159
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400160BOOST_AUTO_TEST_SUITE(Face)
Eric Newberry185ab292017-03-28 06:45:39 +0000161BOOST_FIXTURE_TEST_SUITE(TestLpReliability, LpReliabilityFixture)
162
163BOOST_AUTO_TEST_CASE(SendNoFragmentField)
164{
165 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000166
167 linkService->sendLpPackets({pkt});
168 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000169 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700170 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
171 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
172 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700173 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000174}
175
Eric Newberry7b0071e2017-07-03 17:33:31 +0000176BOOST_AUTO_TEST_CASE(SendUnfragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000177{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000178 lp::Packet pkt1 = makeFrag(1024, 50);
179 lp::Packet pkt2 = makeFrag(3000, 30);
Eric Newberry185ab292017-03-28 06:45:39 +0000180
181 linkService->sendLpPackets({pkt1});
Eric Newberry971d9622018-03-30 23:29:26 -0700182 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Teng Liang13d582a2020-07-21 20:23:11 -0700183 lp::Packet cached1(transport->sentPackets.front());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000184 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
Eric Newberry32f7eac2020-02-07 14:40:17 -0800185 BOOST_CHECK(cached1.has<lp::SequenceField>());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000186 lp::Sequence firstTxSeq = cached1.get<lp::TxSequenceField>();
Eric Newberry971d9622018-03-30 23:29:26 -0700187 BOOST_CHECK_EQUAL(firstTxSeq, 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800188 BOOST_CHECK_EQUAL(getPktNum(cached1), 1024);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700189 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
190 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
191 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700192 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000193
Eric Newberry185ab292017-03-28 06:45:39 +0000194 // T+500ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000195 // 1024 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400196 advanceClocks(1_ms, 500);
Eric Newberry185ab292017-03-28 06:45:39 +0000197 linkService->sendLpPackets({pkt2});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000198 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
Eric Newberry185ab292017-03-28 06:45:39 +0000199
Eric Newberry00d39fd2017-12-10 14:26:45 -0700200 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
201 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 1);
202 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000203 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq).netPkt);
204 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
205 BOOST_CHECK_NE(reliability->m_unackedFrags.at(firstTxSeq).netPkt,
Eric Newberry971d9622018-03-30 23:29:26 -0700206 reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000207 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).retxCount, 0);
208 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
209 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq);
210 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700211 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
212 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
213 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700214 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000215
216 // T+1250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000217 // 1024 rto: 1000ms, txSeq: 4, started T+1000ms, retx 1
218 // 3000 rto: 1000ms, txSeq: 3, started T+500ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400219 advanceClocks(1_ms, 750);
Eric Newberry185ab292017-03-28 06:45:39 +0000220
Eric Newberry00d39fd2017-12-10 14:26:45 -0700221 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000222 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700223 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000224 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 2).retxCount, 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700225 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000226 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
227 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 1);
228 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700229 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
230 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
231 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700232 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000233
234 // T+2250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000235 // 1024 rto: 1000ms, txSeq: 6, started T+2000ms, retx 2
236 // 3000 rto: 1000ms, txSeq: 5, started T+1500ms, retx 1
Davide Pesavento14e71f02019-03-28 17:35:25 -0400237 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000238
Eric Newberry00d39fd2017-12-10 14:26:45 -0700239 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000240 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 0);
241 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700242 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000243 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 4).retxCount, 2);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700244 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000245 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 3).retxCount, 1);
246 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 3);
247 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700248 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
249 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
250 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700251 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000252
253 // T+3250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000254 // 1024 rto: 1000ms, txSeq: 8, started T+3000ms, retx 3
255 // 3000 rto: 1000ms, txSeq: 7, started T+2500ms, retx 2
Davide Pesavento14e71f02019-03-28 17:35:25 -0400256 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000257
Eric Newberry00d39fd2017-12-10 14:26:45 -0700258 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000259 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 0);
260 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700261 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000262 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 6).retxCount, 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700263 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000264 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 5).retxCount, 2);
265 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 5);
266 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 7);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700267 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
268 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
269 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700270 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000271
272 // T+4250ms
273 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000274 // 3000 rto: 1000ms, txSeq: 9, started T+3500ms, retx 3
Davide Pesavento14e71f02019-03-28 17:35:25 -0400275 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000276
Eric Newberry00d39fd2017-12-10 14:26:45 -0700277 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000278 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 0);
279 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700280 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 7), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000281 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 7).retxCount, 3);
282 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 7);
283 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry185ab292017-03-28 06:45:39 +0000284
Eric Newberry00d39fd2017-12-10 14:26:45 -0700285 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
286 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
287 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 1);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700288 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 1);
Eric Newberry41aba102017-11-01 16:42:13 -0700289
Eric Newberry185ab292017-03-28 06:45:39 +0000290 // T+4750ms
291 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000292 // 3000 rto: expired, removed
Davide Pesavento14e71f02019-03-28 17:35:25 -0400293 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000294
295 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000296 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
297 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700298 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
299 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
300 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 2);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700301 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 2);
Eric Newberry185ab292017-03-28 06:45:39 +0000302}
303
Eric Newberry7b0071e2017-07-03 17:33:31 +0000304BOOST_AUTO_TEST_CASE(SendFragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000305{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000306 lp::Packet pkt1 = makeFrag(2048, 30);
307 lp::Packet pkt2 = makeFrag(2049, 30);
308 lp::Packet pkt3 = makeFrag(2050, 10);
Eric Newberry185ab292017-03-28 06:45:39 +0000309
Eric Newberry7b0071e2017-07-03 17:33:31 +0000310 linkService->sendLpPackets({pkt1, pkt2, pkt3});
311 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000312
Teng Liang13d582a2020-07-21 20:23:11 -0700313 lp::Packet cached1(transport->sentPackets.at(0));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000314 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
315 BOOST_CHECK_EQUAL(cached1.get<lp::TxSequenceField>(), 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800316 BOOST_CHECK(cached1.has<lp::SequenceField>());
317 BOOST_CHECK_EQUAL(getPktNum(cached1), 2048);
Teng Liang13d582a2020-07-21 20:23:11 -0700318 lp::Packet cached2(transport->sentPackets.at(1));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000319 BOOST_REQUIRE(cached2.has<lp::TxSequenceField>());
320 BOOST_CHECK_EQUAL(cached2.get<lp::TxSequenceField>(), 3);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800321 BOOST_CHECK(cached2.has<lp::SequenceField>());
322 BOOST_CHECK_EQUAL(getPktNum(cached2), 2049);
Teng Liang13d582a2020-07-21 20:23:11 -0700323 lp::Packet cached3(transport->sentPackets.at(2));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000324 BOOST_REQUIRE(cached3.has<lp::TxSequenceField>());
325 BOOST_CHECK_EQUAL(cached3.get<lp::TxSequenceField>(), 4);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800326 BOOST_CHECK(cached3.has<lp::SequenceField>());
327 BOOST_CHECK_EQUAL(getPktNum(cached3), 2050);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700328 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
329 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
330 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700331 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000332
Eric Newberry7b0071e2017-07-03 17:33:31 +0000333 // T+0ms
334 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
335 // 2049 rto: 1000ms, txSeq: 3, started T+0ms, retx 0
336 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Eric Newberry185ab292017-03-28 06:45:39 +0000337
Eric Newberry00d39fd2017-12-10 14:26:45 -0700338 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
339 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1);
340 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800341 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
342 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(3).pkt), 2049);
343 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000344 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
345 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
346 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
347 BOOST_REQUIRE(reliability->m_unackedFrags.at(3).netPkt);
348 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
349 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
350 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(3).netPkt);
351 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
352 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
353 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
354 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
355 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
356 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
357 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
358 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700359 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
360 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
361 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700362 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000363
Eric Newberry7b0071e2017-07-03 17:33:31 +0000364 // T+250ms
365 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
366 // 2049 rto: 1000ms, txSeq: 5, started T+250ms, retx 1
367 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400368 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800369 reliability->onLpPacketLost(3, true);
Eric Newberry185ab292017-03-28 06:45:39 +0000370
Eric Newberry00d39fd2017-12-10 14:26:45 -0700371 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000372 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700373 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 1);
374 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800375 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
376 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(5).pkt), 2049);
377 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000378 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
379 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
380 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(5).retxCount, 1);
381 BOOST_REQUIRE(reliability->m_unackedFrags.at(5).netPkt);
382 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
383 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
384 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(5).netPkt);
385 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
386 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
387 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
388 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
389 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
390 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
391 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
392 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700393 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
394 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
395 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700396 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000397
398 // T+500ms
399 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
400 // 2049 rto: 1000ms, txSeq: 6, started T+500ms, retx 2
401 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400402 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800403 reliability->onLpPacketLost(5, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000404
Eric Newberry00d39fd2017-12-10 14:26:45 -0700405 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000406 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700407 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 1);
408 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800409 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
410 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(6).pkt), 2049);
411 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000412 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
413 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
414 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(6).retxCount, 2);
415 BOOST_REQUIRE(reliability->m_unackedFrags.at(6).netPkt);
416 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
417 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
418 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(6).netPkt);
419 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
420 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
421 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
422 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
423 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
424 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
425 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
426 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700427 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
428 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
429 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700430 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000431
432 // T+750ms
433 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
434 // 2049 rto: 1000ms, txSeq: 7, started T+750ms, retx 3
435 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400436 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800437 reliability->onLpPacketLost(6, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000438
439 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 1);
440 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700441 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(7), 1);
442 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800443 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
444 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(7).pkt), 2049);
445 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000446 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
447 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
448 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(7).retxCount, 3);
449 BOOST_REQUIRE(reliability->m_unackedFrags.at(7).netPkt);
450 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
451 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
452 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(7).netPkt);
453 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
454 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
455 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
456 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
457 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 7));
458 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
459 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
460 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700461 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
462 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
463 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700464 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000465
466 // T+850ms
467 // 2048 rto: expired, removed
468 // 2049 rto: expired, removed
469 // 2050 rto: expired, removed
Davide Pesavento14e71f02019-03-28 17:35:25 -0400470 advanceClocks(1_ms, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800471 reliability->onLpPacketLost(7, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000472
473 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
474 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700475 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
476 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
477 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 1);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700478 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000479}
480
Eric Newberry00d39fd2017-12-10 14:26:45 -0700481BOOST_AUTO_TEST_CASE(AckUnknownTxSeq)
482{
483 linkService->sendLpPackets({makeFrag(1, 50)});
484
485 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
486 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
487 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
488 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
489 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
490 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
491 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
492 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700493 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700494
495 lp::Packet ackPkt;
496 ackPkt.add<lp::AckField>(10101010);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800497 BOOST_CHECK(reliability->processIncomingPacket(ackPkt));
Eric Newberry00d39fd2017-12-10 14:26:45 -0700498
499 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
500 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
501 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
502 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
503 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
504 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
505 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
506 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700507 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700508}
509
Eric Newberry971d9622018-03-30 23:29:26 -0700510BOOST_AUTO_TEST_CASE(LossByGreaterAcks)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000511{
Eric Newberry971d9622018-03-30 23:29:26 -0700512 // Detect loss by 3x greater Acks, also tests wraparound
513
Eric Newberry7b0071e2017-07-03 17:33:31 +0000514 reliability->m_lastTxSeqNo = 0xFFFFFFFFFFFFFFFE;
515
Eric Newberry971d9622018-03-30 23:29:26 -0700516 // Passed to sendLpPackets individually since they are
517 // from separate, non-fragmented network packets
Eric Newberry7b0071e2017-07-03 17:33:31 +0000518 linkService->sendLpPackets({makeFrag(1, 50)});
519 linkService->sendLpPackets({makeFrag(2, 50)});
520 linkService->sendLpPackets({makeFrag(3, 50)});
521 linkService->sendLpPackets({makeFrag(4, 50)});
522 linkService->sendLpPackets({makeFrag(5, 50)});
Eric Newberry185ab292017-03-28 06:45:39 +0000523
524 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000525 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
526 BOOST_CHECK(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).netPkt);
527 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 1); // pkt2
528 BOOST_CHECK(reliability->m_unackedFrags.at(0).netPkt);
529 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
530 BOOST_CHECK(reliability->m_unackedFrags.at(1).netPkt);
531 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
532 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
533 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
534 BOOST_CHECK(reliability->m_unackedFrags.at(3).netPkt);
Eric Newberry185ab292017-03-28 06:45:39 +0000535 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700536 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
537 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
538 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700539 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000540
541 lp::Packet ackPkt1;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000542 ackPkt1.add<lp::AckField>(0);
Eric Newberry185ab292017-03-28 06:45:39 +0000543
544 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
545
Eric Newberry32f7eac2020-02-07 14:40:17 -0800546 BOOST_CHECK(reliability->processIncomingPacket(ackPkt1));
Eric Newberry185ab292017-03-28 06:45:39 +0000547
548 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700549 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000550 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
551 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000552 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700553 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000554 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
555 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700556 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
Eric Newberry7b0071e2017-07-03 17:33:31 +0000557 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
558 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700559 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000560 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
561 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000562 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000563 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700564 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
565 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
566 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700567 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000568
569 lp::Packet ackPkt2;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000570 ackPkt2.add<lp::AckField>(2);
571 ackPkt1.add<lp::AckField>(101010); // Unknown TxSequence number - ignored
Eric Newberry185ab292017-03-28 06:45:39 +0000572
573 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
574
Eric Newberry32f7eac2020-02-07 14:40:17 -0800575 BOOST_CHECK(reliability->processIncomingPacket(ackPkt2));
Eric Newberry185ab292017-03-28 06:45:39 +0000576
577 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000578 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000579 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
580 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000581 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700582 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000583 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
584 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700585 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
586 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000587 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
588 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
589 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(101010), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000590 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000591 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700592 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 2);
593 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
594 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700595 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000596
597 lp::Packet ackPkt3;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000598 ackPkt3.add<lp::AckField>(1);
Eric Newberry185ab292017-03-28 06:45:39 +0000599
600 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
601
Eric Newberry32f7eac2020-02-07 14:40:17 -0800602 BOOST_CHECK(reliability->processIncomingPacket(ackPkt3));
Eric Newberry185ab292017-03-28 06:45:39 +0000603
604 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000605 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
606 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
607 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
608 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700609 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000610 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
611 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700612 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1); // pkt1 new TxSeq
Eric Newberry7b0071e2017-07-03 17:33:31 +0000613 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 1);
614 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).nGreaterSeqAcks, 0);
615 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000616 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Teng Liang13d582a2020-07-21 20:23:11 -0700617 lp::Packet sentRetxPkt(transport->sentPackets.back());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000618 BOOST_REQUIRE(sentRetxPkt.has<lp::TxSequenceField>());
619 BOOST_CHECK_EQUAL(sentRetxPkt.get<lp::TxSequenceField>(), 4);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800620 BOOST_CHECK_EQUAL(getPktNum(sentRetxPkt), 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700621 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
622 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
623 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700624 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000625
626 lp::Packet ackPkt4;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000627 ackPkt4.add<lp::AckField>(4);
Eric Newberry185ab292017-03-28 06:45:39 +0000628
629 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
630
Eric Newberry32f7eac2020-02-07 14:40:17 -0800631 BOOST_CHECK(reliability->processIncomingPacket(ackPkt4));
Eric Newberry185ab292017-03-28 06:45:39 +0000632
633 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000634 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
635 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
636 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
637 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700638 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000639 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
640 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 1);
641 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 0); // pkt1 new TxSeq
642 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000643 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700644 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
645 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 1);
646 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700647 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700648}
649
Eric Newberry971d9622018-03-30 23:29:26 -0700650BOOST_AUTO_TEST_CASE(SkipFragmentsRemovedInRtt)
651{
652 auto opts = linkService->getOptions();
653 opts.reliabilityOptions.maxRetx = 0; // just to make the test case shorter
654 opts.reliabilityOptions.seqNumLossThreshold = 3;
655 linkService->setOptions(opts);
656
657 lp::Packet frag1 = makeFrag(5001);
658 lp::Packet frag2 = makeFrag(5002);
659 linkService->sendLpPackets({frag1, frag2}); // First packet has 2 fragments
660 linkService->sendLpPackets({makeFrag(5003)});
661 linkService->sendLpPackets({makeFrag(5004)});
662 linkService->sendLpPackets({makeFrag(5005)});
663
664 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
665 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
666
667 lp::Sequence firstTxSeq = reliability->m_firstUnackedFrag->first;
668
669 // Ack the last 2 packets
670 lp::Packet ackPkt1;
671 ackPkt1.add<lp::AckField>(firstTxSeq + 4);
672 ackPkt1.add<lp::AckField>(firstTxSeq + 3);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800673 BOOST_CHECK(reliability->processIncomingPacket(ackPkt1));
Eric Newberry971d9622018-03-30 23:29:26 -0700674
675 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
676 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).nGreaterSeqAcks, 2);
677 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).nGreaterSeqAcks, 2);
678
679 // Ack the third packet (5003)
680 // This triggers a "loss by greater Acks" for packets 5001 and 5002
681 lp::Packet ackPkt2;
682 ackPkt2.add<lp::AckField>(firstTxSeq + 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800683 BOOST_CHECK(reliability->processIncomingPacket(ackPkt2)); // tests crash/assert reported in bug #4479
Eric Newberry971d9622018-03-30 23:29:26 -0700684
685 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
686}
687
Eric Newberry00d39fd2017-12-10 14:26:45 -0700688BOOST_AUTO_TEST_CASE(CancelLossNotificationOnAck)
689{
690 reliability->onDroppedInterest.connect([] (const Interest&) {
691 BOOST_FAIL("Packet loss timeout should be cancelled when packet acknowledged");
692 });
693
694 reliability->m_lastTxSeqNo = 0;
695
696 linkService->sendLpPackets({makeFrag(1, 50)});
697
Davide Pesavento14e71f02019-03-28 17:35:25 -0400698 advanceClocks(1_ms, 500);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700699
700 lp::Packet ackPkt;
701 ackPkt.add<lp::AckField>(1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800702 BOOST_CHECK(reliability->processIncomingPacket(ackPkt));
Eric Newberry00d39fd2017-12-10 14:26:45 -0700703
Davide Pesavento14e71f02019-03-28 17:35:25 -0400704 advanceClocks(1_ms, 1000);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700705
706 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
707 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
708 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700709 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000710}
711
Eric Newberry7b0071e2017-07-03 17:33:31 +0000712BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
713{
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400714 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000715 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
716
717 lp::Packet pkt1 = makeFrag(100, 40);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800718 pkt1.add<lp::SequenceField>(123456);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000719 pkt1.add<lp::TxSequenceField>(765432);
720
Eric Newberry32f7eac2020-02-07 14:40:17 -0800721 BOOST_CHECK(reliability->processIncomingPacket(pkt1));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000722
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400723 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000724 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
725 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800726 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
727 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(123456), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000728
729 lp::Packet pkt2 = makeFrag(276, 40);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800730 pkt2.add<lp::SequenceField>(654321);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000731 pkt2.add<lp::TxSequenceField>(234567);
732
Eric Newberry32f7eac2020-02-07 14:40:17 -0800733 BOOST_CHECK(reliability->processIncomingPacket(pkt2));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000734
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400735 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000736 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
737 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
738 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 234567);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800739 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
740 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(123456), 1);
741 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(654321), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000742
743 // T+5ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400744 advanceClocks(1_ms, 5);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400745 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000746}
747
748BOOST_AUTO_TEST_CASE(PiggybackAcks)
749{
750 reliability->m_ackQueue.push(256);
751 reliability->m_ackQueue.push(257);
752 reliability->m_ackQueue.push(10);
753
754 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000755 linkService->sendLpPackets({pkt});
756
757 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Teng Liang13d582a2020-07-21 20:23:11 -0700758 lp::Packet sentPkt(transport->sentPackets.front());
Eric Newberry185ab292017-03-28 06:45:39 +0000759
760 BOOST_REQUIRE_EQUAL(sentPkt.count<lp::AckField>(), 3);
761 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(0), 256);
762 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(1), 257);
763 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(2), 10);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000764 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Eric Newberry185ab292017-03-28 06:45:39 +0000765
766 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
767}
768
769BOOST_AUTO_TEST_CASE(PiggybackAcksMtu)
770{
Eric Newberry32f7eac2020-02-07 14:40:17 -0800771 // MTU is 1500, payload has 60 octets plus 6 octets for LpPacket and Fragment TL and 10 octets
772 // each for Sequence and TxSequence, leaving 1414 octets for piggybacking. Each Ack header is 12
773 // octets, so each LpPacket can carry 117 Acks, and it takes 9 LpPackets for 1000 Acks.
Eric Newberry185ab292017-03-28 06:45:39 +0000774
Eric Newberry7b0071e2017-07-03 17:33:31 +0000775 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000776
Junxiao Shi21e01932018-04-21 10:39:05 +0000777 std::unordered_set<lp::Sequence> expectedAcks;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000778 for (lp::Sequence i = 1000; i < 2000; i++) {
779 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000780 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000781 }
Eric Newberry185ab292017-03-28 06:45:39 +0000782
Junxiao Shi21e01932018-04-21 10:39:05 +0000783 for (uint32_t i = 1; i <= 9; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000784 lp::Packet pkt = makeFrag(i, 60);
785 linkService->sendLpPackets({pkt});
Eric Newberry185ab292017-03-28 06:45:39 +0000786
Junxiao Shi21e01932018-04-21 10:39:05 +0000787 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), i);
Teng Liang13d582a2020-07-21 20:23:11 -0700788 lp::Packet sentPkt(transport->sentPackets.back());
Eric Newberry32f7eac2020-02-07 14:40:17 -0800789 BOOST_CHECK_EQUAL(getPktNum(sentPkt), i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000790 BOOST_CHECK(sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000791
792 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
793 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
794 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000795 }
Eric Newberry185ab292017-03-28 06:45:39 +0000796
Eric Newberry7b0071e2017-07-03 17:33:31 +0000797 BOOST_CHECK(reliability->m_ackQueue.empty());
Junxiao Shi21e01932018-04-21 10:39:05 +0000798 BOOST_CHECK(expectedAcks.empty());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000799}
Eric Newberry185ab292017-03-28 06:45:39 +0000800
Eric Newberry7b0071e2017-07-03 17:33:31 +0000801BOOST_AUTO_TEST_CASE(PiggybackAcksMtuNoSpace)
802{
Eric Newberry32f7eac2020-02-07 14:40:17 -0800803 // MTU is 64, payload has 34 octets plus 4 octets for LpPacket and Fragment TL and 10 octets each
804 // for Sequence and TxSequence, leaving 6 octets for piggybacking. Each Ack header is 12 octets,
805 // so there's no room to piggyback any Ack in LpPacket.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000806
Eric Newberrycb6551e2020-03-02 14:12:16 -0800807 transport->setMtu(MIN_MTU);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000808
809 for (lp::Sequence i = 1000; i < 1100; i++) {
810 reliability->m_ackQueue.push(i);
811 }
812
Eric Newberry32f7eac2020-02-07 14:40:17 -0800813 lp::Packet pkt = makeFrag(1, 34);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000814 linkService->sendLpPackets({pkt});
815
Eric Newberry185ab292017-03-28 06:45:39 +0000816 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Teng Liang13d582a2020-07-21 20:23:11 -0700817 lp::Packet sentPkt(transport->sentPackets.back());
Eric Newberry32f7eac2020-02-07 14:40:17 -0800818 BOOST_CHECK_EQUAL(getPktNum(sentPkt), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000819 BOOST_CHECK(!sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000820
821 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 100);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000822}
Eric Newberry185ab292017-03-28 06:45:39 +0000823
Eric Newberry7b0071e2017-07-03 17:33:31 +0000824BOOST_AUTO_TEST_CASE(StartIdleAckTimer)
825{
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400826 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000827
Eric Newberry7b0071e2017-07-03 17:33:31 +0000828 lp::Packet pkt1 = makeFrag(1, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800829 pkt1.add<lp::SequenceField>(1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000830 pkt1.add<lp::TxSequenceField>(12);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800831 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400832 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000833
Eric Newberry7b0071e2017-07-03 17:33:31 +0000834 // T+1ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400835 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400836 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000837
Eric Newberry7b0071e2017-07-03 17:33:31 +0000838 lp::Packet pkt2 = makeFrag(2, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800839 pkt2.add<lp::SequenceField>(2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000840 pkt2.add<lp::TxSequenceField>(13);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800841 BOOST_CHECK(reliability->processIncomingPacket({pkt2}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400842 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000843
Eric Newberry7b0071e2017-07-03 17:33:31 +0000844 // T+5ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400845 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400846 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000847
Eric Newberry7b0071e2017-07-03 17:33:31 +0000848 lp::Packet pkt3 = makeFrag(3, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800849 pkt3.add<lp::SequenceField>(3);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000850 pkt3.add<lp::TxSequenceField>(15);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800851 BOOST_CHECK(reliability->processIncomingPacket({pkt3}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400852 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000853
Eric Newberry7b0071e2017-07-03 17:33:31 +0000854 // T+9ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400855 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400856 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000857
Eric Newberry7b0071e2017-07-03 17:33:31 +0000858 // T+10ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400859 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400860 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000861}
862
863BOOST_AUTO_TEST_CASE(IdleAckTimer)
864{
Junxiao Shi21e01932018-04-21 10:39:05 +0000865 // T+0ms: populate ack queue and start idle ack timer
866 std::unordered_set<lp::Sequence> expectedAcks;
867 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000868 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000869 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000870 }
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400871 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000872 reliability->startIdleAckTimer();
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400873 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000874
Junxiao Shi21e01932018-04-21 10:39:05 +0000875 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400876 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400877 BOOST_CHECK(reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000878 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000879 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
Junxiao Shi21e01932018-04-21 10:39:05 +0000880 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000881 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
882
Junxiao Shi21e01932018-04-21 10:39:05 +0000883 // T+5ms: idle ack timer expires, IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400884 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400885 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000886 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000887 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry185ab292017-03-28 06:45:39 +0000888
Teng Liang13d582a2020-07-21 20:23:11 -0700889 lp::Packet sentPkt(transport->sentPackets.back());
Junxiao Shi21e01932018-04-21 10:39:05 +0000890 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
891 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
892 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000893 }
Junxiao Shi21e01932018-04-21 10:39:05 +0000894 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000895}
896
897BOOST_AUTO_TEST_CASE(IdleAckTimerMtu)
898{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000899 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000900
Junxiao Shi21e01932018-04-21 10:39:05 +0000901 // T+0ms: populate ack queue and start idle ack timer
902 std::unordered_set<lp::Sequence> expectedAcks;
903 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000904 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000905 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000906 }
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400907 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000908 reliability->startIdleAckTimer();
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400909 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000910
Junxiao Shi21e01932018-04-21 10:39:05 +0000911 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400912 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400913 BOOST_CHECK(reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000914 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
915 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
916 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000917 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
918
Junxiao Shi21e01932018-04-21 10:39:05 +0000919 // T+5ms: idle ack timer expires, IDLE packets generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400920 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400921 BOOST_CHECK(!reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000922 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000923
Junxiao Shi21e01932018-04-21 10:39:05 +0000924 // MTU is 1500. LpPacket TL occupies 4 octets. Each Ack header is 12 octets. There are room for
925 // 124 Acks per LpPacket, and it takes 5 LpPackets to carry 500 Acks.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000926 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Junxiao Shi21e01932018-04-21 10:39:05 +0000927 for (size_t i = 0; i < 5; i++) {
Teng Liang13d582a2020-07-21 20:23:11 -0700928 lp::Packet sentPkt(transport->sentPackets[i]);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000929 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000930 BOOST_CHECK_EQUAL(sentPkt.count<lp::AckField>(), i == 4 ? 4 : 124);
931 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
932 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
933 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000934 }
935
Junxiao Shi21e01932018-04-21 10:39:05 +0000936 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000937}
938
Eric Newberry32f7eac2020-02-07 14:40:17 -0800939BOOST_AUTO_TEST_CASE(TrackRecentReceivedLpPackets)
940{
941 lp::Packet pkt1 = makeFrag(1, 100);
942 pkt1.add<lp::SequenceField>(7);
943 pkt1.add<lp::TxSequenceField>(12);
944 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
945 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 1);
946 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 7);
947 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
948 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
949
950 // T+500ms
951 // Estimated RTO starts at 1000ms and we are not adding any measurements, so it should remain
952 // this value throughout the test case
953 advanceClocks(500_ms, 1);
954 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
955 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
956 lp::Packet pkt2 = makeFrag(1, 100);
957 pkt2.add<lp::SequenceField>(23);
958 pkt2.add<lp::TxSequenceField>(13);
959 BOOST_CHECK(reliability->processIncomingPacket({pkt2}));
960 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
961 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 7);
962 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
963 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
964 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(23), 1);
965
966 // T+1250ms
967 // First received sequence should be removed after next received packet, but second should remain
968 advanceClocks(750_ms, 1);
969 lp::Packet pkt3 = makeFrag(1, 100);
970 pkt3.add<lp::SequenceField>(24);
971 pkt3.add<lp::TxSequenceField>(14);
972 BOOST_CHECK(reliability->processIncomingPacket({pkt3}));
973 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
974 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 23);
975 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
976 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(23), 1);
977 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(24), 1);
978
979 // T+1750ms
980 // Second received sequence should be removed
981 advanceClocks(500_ms, 1);
982 lp::Packet pkt4 = makeFrag(1, 100);
983 pkt4.add<lp::SequenceField>(25);
984 pkt4.add<lp::TxSequenceField>(15);
985 BOOST_CHECK(reliability->processIncomingPacket({pkt4}));
986 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
987 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 24);
988 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
989 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(24), 1);
990 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(25), 1);
991}
992
993BOOST_AUTO_TEST_CASE(DropDuplicateReceivedSequence)
994{
995 Interest interest("/test/prefix");
Eric Newberry32f7eac2020-02-07 14:40:17 -0800996 lp::Packet pkt1;
997 pkt1.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
998 pkt1.add<lp::SequenceField>(7);
999 pkt1.add<lp::TxSequenceField>(12);
1000 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
1001 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
1002 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
1003
1004 lp::Packet pkt2;
1005 pkt2.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
1006 pkt2.add<lp::SequenceField>(7);
1007 pkt2.add<lp::TxSequenceField>(13);
1008 BOOST_CHECK(!reliability->processIncomingPacket({pkt2}));
1009 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
1010 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
1011}
1012
1013BOOST_AUTO_TEST_CASE(DropDuplicateAckForRetx)
1014{
1015 lp::Packet pkt1 = makeFrag(1024, 50);
1016 linkService->sendLpPackets({pkt1});
1017
1018 // Will send out a single fragment
1019 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
1020 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
1021 lp::Sequence firstTxSeq = reliability->m_firstUnackedFrag->first;
1022
1023 // RTO is initially 1 second, so will time out and retx
1024 advanceClocks(1250_ms, 1);
1025 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
1026 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
1027
1028 // Acknowledge first transmission (RTO underestimation)
1029 // Ack will be dropped because unknown
1030 lp::Packet ackPkt1;
1031 ackPkt1.add<lp::AckField>(firstTxSeq);
1032 reliability->processIncomingPacket(ackPkt1);
1033 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.size(), 1); // Required because collection used below
1034
1035 // Acknowledge second transmission
1036 // Ack will acknowledge retx and remove unacked frag
1037 lp::Packet ackPkt2;
1038 ackPkt2.add<lp::AckField>(reliability->m_firstUnackedFrag->first);
1039 reliability->processIncomingPacket(ackPkt2);
1040 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
1041}
1042
Eric Newberry7b0071e2017-07-03 17:33:31 +00001043BOOST_AUTO_TEST_SUITE_END() // TestLpReliability
Eric Newberry185ab292017-03-28 06:45:39 +00001044BOOST_AUTO_TEST_SUITE_END() // Face
1045
1046} // namespace tests
1047} // namespace face
1048} // namespace nfd