blob: 81c28e03e458ec358d780af1fd50d8f9d5ee2be4 [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
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040038namespace nfd::tests {
Eric Newberry185ab292017-03-28 06:45:39 +000039
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040040using namespace nfd::face;
Eric Newberry185ab292017-03-28 06:45:39 +000041
Eric Newberry185ab292017-03-28 06:45:39 +000042class DummyLpReliabilityLinkService : public GenericLinkService
43{
44public:
45 LpReliability*
46 getLpReliability()
47 {
48 return &m_reliability;
49 }
50
51 void
52 sendLpPackets(std::vector<lp::Packet> frags)
53 {
54 if (frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -070055 Interest interest("/test/prefix");
56 lp::Packet pkt;
Davide Pesaventof190cfa2019-07-17 20:14:11 -040057 pkt.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
Eric Newberry32f7eac2020-02-07 14:40:17 -080058 assignSequences(frags);
Eric Newberry41aba102017-11-01 16:42:13 -070059 m_reliability.handleOutgoing(frags, std::move(pkt), true);
Eric Newberry185ab292017-03-28 06:45:39 +000060 }
61
Davide Pesaventof190cfa2019-07-17 20:14:11 -040062 for (auto frag : frags) {
Teng Liangf3bc3ae2020-06-08 10:19:25 -070063 this->sendLpPacket(std::move(frag));
Eric Newberry185ab292017-03-28 06:45:39 +000064 }
65 }
66
67private:
68 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070069 doSendInterest(const Interest&) final
Eric Newberry185ab292017-03-28 06:45:39 +000070 {
Davide Pesavento5a897692019-10-31 01:28:43 -040071 BOOST_FAIL("unexpected doSendInterest");
Eric Newberry185ab292017-03-28 06:45:39 +000072 }
73
74 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070075 doSendData(const Data&) final
Eric Newberry185ab292017-03-28 06:45:39 +000076 {
Davide Pesavento5a897692019-10-31 01:28:43 -040077 BOOST_FAIL("unexpected doSendData");
Eric Newberry185ab292017-03-28 06:45:39 +000078 }
79
80 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070081 doSendNack(const lp::Nack&) final
Eric Newberry185ab292017-03-28 06:45:39 +000082 {
Davide Pesavento5a897692019-10-31 01:28:43 -040083 BOOST_FAIL("unexpected doSendNack");
Eric Newberry185ab292017-03-28 06:45:39 +000084 }
85
86 void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040087 doReceivePacket(const Block&, const EndpointId&) final
Eric Newberry185ab292017-03-28 06:45:39 +000088 {
Davide Pesavento5a897692019-10-31 01:28:43 -040089 BOOST_FAIL("unexpected doReceivePacket");
Eric Newberry185ab292017-03-28 06:45:39 +000090 }
91};
92
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040093class LpReliabilityFixture : public GlobalIoTimeFixture
Eric Newberry185ab292017-03-28 06:45:39 +000094{
95public:
96 LpReliabilityFixture()
97 : linkService(make_unique<DummyLpReliabilityLinkService>())
98 , transport(make_unique<DummyTransport>())
99 , face(make_unique<DummyFace>())
100 {
101 linkService->setFaceAndTransport(*face, *transport);
102 transport->setFaceAndLinkService(*face, *linkService);
103
104 GenericLinkService::Options options;
105 options.reliabilityOptions.isEnabled = true;
106 linkService->setOptions(options);
107
108 reliability = linkService->getLpReliability();
Eric Newberry7b0071e2017-07-03 17:33:31 +0000109 reliability->m_lastTxSeqNo = 1;
110 }
111
112 static bool
113 netPktHasUnackedFrag(const shared_ptr<LpReliability::NetPkt>& netPkt, lp::Sequence txSeq)
114 {
115 return std::any_of(netPkt->unackedFrags.begin(), netPkt->unackedFrags.end(),
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400116 [txSeq] (auto fragIt) { return fragIt->first == txSeq; });
Eric Newberry7b0071e2017-07-03 17:33:31 +0000117 }
118
Eric Newberry7b0071e2017-07-03 17:33:31 +0000119 /** \brief make an LpPacket with fragment of specified size
Eric Newberry32f7eac2020-02-07 14:40:17 -0800120 * \param pktNum packet identifier, which can be extracted with \p getPktNum
Davide Pesaventob93fb6c2020-04-12 14:10:45 -0400121 * \param payloadSize total payload size; must be >= 4 and <= 255
Eric Newberry7b0071e2017-07-03 17:33:31 +0000122 */
123 static lp::Packet
Eric Newberry32f7eac2020-02-07 14:40:17 -0800124 makeFrag(uint32_t pktNum, size_t payloadSize = 4)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000125 {
Davide Pesaventob93fb6c2020-04-12 14:10:45 -0400126 BOOST_ASSERT(payloadSize >= 4 && payloadSize <= 255);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000127 lp::Packet pkt;
128 ndn::Buffer buf(payloadSize);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800129 std::memcpy(buf.data(), &pktNum, sizeof(pktNum));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400130 pkt.set<lp::FragmentField>({buf.cbegin(), buf.cend()});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000131 return pkt;
132 }
133
134 /** \brief extract packet identifier from LpPacket made with \p makeFrag
135 * \retval 0 packet identifier cannot be extracted
136 */
137 static uint32_t
Eric Newberry32f7eac2020-02-07 14:40:17 -0800138 getPktNum(const lp::Packet& pkt)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000139 {
Davide Pesaventob93fb6c2020-04-12 14:10:45 -0400140 BOOST_REQUIRE(pkt.has<lp::FragmentField>());
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400141 auto [begin, end] = pkt.get<lp::FragmentField>();
Eric Newberry7b0071e2017-07-03 17:33:31 +0000142 if (std::distance(begin, end) < 4) {
143 return 0;
144 }
145
146 uint32_t value = 0;
147 std::memcpy(&value, &*begin, sizeof(value));
148 return value;
Eric Newberry185ab292017-03-28 06:45:39 +0000149 }
150
Eric Newberry971d9622018-03-30 23:29:26 -0700151protected:
Eric Newberry185ab292017-03-28 06:45:39 +0000152 unique_ptr<DummyLpReliabilityLinkService> linkService;
153 unique_ptr<DummyTransport> transport;
154 unique_ptr<DummyFace> face;
155 LpReliability* reliability;
156};
157
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400158BOOST_AUTO_TEST_SUITE(Face)
Eric Newberry185ab292017-03-28 06:45:39 +0000159BOOST_FIXTURE_TEST_SUITE(TestLpReliability, LpReliabilityFixture)
160
161BOOST_AUTO_TEST_CASE(SendNoFragmentField)
162{
163 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000164
165 linkService->sendLpPackets({pkt});
166 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000167 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700168 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
169 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
170 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700171 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000172}
173
Eric Newberry7b0071e2017-07-03 17:33:31 +0000174BOOST_AUTO_TEST_CASE(SendUnfragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000175{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000176 lp::Packet pkt1 = makeFrag(1024, 50);
177 lp::Packet pkt2 = makeFrag(3000, 30);
Eric Newberry185ab292017-03-28 06:45:39 +0000178
179 linkService->sendLpPackets({pkt1});
Eric Newberry971d9622018-03-30 23:29:26 -0700180 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Teng Liang13d582a2020-07-21 20:23:11 -0700181 lp::Packet cached1(transport->sentPackets.front());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000182 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
Eric Newberry32f7eac2020-02-07 14:40:17 -0800183 BOOST_CHECK(cached1.has<lp::SequenceField>());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000184 lp::Sequence firstTxSeq = cached1.get<lp::TxSequenceField>();
Eric Newberry971d9622018-03-30 23:29:26 -0700185 BOOST_CHECK_EQUAL(firstTxSeq, 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800186 BOOST_CHECK_EQUAL(getPktNum(cached1), 1024);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700187 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
188 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
189 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700190 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000191
Eric Newberry185ab292017-03-28 06:45:39 +0000192 // T+500ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000193 // 1024 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400194 advanceClocks(1_ms, 500);
Eric Newberry185ab292017-03-28 06:45:39 +0000195 linkService->sendLpPackets({pkt2});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000196 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
Eric Newberry185ab292017-03-28 06:45:39 +0000197
Eric Newberry00d39fd2017-12-10 14:26:45 -0700198 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
199 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 1);
200 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000201 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq).netPkt);
202 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
203 BOOST_CHECK_NE(reliability->m_unackedFrags.at(firstTxSeq).netPkt,
Eric Newberry971d9622018-03-30 23:29:26 -0700204 reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000205 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).retxCount, 0);
206 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
207 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq);
208 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700209 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
210 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
211 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700212 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000213
214 // T+1250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000215 // 1024 rto: 1000ms, txSeq: 4, started T+1000ms, retx 1
216 // 3000 rto: 1000ms, txSeq: 3, started T+500ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400217 advanceClocks(1_ms, 750);
Eric Newberry185ab292017-03-28 06:45:39 +0000218
Eric Newberry00d39fd2017-12-10 14:26:45 -0700219 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000220 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700221 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000222 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 2).retxCount, 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700223 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000224 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
225 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 1);
226 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700227 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
228 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
229 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700230 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000231
232 // T+2250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000233 // 1024 rto: 1000ms, txSeq: 6, started T+2000ms, retx 2
234 // 3000 rto: 1000ms, txSeq: 5, started T+1500ms, retx 1
Davide Pesavento14e71f02019-03-28 17:35:25 -0400235 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000236
Eric Newberry00d39fd2017-12-10 14:26:45 -0700237 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000238 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 0);
239 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700240 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000241 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 4).retxCount, 2);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700242 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000243 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 3).retxCount, 1);
244 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 3);
245 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700246 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
247 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
248 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700249 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000250
251 // T+3250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000252 // 1024 rto: 1000ms, txSeq: 8, started T+3000ms, retx 3
253 // 3000 rto: 1000ms, txSeq: 7, started T+2500ms, retx 2
Davide Pesavento14e71f02019-03-28 17:35:25 -0400254 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000255
Eric Newberry00d39fd2017-12-10 14:26:45 -0700256 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000257 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 0);
258 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700259 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000260 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 6).retxCount, 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700261 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000262 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 5).retxCount, 2);
263 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 5);
264 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 7);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700265 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
266 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
267 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700268 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000269
270 // T+4250ms
271 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000272 // 3000 rto: 1000ms, txSeq: 9, started T+3500ms, retx 3
Davide Pesavento14e71f02019-03-28 17:35:25 -0400273 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000274
Eric Newberry00d39fd2017-12-10 14:26:45 -0700275 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000276 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 0);
277 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700278 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 7), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000279 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 7).retxCount, 3);
280 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 7);
281 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry185ab292017-03-28 06:45:39 +0000282
Eric Newberry00d39fd2017-12-10 14:26:45 -0700283 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
284 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
285 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 1);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700286 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 1);
Eric Newberry41aba102017-11-01 16:42:13 -0700287
Eric Newberry185ab292017-03-28 06:45:39 +0000288 // T+4750ms
289 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000290 // 3000 rto: expired, removed
Davide Pesavento14e71f02019-03-28 17:35:25 -0400291 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000292
293 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000294 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
295 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700296 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
297 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
298 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 2);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700299 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 2);
Eric Newberry185ab292017-03-28 06:45:39 +0000300}
301
Eric Newberry7b0071e2017-07-03 17:33:31 +0000302BOOST_AUTO_TEST_CASE(SendFragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000303{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000304 lp::Packet pkt1 = makeFrag(2048, 30);
305 lp::Packet pkt2 = makeFrag(2049, 30);
306 lp::Packet pkt3 = makeFrag(2050, 10);
Eric Newberry185ab292017-03-28 06:45:39 +0000307
Eric Newberry7b0071e2017-07-03 17:33:31 +0000308 linkService->sendLpPackets({pkt1, pkt2, pkt3});
309 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000310
Teng Liang13d582a2020-07-21 20:23:11 -0700311 lp::Packet cached1(transport->sentPackets.at(0));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000312 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
313 BOOST_CHECK_EQUAL(cached1.get<lp::TxSequenceField>(), 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800314 BOOST_CHECK(cached1.has<lp::SequenceField>());
315 BOOST_CHECK_EQUAL(getPktNum(cached1), 2048);
Teng Liang13d582a2020-07-21 20:23:11 -0700316 lp::Packet cached2(transport->sentPackets.at(1));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000317 BOOST_REQUIRE(cached2.has<lp::TxSequenceField>());
318 BOOST_CHECK_EQUAL(cached2.get<lp::TxSequenceField>(), 3);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800319 BOOST_CHECK(cached2.has<lp::SequenceField>());
320 BOOST_CHECK_EQUAL(getPktNum(cached2), 2049);
Teng Liang13d582a2020-07-21 20:23:11 -0700321 lp::Packet cached3(transport->sentPackets.at(2));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000322 BOOST_REQUIRE(cached3.has<lp::TxSequenceField>());
323 BOOST_CHECK_EQUAL(cached3.get<lp::TxSequenceField>(), 4);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800324 BOOST_CHECK(cached3.has<lp::SequenceField>());
325 BOOST_CHECK_EQUAL(getPktNum(cached3), 2050);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700326 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
327 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
328 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700329 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000330
Eric Newberry7b0071e2017-07-03 17:33:31 +0000331 // T+0ms
332 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
333 // 2049 rto: 1000ms, txSeq: 3, started T+0ms, retx 0
334 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Eric Newberry185ab292017-03-28 06:45:39 +0000335
Eric Newberry00d39fd2017-12-10 14:26:45 -0700336 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
337 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1);
338 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800339 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
340 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(3).pkt), 2049);
341 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000342 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
343 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
344 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
345 BOOST_REQUIRE(reliability->m_unackedFrags.at(3).netPkt);
346 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
347 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
348 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(3).netPkt);
349 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
350 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
351 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
352 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
353 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
354 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
355 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
356 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700357 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
358 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
359 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700360 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000361
Eric Newberry7b0071e2017-07-03 17:33:31 +0000362 // T+250ms
363 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
364 // 2049 rto: 1000ms, txSeq: 5, started T+250ms, retx 1
365 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400366 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800367 reliability->onLpPacketLost(3, true);
Eric Newberry185ab292017-03-28 06:45:39 +0000368
Eric Newberry00d39fd2017-12-10 14:26:45 -0700369 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000370 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700371 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 1);
372 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800373 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
374 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(5).pkt), 2049);
375 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000376 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
377 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
378 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(5).retxCount, 1);
379 BOOST_REQUIRE(reliability->m_unackedFrags.at(5).netPkt);
380 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
381 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
382 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(5).netPkt);
383 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
384 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
385 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
386 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
387 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
388 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
389 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
390 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700391 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
392 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
393 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700394 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000395
396 // T+500ms
397 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
398 // 2049 rto: 1000ms, txSeq: 6, started T+500ms, retx 2
399 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400400 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800401 reliability->onLpPacketLost(5, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000402
Eric Newberry00d39fd2017-12-10 14:26:45 -0700403 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000404 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700405 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 1);
406 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800407 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
408 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(6).pkt), 2049);
409 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000410 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
411 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
412 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(6).retxCount, 2);
413 BOOST_REQUIRE(reliability->m_unackedFrags.at(6).netPkt);
414 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
415 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
416 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(6).netPkt);
417 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
418 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
419 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
420 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
421 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
422 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
423 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
424 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700425 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
426 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
427 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700428 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000429
430 // T+750ms
431 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
432 // 2049 rto: 1000ms, txSeq: 7, started T+750ms, retx 3
433 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400434 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800435 reliability->onLpPacketLost(6, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000436
437 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 1);
438 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700439 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(7), 1);
440 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800441 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
442 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(7).pkt), 2049);
443 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000444 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
445 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
446 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(7).retxCount, 3);
447 BOOST_REQUIRE(reliability->m_unackedFrags.at(7).netPkt);
448 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
449 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
450 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(7).netPkt);
451 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
452 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
453 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
454 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
455 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 7));
456 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
457 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
458 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700459 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
460 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
461 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700462 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000463
464 // T+850ms
465 // 2048 rto: expired, removed
466 // 2049 rto: expired, removed
467 // 2050 rto: expired, removed
Davide Pesavento14e71f02019-03-28 17:35:25 -0400468 advanceClocks(1_ms, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800469 reliability->onLpPacketLost(7, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000470
471 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
472 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700473 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
474 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
475 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 1);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700476 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000477}
478
Eric Newberry00d39fd2017-12-10 14:26:45 -0700479BOOST_AUTO_TEST_CASE(AckUnknownTxSeq)
480{
481 linkService->sendLpPackets({makeFrag(1, 50)});
482
483 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
484 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
485 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
486 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
487 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
488 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
489 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
490 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700491 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700492
493 lp::Packet ackPkt;
494 ackPkt.add<lp::AckField>(10101010);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800495 BOOST_CHECK(reliability->processIncomingPacket(ackPkt));
Eric Newberry00d39fd2017-12-10 14:26:45 -0700496
497 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
498 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
499 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
500 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
501 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
502 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
503 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
504 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700505 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700506}
507
Eric Newberry971d9622018-03-30 23:29:26 -0700508BOOST_AUTO_TEST_CASE(LossByGreaterAcks)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000509{
Eric Newberry971d9622018-03-30 23:29:26 -0700510 // Detect loss by 3x greater Acks, also tests wraparound
511
Eric Newberry7b0071e2017-07-03 17:33:31 +0000512 reliability->m_lastTxSeqNo = 0xFFFFFFFFFFFFFFFE;
513
Eric Newberry971d9622018-03-30 23:29:26 -0700514 // Passed to sendLpPackets individually since they are
515 // from separate, non-fragmented network packets
Eric Newberry7b0071e2017-07-03 17:33:31 +0000516 linkService->sendLpPackets({makeFrag(1, 50)});
517 linkService->sendLpPackets({makeFrag(2, 50)});
518 linkService->sendLpPackets({makeFrag(3, 50)});
519 linkService->sendLpPackets({makeFrag(4, 50)});
520 linkService->sendLpPackets({makeFrag(5, 50)});
Eric Newberry185ab292017-03-28 06:45:39 +0000521
522 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000523 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
524 BOOST_CHECK(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).netPkt);
525 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 1); // pkt2
526 BOOST_CHECK(reliability->m_unackedFrags.at(0).netPkt);
527 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
528 BOOST_CHECK(reliability->m_unackedFrags.at(1).netPkt);
529 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
530 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
531 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
532 BOOST_CHECK(reliability->m_unackedFrags.at(3).netPkt);
Eric Newberry185ab292017-03-28 06:45:39 +0000533 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700534 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
535 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
536 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700537 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000538
539 lp::Packet ackPkt1;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000540 ackPkt1.add<lp::AckField>(0);
Eric Newberry185ab292017-03-28 06:45:39 +0000541
542 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
543
Eric Newberry32f7eac2020-02-07 14:40:17 -0800544 BOOST_CHECK(reliability->processIncomingPacket(ackPkt1));
Eric Newberry185ab292017-03-28 06:45:39 +0000545
546 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700547 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000548 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
549 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000550 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700551 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000552 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
553 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700554 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
Eric Newberry7b0071e2017-07-03 17:33:31 +0000555 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
556 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700557 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000558 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
559 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000560 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000561 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700562 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
563 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
564 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700565 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000566
567 lp::Packet ackPkt2;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000568 ackPkt2.add<lp::AckField>(2);
569 ackPkt1.add<lp::AckField>(101010); // Unknown TxSequence number - ignored
Eric Newberry185ab292017-03-28 06:45:39 +0000570
571 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
572
Eric Newberry32f7eac2020-02-07 14:40:17 -0800573 BOOST_CHECK(reliability->processIncomingPacket(ackPkt2));
Eric Newberry185ab292017-03-28 06:45:39 +0000574
575 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000576 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000577 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
578 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000579 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700580 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000581 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
582 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700583 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
584 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000585 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
586 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
587 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(101010), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000588 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000589 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700590 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 2);
591 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
592 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700593 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000594
595 lp::Packet ackPkt3;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000596 ackPkt3.add<lp::AckField>(1);
Eric Newberry185ab292017-03-28 06:45:39 +0000597
598 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
599
Eric Newberry32f7eac2020-02-07 14:40:17 -0800600 BOOST_CHECK(reliability->processIncomingPacket(ackPkt3));
Eric Newberry185ab292017-03-28 06:45:39 +0000601
602 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000603 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
604 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
605 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
606 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700607 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000608 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
609 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700610 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1); // pkt1 new TxSeq
Eric Newberry7b0071e2017-07-03 17:33:31 +0000611 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 1);
612 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).nGreaterSeqAcks, 0);
613 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000614 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Teng Liang13d582a2020-07-21 20:23:11 -0700615 lp::Packet sentRetxPkt(transport->sentPackets.back());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000616 BOOST_REQUIRE(sentRetxPkt.has<lp::TxSequenceField>());
617 BOOST_CHECK_EQUAL(sentRetxPkt.get<lp::TxSequenceField>(), 4);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800618 BOOST_CHECK_EQUAL(getPktNum(sentRetxPkt), 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700619 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
620 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
621 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700622 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000623
624 lp::Packet ackPkt4;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000625 ackPkt4.add<lp::AckField>(4);
Eric Newberry185ab292017-03-28 06:45:39 +0000626
627 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
628
Eric Newberry32f7eac2020-02-07 14:40:17 -0800629 BOOST_CHECK(reliability->processIncomingPacket(ackPkt4));
Eric Newberry185ab292017-03-28 06:45:39 +0000630
631 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000632 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
633 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
634 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
635 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700636 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000637 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
638 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 1);
639 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 0); // pkt1 new TxSeq
640 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000641 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700642 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
643 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 1);
644 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700645 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700646}
647
Eric Newberry971d9622018-03-30 23:29:26 -0700648BOOST_AUTO_TEST_CASE(SkipFragmentsRemovedInRtt)
649{
650 auto opts = linkService->getOptions();
651 opts.reliabilityOptions.maxRetx = 0; // just to make the test case shorter
652 opts.reliabilityOptions.seqNumLossThreshold = 3;
653 linkService->setOptions(opts);
654
655 lp::Packet frag1 = makeFrag(5001);
656 lp::Packet frag2 = makeFrag(5002);
657 linkService->sendLpPackets({frag1, frag2}); // First packet has 2 fragments
658 linkService->sendLpPackets({makeFrag(5003)});
659 linkService->sendLpPackets({makeFrag(5004)});
660 linkService->sendLpPackets({makeFrag(5005)});
661
662 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
663 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
664
665 lp::Sequence firstTxSeq = reliability->m_firstUnackedFrag->first;
666
667 // Ack the last 2 packets
668 lp::Packet ackPkt1;
669 ackPkt1.add<lp::AckField>(firstTxSeq + 4);
670 ackPkt1.add<lp::AckField>(firstTxSeq + 3);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800671 BOOST_CHECK(reliability->processIncomingPacket(ackPkt1));
Eric Newberry971d9622018-03-30 23:29:26 -0700672
673 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
674 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).nGreaterSeqAcks, 2);
675 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).nGreaterSeqAcks, 2);
676
677 // Ack the third packet (5003)
678 // This triggers a "loss by greater Acks" for packets 5001 and 5002
679 lp::Packet ackPkt2;
680 ackPkt2.add<lp::AckField>(firstTxSeq + 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800681 BOOST_CHECK(reliability->processIncomingPacket(ackPkt2)); // tests crash/assert reported in bug #4479
Eric Newberry971d9622018-03-30 23:29:26 -0700682
683 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
684}
685
Eric Newberry00d39fd2017-12-10 14:26:45 -0700686BOOST_AUTO_TEST_CASE(CancelLossNotificationOnAck)
687{
688 reliability->onDroppedInterest.connect([] (const Interest&) {
689 BOOST_FAIL("Packet loss timeout should be cancelled when packet acknowledged");
690 });
691
692 reliability->m_lastTxSeqNo = 0;
693
694 linkService->sendLpPackets({makeFrag(1, 50)});
695
Davide Pesavento14e71f02019-03-28 17:35:25 -0400696 advanceClocks(1_ms, 500);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700697
698 lp::Packet ackPkt;
699 ackPkt.add<lp::AckField>(1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800700 BOOST_CHECK(reliability->processIncomingPacket(ackPkt));
Eric Newberry00d39fd2017-12-10 14:26:45 -0700701
Davide Pesavento14e71f02019-03-28 17:35:25 -0400702 advanceClocks(1_ms, 1000);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700703
704 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
705 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
706 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700707 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000708}
709
Eric Newberry7b0071e2017-07-03 17:33:31 +0000710BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
711{
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400712 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000713 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
714
715 lp::Packet pkt1 = makeFrag(100, 40);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800716 pkt1.add<lp::SequenceField>(123456);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000717 pkt1.add<lp::TxSequenceField>(765432);
718
Eric Newberry32f7eac2020-02-07 14:40:17 -0800719 BOOST_CHECK(reliability->processIncomingPacket(pkt1));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000720
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400721 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000722 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
723 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800724 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
725 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(123456), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000726
727 lp::Packet pkt2 = makeFrag(276, 40);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800728 pkt2.add<lp::SequenceField>(654321);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000729 pkt2.add<lp::TxSequenceField>(234567);
730
Eric Newberry32f7eac2020-02-07 14:40:17 -0800731 BOOST_CHECK(reliability->processIncomingPacket(pkt2));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000732
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400733 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000734 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
735 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
736 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 234567);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800737 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
738 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(123456), 1);
739 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(654321), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000740
741 // T+5ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400742 advanceClocks(1_ms, 5);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400743 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000744}
745
746BOOST_AUTO_TEST_CASE(PiggybackAcks)
747{
748 reliability->m_ackQueue.push(256);
749 reliability->m_ackQueue.push(257);
750 reliability->m_ackQueue.push(10);
751
752 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000753 linkService->sendLpPackets({pkt});
754
755 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Teng Liang13d582a2020-07-21 20:23:11 -0700756 lp::Packet sentPkt(transport->sentPackets.front());
Eric Newberry185ab292017-03-28 06:45:39 +0000757
758 BOOST_REQUIRE_EQUAL(sentPkt.count<lp::AckField>(), 3);
759 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(0), 256);
760 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(1), 257);
761 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(2), 10);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000762 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Eric Newberry185ab292017-03-28 06:45:39 +0000763
764 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
765}
766
767BOOST_AUTO_TEST_CASE(PiggybackAcksMtu)
768{
Eric Newberry32f7eac2020-02-07 14:40:17 -0800769 // MTU is 1500, payload has 60 octets plus 6 octets for LpPacket and Fragment TL and 10 octets
770 // each for Sequence and TxSequence, leaving 1414 octets for piggybacking. Each Ack header is 12
771 // octets, so each LpPacket can carry 117 Acks, and it takes 9 LpPackets for 1000 Acks.
Eric Newberry185ab292017-03-28 06:45:39 +0000772
Eric Newberry7b0071e2017-07-03 17:33:31 +0000773 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000774
Junxiao Shi21e01932018-04-21 10:39:05 +0000775 std::unordered_set<lp::Sequence> expectedAcks;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000776 for (lp::Sequence i = 1000; i < 2000; i++) {
777 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000778 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000779 }
Eric Newberry185ab292017-03-28 06:45:39 +0000780
Junxiao Shi21e01932018-04-21 10:39:05 +0000781 for (uint32_t i = 1; i <= 9; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000782 lp::Packet pkt = makeFrag(i, 60);
783 linkService->sendLpPackets({pkt});
Eric Newberry185ab292017-03-28 06:45:39 +0000784
Junxiao Shi21e01932018-04-21 10:39:05 +0000785 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), i);
Teng Liang13d582a2020-07-21 20:23:11 -0700786 lp::Packet sentPkt(transport->sentPackets.back());
Eric Newberry32f7eac2020-02-07 14:40:17 -0800787 BOOST_CHECK_EQUAL(getPktNum(sentPkt), i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000788 BOOST_CHECK(sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000789
790 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
791 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
792 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000793 }
Eric Newberry185ab292017-03-28 06:45:39 +0000794
Eric Newberry7b0071e2017-07-03 17:33:31 +0000795 BOOST_CHECK(reliability->m_ackQueue.empty());
Junxiao Shi21e01932018-04-21 10:39:05 +0000796 BOOST_CHECK(expectedAcks.empty());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000797}
Eric Newberry185ab292017-03-28 06:45:39 +0000798
Eric Newberry7b0071e2017-07-03 17:33:31 +0000799BOOST_AUTO_TEST_CASE(PiggybackAcksMtuNoSpace)
800{
Eric Newberry32f7eac2020-02-07 14:40:17 -0800801 // MTU is 64, payload has 34 octets plus 4 octets for LpPacket and Fragment TL and 10 octets each
802 // for Sequence and TxSequence, leaving 6 octets for piggybacking. Each Ack header is 12 octets,
803 // so there's no room to piggyback any Ack in LpPacket.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000804
Eric Newberrycb6551e2020-03-02 14:12:16 -0800805 transport->setMtu(MIN_MTU);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000806
807 for (lp::Sequence i = 1000; i < 1100; i++) {
808 reliability->m_ackQueue.push(i);
809 }
810
Eric Newberry32f7eac2020-02-07 14:40:17 -0800811 lp::Packet pkt = makeFrag(1, 34);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000812 linkService->sendLpPackets({pkt});
813
Eric Newberry185ab292017-03-28 06:45:39 +0000814 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Teng Liang13d582a2020-07-21 20:23:11 -0700815 lp::Packet sentPkt(transport->sentPackets.back());
Eric Newberry32f7eac2020-02-07 14:40:17 -0800816 BOOST_CHECK_EQUAL(getPktNum(sentPkt), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000817 BOOST_CHECK(!sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000818
819 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 100);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000820}
Eric Newberry185ab292017-03-28 06:45:39 +0000821
Eric Newberry7b0071e2017-07-03 17:33:31 +0000822BOOST_AUTO_TEST_CASE(StartIdleAckTimer)
823{
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400824 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000825
Eric Newberry7b0071e2017-07-03 17:33:31 +0000826 lp::Packet pkt1 = makeFrag(1, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800827 pkt1.add<lp::SequenceField>(1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000828 pkt1.add<lp::TxSequenceField>(12);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800829 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400830 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000831
Eric Newberry7b0071e2017-07-03 17:33:31 +0000832 // T+1ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400833 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400834 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000835
Eric Newberry7b0071e2017-07-03 17:33:31 +0000836 lp::Packet pkt2 = makeFrag(2, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800837 pkt2.add<lp::SequenceField>(2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000838 pkt2.add<lp::TxSequenceField>(13);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800839 BOOST_CHECK(reliability->processIncomingPacket({pkt2}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400840 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000841
Eric Newberry7b0071e2017-07-03 17:33:31 +0000842 // T+5ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400843 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400844 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000845
Eric Newberry7b0071e2017-07-03 17:33:31 +0000846 lp::Packet pkt3 = makeFrag(3, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800847 pkt3.add<lp::SequenceField>(3);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000848 pkt3.add<lp::TxSequenceField>(15);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800849 BOOST_CHECK(reliability->processIncomingPacket({pkt3}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400850 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000851
Eric Newberry7b0071e2017-07-03 17:33:31 +0000852 // T+9ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400853 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400854 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000855
Eric Newberry7b0071e2017-07-03 17:33:31 +0000856 // T+10ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400857 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400858 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000859}
860
861BOOST_AUTO_TEST_CASE(IdleAckTimer)
862{
Junxiao Shi21e01932018-04-21 10:39:05 +0000863 // T+0ms: populate ack queue and start idle ack timer
864 std::unordered_set<lp::Sequence> expectedAcks;
865 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000866 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000867 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000868 }
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400869 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000870 reliability->startIdleAckTimer();
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400871 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000872
Junxiao Shi21e01932018-04-21 10:39:05 +0000873 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400874 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400875 BOOST_CHECK(reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000876 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000877 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
Junxiao Shi21e01932018-04-21 10:39:05 +0000878 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000879 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
880
Junxiao Shi21e01932018-04-21 10:39:05 +0000881 // T+5ms: idle ack timer expires, IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400882 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400883 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000884 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000885 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry185ab292017-03-28 06:45:39 +0000886
Teng Liang13d582a2020-07-21 20:23:11 -0700887 lp::Packet sentPkt(transport->sentPackets.back());
Junxiao Shi21e01932018-04-21 10:39:05 +0000888 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
889 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
890 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000891 }
Junxiao Shi21e01932018-04-21 10:39:05 +0000892 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000893}
894
895BOOST_AUTO_TEST_CASE(IdleAckTimerMtu)
896{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000897 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000898
Junxiao Shi21e01932018-04-21 10:39:05 +0000899 // T+0ms: populate ack queue and start idle ack timer
900 std::unordered_set<lp::Sequence> expectedAcks;
901 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000902 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000903 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000904 }
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400905 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000906 reliability->startIdleAckTimer();
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400907 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000908
Junxiao Shi21e01932018-04-21 10:39:05 +0000909 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400910 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400911 BOOST_CHECK(reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000912 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
913 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
914 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000915 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
916
Junxiao Shi21e01932018-04-21 10:39:05 +0000917 // T+5ms: idle ack timer expires, IDLE packets generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400918 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400919 BOOST_CHECK(!reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000920 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000921
Junxiao Shi21e01932018-04-21 10:39:05 +0000922 // MTU is 1500. LpPacket TL occupies 4 octets. Each Ack header is 12 octets. There are room for
923 // 124 Acks per LpPacket, and it takes 5 LpPackets to carry 500 Acks.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000924 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Junxiao Shi21e01932018-04-21 10:39:05 +0000925 for (size_t i = 0; i < 5; i++) {
Teng Liang13d582a2020-07-21 20:23:11 -0700926 lp::Packet sentPkt(transport->sentPackets[i]);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000927 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000928 BOOST_CHECK_EQUAL(sentPkt.count<lp::AckField>(), i == 4 ? 4 : 124);
929 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
930 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
931 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000932 }
933
Junxiao Shi21e01932018-04-21 10:39:05 +0000934 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000935}
936
Eric Newberry32f7eac2020-02-07 14:40:17 -0800937BOOST_AUTO_TEST_CASE(TrackRecentReceivedLpPackets)
938{
939 lp::Packet pkt1 = makeFrag(1, 100);
940 pkt1.add<lp::SequenceField>(7);
941 pkt1.add<lp::TxSequenceField>(12);
942 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
943 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 1);
944 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 7);
945 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
946 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
947
948 // T+500ms
949 // Estimated RTO starts at 1000ms and we are not adding any measurements, so it should remain
950 // this value throughout the test case
951 advanceClocks(500_ms, 1);
952 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
953 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
954 lp::Packet pkt2 = makeFrag(1, 100);
955 pkt2.add<lp::SequenceField>(23);
956 pkt2.add<lp::TxSequenceField>(13);
957 BOOST_CHECK(reliability->processIncomingPacket({pkt2}));
958 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
959 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 7);
960 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
961 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
962 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(23), 1);
963
964 // T+1250ms
965 // First received sequence should be removed after next received packet, but second should remain
966 advanceClocks(750_ms, 1);
967 lp::Packet pkt3 = makeFrag(1, 100);
968 pkt3.add<lp::SequenceField>(24);
969 pkt3.add<lp::TxSequenceField>(14);
970 BOOST_CHECK(reliability->processIncomingPacket({pkt3}));
971 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
972 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 23);
973 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
974 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(23), 1);
975 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(24), 1);
976
977 // T+1750ms
978 // Second received sequence should be removed
979 advanceClocks(500_ms, 1);
980 lp::Packet pkt4 = makeFrag(1, 100);
981 pkt4.add<lp::SequenceField>(25);
982 pkt4.add<lp::TxSequenceField>(15);
983 BOOST_CHECK(reliability->processIncomingPacket({pkt4}));
984 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
985 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 24);
986 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
987 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(24), 1);
988 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(25), 1);
989}
990
991BOOST_AUTO_TEST_CASE(DropDuplicateReceivedSequence)
992{
993 Interest interest("/test/prefix");
Eric Newberry32f7eac2020-02-07 14:40:17 -0800994 lp::Packet pkt1;
995 pkt1.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
996 pkt1.add<lp::SequenceField>(7);
997 pkt1.add<lp::TxSequenceField>(12);
998 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
999 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
1000 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
1001
1002 lp::Packet pkt2;
1003 pkt2.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
1004 pkt2.add<lp::SequenceField>(7);
1005 pkt2.add<lp::TxSequenceField>(13);
1006 BOOST_CHECK(!reliability->processIncomingPacket({pkt2}));
1007 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
1008 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
1009}
1010
1011BOOST_AUTO_TEST_CASE(DropDuplicateAckForRetx)
1012{
1013 lp::Packet pkt1 = makeFrag(1024, 50);
1014 linkService->sendLpPackets({pkt1});
1015
1016 // Will send out a single fragment
1017 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
1018 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
1019 lp::Sequence firstTxSeq = reliability->m_firstUnackedFrag->first;
1020
1021 // RTO is initially 1 second, so will time out and retx
1022 advanceClocks(1250_ms, 1);
1023 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
1024 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
1025
1026 // Acknowledge first transmission (RTO underestimation)
1027 // Ack will be dropped because unknown
1028 lp::Packet ackPkt1;
1029 ackPkt1.add<lp::AckField>(firstTxSeq);
1030 reliability->processIncomingPacket(ackPkt1);
1031 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.size(), 1); // Required because collection used below
1032
1033 // Acknowledge second transmission
1034 // Ack will acknowledge retx and remove unacked frag
1035 lp::Packet ackPkt2;
1036 ackPkt2.add<lp::AckField>(reliability->m_firstUnackedFrag->first);
1037 reliability->processIncomingPacket(ackPkt2);
1038 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
1039}
1040
Eric Newberry7b0071e2017-07-03 17:33:31 +00001041BOOST_AUTO_TEST_SUITE_END() // TestLpReliability
Eric Newberry185ab292017-03-28 06:45:39 +00001042BOOST_AUTO_TEST_SUITE_END() // Face
1043
Davide Pesaventoe422f9e2022-06-03 01:30:23 -04001044} // namespace nfd::tests