blob: 834cb780b04aedc700b8abb99986f8d7cbffb4bd [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 Pesavento9a63bf22023-11-11 17:12:51 -05003 * Copyright (c) 2014-2023, 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"
Eric Newberry185ab292017-03-28 06:45:39 +000027#include "face/generic-link-service.hpp"
28
29#include "tests/test-common.hpp"
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040030#include "tests/daemon/global-io-fixture.hpp"
Eric Newberry185ab292017-03-28 06:45:39 +000031#include "dummy-face.hpp"
32#include "dummy-transport.hpp"
33
Davide Pesavento9a63bf22023-11-11 17:12:51 -050034#include <ndn-cxx/lp/fields.hpp>
35
Eric Newberry7b0071e2017-07-03 17:33:31 +000036#include <cstring>
Davide Pesaventob7bfcb92022-05-22 23:55:23 -040037#include <unordered_set>
Eric Newberry7b0071e2017-07-03 17:33:31 +000038
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040039namespace nfd::tests {
Eric Newberry185ab292017-03-28 06:45:39 +000040
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040041using namespace nfd::face;
Eric Newberry185ab292017-03-28 06:45:39 +000042
Eric Newberry185ab292017-03-28 06:45:39 +000043class DummyLpReliabilityLinkService : public GenericLinkService
44{
45public:
46 LpReliability*
47 getLpReliability()
48 {
49 return &m_reliability;
50 }
51
52 void
53 sendLpPackets(std::vector<lp::Packet> frags)
54 {
55 if (frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -070056 Interest interest("/test/prefix");
57 lp::Packet pkt;
Davide Pesaventof190cfa2019-07-17 20:14:11 -040058 pkt.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
Eric Newberry32f7eac2020-02-07 14:40:17 -080059 assignSequences(frags);
Eric Newberry41aba102017-11-01 16:42:13 -070060 m_reliability.handleOutgoing(frags, std::move(pkt), true);
Eric Newberry185ab292017-03-28 06:45:39 +000061 }
62
Davide Pesaventof190cfa2019-07-17 20:14:11 -040063 for (auto frag : frags) {
Teng Liangf3bc3ae2020-06-08 10:19:25 -070064 this->sendLpPacket(std::move(frag));
Eric Newberry185ab292017-03-28 06:45:39 +000065 }
66 }
67
68private:
69 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070070 doSendInterest(const Interest&) final
Eric Newberry185ab292017-03-28 06:45:39 +000071 {
Davide Pesavento5a897692019-10-31 01:28:43 -040072 BOOST_FAIL("unexpected doSendInterest");
Eric Newberry185ab292017-03-28 06:45:39 +000073 }
74
75 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070076 doSendData(const Data&) final
Eric Newberry185ab292017-03-28 06:45:39 +000077 {
Davide Pesavento5a897692019-10-31 01:28:43 -040078 BOOST_FAIL("unexpected doSendData");
Eric Newberry185ab292017-03-28 06:45:39 +000079 }
80
81 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070082 doSendNack(const lp::Nack&) final
Eric Newberry185ab292017-03-28 06:45:39 +000083 {
Davide Pesavento5a897692019-10-31 01:28:43 -040084 BOOST_FAIL("unexpected doSendNack");
Eric Newberry185ab292017-03-28 06:45:39 +000085 }
86
87 void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040088 doReceivePacket(const Block&, const EndpointId&) final
Eric Newberry185ab292017-03-28 06:45:39 +000089 {
Davide Pesavento5a897692019-10-31 01:28:43 -040090 BOOST_FAIL("unexpected doReceivePacket");
Eric Newberry185ab292017-03-28 06:45:39 +000091 }
92};
93
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040094class LpReliabilityFixture : public GlobalIoTimeFixture
Eric Newberry185ab292017-03-28 06:45:39 +000095{
96public:
97 LpReliabilityFixture()
98 : linkService(make_unique<DummyLpReliabilityLinkService>())
99 , transport(make_unique<DummyTransport>())
100 , face(make_unique<DummyFace>())
101 {
102 linkService->setFaceAndTransport(*face, *transport);
103 transport->setFaceAndLinkService(*face, *linkService);
104
105 GenericLinkService::Options options;
106 options.reliabilityOptions.isEnabled = true;
107 linkService->setOptions(options);
108
109 reliability = linkService->getLpReliability();
Eric Newberry7b0071e2017-07-03 17:33:31 +0000110 reliability->m_lastTxSeqNo = 1;
111 }
112
113 static bool
114 netPktHasUnackedFrag(const shared_ptr<LpReliability::NetPkt>& netPkt, lp::Sequence txSeq)
115 {
116 return std::any_of(netPkt->unackedFrags.begin(), netPkt->unackedFrags.end(),
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400117 [txSeq] (auto fragIt) { return fragIt->first == txSeq; });
Eric Newberry7b0071e2017-07-03 17:33:31 +0000118 }
119
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400120 /** \brief Make an LpPacket with fragment of specified size.
Eric Newberry32f7eac2020-02-07 14:40:17 -0800121 * \param pktNum packet identifier, which can be extracted with \p getPktNum
Davide Pesaventob93fb6c2020-04-12 14:10:45 -0400122 * \param payloadSize total payload size; must be >= 4 and <= 255
Eric Newberry7b0071e2017-07-03 17:33:31 +0000123 */
124 static lp::Packet
Eric Newberry32f7eac2020-02-07 14:40:17 -0800125 makeFrag(uint32_t pktNum, size_t payloadSize = 4)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000126 {
Davide Pesaventob93fb6c2020-04-12 14:10:45 -0400127 BOOST_ASSERT(payloadSize >= 4 && payloadSize <= 255);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000128 lp::Packet pkt;
129 ndn::Buffer buf(payloadSize);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800130 std::memcpy(buf.data(), &pktNum, sizeof(pktNum));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400131 pkt.set<lp::FragmentField>({buf.cbegin(), buf.cend()});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000132 return pkt;
133 }
134
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400135 /** \brief Extract packet identifier from LpPacket made with \p makeFrag.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000136 * \retval 0 packet identifier cannot be extracted
137 */
138 static uint32_t
Eric Newberry32f7eac2020-02-07 14:40:17 -0800139 getPktNum(const lp::Packet& pkt)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000140 {
Davide Pesaventob93fb6c2020-04-12 14:10:45 -0400141 BOOST_REQUIRE(pkt.has<lp::FragmentField>());
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400142 auto [begin, end] = pkt.get<lp::FragmentField>();
Eric Newberry7b0071e2017-07-03 17:33:31 +0000143 if (std::distance(begin, end) < 4) {
144 return 0;
145 }
146
147 uint32_t value = 0;
148 std::memcpy(&value, &*begin, sizeof(value));
149 return value;
Eric Newberry185ab292017-03-28 06:45:39 +0000150 }
151
Eric Newberry971d9622018-03-30 23:29:26 -0700152protected:
Eric Newberry185ab292017-03-28 06:45:39 +0000153 unique_ptr<DummyLpReliabilityLinkService> linkService;
154 unique_ptr<DummyTransport> transport;
155 unique_ptr<DummyFace> face;
156 LpReliability* reliability;
157};
158
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400159BOOST_AUTO_TEST_SUITE(Face)
Eric Newberry185ab292017-03-28 06:45:39 +0000160BOOST_FIXTURE_TEST_SUITE(TestLpReliability, LpReliabilityFixture)
161
162BOOST_AUTO_TEST_CASE(SendNoFragmentField)
163{
164 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000165
166 linkService->sendLpPackets({pkt});
167 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000168 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700169 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
170 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
171 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700172 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000173}
174
Eric Newberry7b0071e2017-07-03 17:33:31 +0000175BOOST_AUTO_TEST_CASE(SendUnfragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000176{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000177 lp::Packet pkt1 = makeFrag(1024, 50);
178 lp::Packet pkt2 = makeFrag(3000, 30);
Eric Newberry185ab292017-03-28 06:45:39 +0000179
180 linkService->sendLpPackets({pkt1});
Eric Newberry971d9622018-03-30 23:29:26 -0700181 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Teng Liang13d582a2020-07-21 20:23:11 -0700182 lp::Packet cached1(transport->sentPackets.front());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000183 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
Eric Newberry32f7eac2020-02-07 14:40:17 -0800184 BOOST_CHECK(cached1.has<lp::SequenceField>());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000185 lp::Sequence firstTxSeq = cached1.get<lp::TxSequenceField>();
Eric Newberry971d9622018-03-30 23:29:26 -0700186 BOOST_CHECK_EQUAL(firstTxSeq, 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800187 BOOST_CHECK_EQUAL(getPktNum(cached1), 1024);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700188 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
189 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
190 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700191 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000192
Eric Newberry185ab292017-03-28 06:45:39 +0000193 // T+500ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000194 // 1024 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400195 advanceClocks(1_ms, 500);
Eric Newberry185ab292017-03-28 06:45:39 +0000196 linkService->sendLpPackets({pkt2});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000197 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
Eric Newberry185ab292017-03-28 06:45:39 +0000198
Eric Newberry00d39fd2017-12-10 14:26:45 -0700199 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
200 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 1);
201 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000202 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq).netPkt);
203 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
204 BOOST_CHECK_NE(reliability->m_unackedFrags.at(firstTxSeq).netPkt,
Eric Newberry971d9622018-03-30 23:29:26 -0700205 reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000206 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).retxCount, 0);
207 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
208 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq);
209 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700210 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
211 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
212 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700213 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000214
215 // T+1250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000216 // 1024 rto: 1000ms, txSeq: 4, started T+1000ms, retx 1
217 // 3000 rto: 1000ms, txSeq: 3, started T+500ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400218 advanceClocks(1_ms, 750);
Eric Newberry185ab292017-03-28 06:45:39 +0000219
Eric Newberry00d39fd2017-12-10 14:26:45 -0700220 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000221 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700222 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000223 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 2).retxCount, 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700224 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000225 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
226 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 1);
227 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700228 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
229 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
230 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700231 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000232
233 // T+2250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000234 // 1024 rto: 1000ms, txSeq: 6, started T+2000ms, retx 2
235 // 3000 rto: 1000ms, txSeq: 5, started T+1500ms, retx 1
Davide Pesavento14e71f02019-03-28 17:35:25 -0400236 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000237
Eric Newberry00d39fd2017-12-10 14:26:45 -0700238 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000239 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 0);
240 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700241 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000242 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 4).retxCount, 2);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700243 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000244 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 3).retxCount, 1);
245 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 3);
246 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700247 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
248 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
249 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700250 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000251
252 // T+3250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000253 // 1024 rto: 1000ms, txSeq: 8, started T+3000ms, retx 3
254 // 3000 rto: 1000ms, txSeq: 7, started T+2500ms, retx 2
Davide Pesavento14e71f02019-03-28 17:35:25 -0400255 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000256
Eric Newberry00d39fd2017-12-10 14:26:45 -0700257 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000258 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 0);
259 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700260 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000261 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 6).retxCount, 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700262 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000263 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 5).retxCount, 2);
264 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 5);
265 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 7);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700266 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
267 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
268 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700269 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000270
271 // T+4250ms
272 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000273 // 3000 rto: 1000ms, txSeq: 9, started T+3500ms, retx 3
Davide Pesavento14e71f02019-03-28 17:35:25 -0400274 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000275
Eric Newberry00d39fd2017-12-10 14:26:45 -0700276 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000277 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 0);
278 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700279 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 7), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000280 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 7).retxCount, 3);
281 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 7);
282 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry185ab292017-03-28 06:45:39 +0000283
Eric Newberry00d39fd2017-12-10 14:26:45 -0700284 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
285 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
286 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 1);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700287 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 1);
Eric Newberry41aba102017-11-01 16:42:13 -0700288
Eric Newberry185ab292017-03-28 06:45:39 +0000289 // T+4750ms
290 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000291 // 3000 rto: expired, removed
Davide Pesavento14e71f02019-03-28 17:35:25 -0400292 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000293
294 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000295 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
296 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700297 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
298 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
299 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 2);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700300 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 2);
Eric Newberry185ab292017-03-28 06:45:39 +0000301}
302
Eric Newberry7b0071e2017-07-03 17:33:31 +0000303BOOST_AUTO_TEST_CASE(SendFragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000304{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000305 lp::Packet pkt1 = makeFrag(2048, 30);
306 lp::Packet pkt2 = makeFrag(2049, 30);
307 lp::Packet pkt3 = makeFrag(2050, 10);
Eric Newberry185ab292017-03-28 06:45:39 +0000308
Eric Newberry7b0071e2017-07-03 17:33:31 +0000309 linkService->sendLpPackets({pkt1, pkt2, pkt3});
310 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000311
Teng Liang13d582a2020-07-21 20:23:11 -0700312 lp::Packet cached1(transport->sentPackets.at(0));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000313 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
314 BOOST_CHECK_EQUAL(cached1.get<lp::TxSequenceField>(), 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800315 BOOST_CHECK(cached1.has<lp::SequenceField>());
316 BOOST_CHECK_EQUAL(getPktNum(cached1), 2048);
Teng Liang13d582a2020-07-21 20:23:11 -0700317 lp::Packet cached2(transport->sentPackets.at(1));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000318 BOOST_REQUIRE(cached2.has<lp::TxSequenceField>());
319 BOOST_CHECK_EQUAL(cached2.get<lp::TxSequenceField>(), 3);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800320 BOOST_CHECK(cached2.has<lp::SequenceField>());
321 BOOST_CHECK_EQUAL(getPktNum(cached2), 2049);
Teng Liang13d582a2020-07-21 20:23:11 -0700322 lp::Packet cached3(transport->sentPackets.at(2));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000323 BOOST_REQUIRE(cached3.has<lp::TxSequenceField>());
324 BOOST_CHECK_EQUAL(cached3.get<lp::TxSequenceField>(), 4);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800325 BOOST_CHECK(cached3.has<lp::SequenceField>());
326 BOOST_CHECK_EQUAL(getPktNum(cached3), 2050);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700327 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
328 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
329 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700330 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000331
Eric Newberry7b0071e2017-07-03 17:33:31 +0000332 // T+0ms
333 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
334 // 2049 rto: 1000ms, txSeq: 3, started T+0ms, retx 0
335 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Eric Newberry185ab292017-03-28 06:45:39 +0000336
Eric Newberry00d39fd2017-12-10 14:26:45 -0700337 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
338 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1);
339 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800340 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
341 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(3).pkt), 2049);
342 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000343 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
344 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
345 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
346 BOOST_REQUIRE(reliability->m_unackedFrags.at(3).netPkt);
347 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
348 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
349 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(3).netPkt);
350 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
351 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
352 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
353 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
354 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
355 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
356 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
357 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700358 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
359 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
360 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700361 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000362
Eric Newberry7b0071e2017-07-03 17:33:31 +0000363 // T+250ms
364 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
365 // 2049 rto: 1000ms, txSeq: 5, started T+250ms, retx 1
366 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400367 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800368 reliability->onLpPacketLost(3, true);
Eric Newberry185ab292017-03-28 06:45:39 +0000369
Eric Newberry00d39fd2017-12-10 14:26:45 -0700370 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000371 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700372 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 1);
373 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800374 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
375 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(5).pkt), 2049);
376 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000377 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
378 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
379 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(5).retxCount, 1);
380 BOOST_REQUIRE(reliability->m_unackedFrags.at(5).netPkt);
381 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
382 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
383 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(5).netPkt);
384 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
385 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
386 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
387 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
388 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
389 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
390 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
391 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700392 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
393 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
394 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700395 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000396
397 // T+500ms
398 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
399 // 2049 rto: 1000ms, txSeq: 6, started T+500ms, retx 2
400 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400401 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800402 reliability->onLpPacketLost(5, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000403
Eric Newberry00d39fd2017-12-10 14:26:45 -0700404 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000405 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700406 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 1);
407 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800408 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
409 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(6).pkt), 2049);
410 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000411 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
412 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
413 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(6).retxCount, 2);
414 BOOST_REQUIRE(reliability->m_unackedFrags.at(6).netPkt);
415 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
416 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
417 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(6).netPkt);
418 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
419 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
420 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
421 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
422 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
423 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
424 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
425 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700426 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
427 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
428 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700429 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000430
431 // T+750ms
432 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
433 // 2049 rto: 1000ms, txSeq: 7, started T+750ms, retx 3
434 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400435 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800436 reliability->onLpPacketLost(6, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000437
438 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 1);
439 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700440 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(7), 1);
441 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800442 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
443 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(7).pkt), 2049);
444 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000445 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
446 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
447 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(7).retxCount, 3);
448 BOOST_REQUIRE(reliability->m_unackedFrags.at(7).netPkt);
449 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
450 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
451 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(7).netPkt);
452 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
453 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
454 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
455 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
456 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 7));
457 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
458 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
459 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700460 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
461 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
462 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700463 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000464
465 // T+850ms
466 // 2048 rto: expired, removed
467 // 2049 rto: expired, removed
468 // 2050 rto: expired, removed
Davide Pesavento14e71f02019-03-28 17:35:25 -0400469 advanceClocks(1_ms, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800470 reliability->onLpPacketLost(7, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000471
472 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
473 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700474 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
475 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
476 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 1);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700477 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000478}
479
Eric Newberry00d39fd2017-12-10 14:26:45 -0700480BOOST_AUTO_TEST_CASE(AckUnknownTxSeq)
481{
482 linkService->sendLpPackets({makeFrag(1, 50)});
483
484 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
485 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
486 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
487 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
488 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
489 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
490 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
491 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700492 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700493
494 lp::Packet ackPkt;
495 ackPkt.add<lp::AckField>(10101010);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800496 BOOST_CHECK(reliability->processIncomingPacket(ackPkt));
Eric Newberry00d39fd2017-12-10 14:26:45 -0700497
498 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
499 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
500 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
501 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
502 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
503 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
504 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
505 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700506 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700507}
508
Eric Newberry971d9622018-03-30 23:29:26 -0700509BOOST_AUTO_TEST_CASE(LossByGreaterAcks)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000510{
Eric Newberry971d9622018-03-30 23:29:26 -0700511 // Detect loss by 3x greater Acks, also tests wraparound
512
Eric Newberry7b0071e2017-07-03 17:33:31 +0000513 reliability->m_lastTxSeqNo = 0xFFFFFFFFFFFFFFFE;
514
Eric Newberry971d9622018-03-30 23:29:26 -0700515 // Passed to sendLpPackets individually since they are
516 // from separate, non-fragmented network packets
Eric Newberry7b0071e2017-07-03 17:33:31 +0000517 linkService->sendLpPackets({makeFrag(1, 50)});
518 linkService->sendLpPackets({makeFrag(2, 50)});
519 linkService->sendLpPackets({makeFrag(3, 50)});
520 linkService->sendLpPackets({makeFrag(4, 50)});
521 linkService->sendLpPackets({makeFrag(5, 50)});
Eric Newberry185ab292017-03-28 06:45:39 +0000522
523 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000524 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
525 BOOST_CHECK(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).netPkt);
526 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 1); // pkt2
527 BOOST_CHECK(reliability->m_unackedFrags.at(0).netPkt);
528 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
529 BOOST_CHECK(reliability->m_unackedFrags.at(1).netPkt);
530 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
531 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
532 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
533 BOOST_CHECK(reliability->m_unackedFrags.at(3).netPkt);
Eric Newberry185ab292017-03-28 06:45:39 +0000534 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700535 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
536 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
537 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700538 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000539
540 lp::Packet ackPkt1;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000541 ackPkt1.add<lp::AckField>(0);
Eric Newberry185ab292017-03-28 06:45:39 +0000542
543 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
544
Eric Newberry32f7eac2020-02-07 14:40:17 -0800545 BOOST_CHECK(reliability->processIncomingPacket(ackPkt1));
Eric Newberry185ab292017-03-28 06:45:39 +0000546
547 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700548 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000549 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
550 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000551 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700552 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000553 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
554 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700555 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
Eric Newberry7b0071e2017-07-03 17:33:31 +0000556 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
557 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700558 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000559 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
560 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000561 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000562 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700563 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
564 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
565 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700566 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000567
568 lp::Packet ackPkt2;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000569 ackPkt2.add<lp::AckField>(2);
570 ackPkt1.add<lp::AckField>(101010); // Unknown TxSequence number - ignored
Eric Newberry185ab292017-03-28 06:45:39 +0000571
572 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
573
Eric Newberry32f7eac2020-02-07 14:40:17 -0800574 BOOST_CHECK(reliability->processIncomingPacket(ackPkt2));
Eric Newberry185ab292017-03-28 06:45:39 +0000575
576 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000577 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000578 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
579 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000580 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700581 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000582 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
583 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700584 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
585 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000586 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
587 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
588 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(101010), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000589 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000590 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700591 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 2);
592 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
593 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700594 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000595
596 lp::Packet ackPkt3;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000597 ackPkt3.add<lp::AckField>(1);
Eric Newberry185ab292017-03-28 06:45:39 +0000598
599 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
600
Eric Newberry32f7eac2020-02-07 14:40:17 -0800601 BOOST_CHECK(reliability->processIncomingPacket(ackPkt3));
Eric Newberry185ab292017-03-28 06:45:39 +0000602
603 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000604 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
605 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
606 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
607 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700608 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000609 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
610 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700611 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1); // pkt1 new TxSeq
Eric Newberry7b0071e2017-07-03 17:33:31 +0000612 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 1);
613 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).nGreaterSeqAcks, 0);
614 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000615 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Teng Liang13d582a2020-07-21 20:23:11 -0700616 lp::Packet sentRetxPkt(transport->sentPackets.back());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000617 BOOST_REQUIRE(sentRetxPkt.has<lp::TxSequenceField>());
618 BOOST_CHECK_EQUAL(sentRetxPkt.get<lp::TxSequenceField>(), 4);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800619 BOOST_CHECK_EQUAL(getPktNum(sentRetxPkt), 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700620 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
621 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
622 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700623 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000624
625 lp::Packet ackPkt4;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000626 ackPkt4.add<lp::AckField>(4);
Eric Newberry185ab292017-03-28 06:45:39 +0000627
628 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
629
Eric Newberry32f7eac2020-02-07 14:40:17 -0800630 BOOST_CHECK(reliability->processIncomingPacket(ackPkt4));
Eric Newberry185ab292017-03-28 06:45:39 +0000631
632 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000633 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
634 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
635 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
636 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700637 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000638 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
639 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 1);
640 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 0); // pkt1 new TxSeq
641 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000642 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700643 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
644 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 1);
645 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700646 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700647}
648
Eric Newberry971d9622018-03-30 23:29:26 -0700649BOOST_AUTO_TEST_CASE(SkipFragmentsRemovedInRtt)
650{
651 auto opts = linkService->getOptions();
652 opts.reliabilityOptions.maxRetx = 0; // just to make the test case shorter
653 opts.reliabilityOptions.seqNumLossThreshold = 3;
654 linkService->setOptions(opts);
655
656 lp::Packet frag1 = makeFrag(5001);
657 lp::Packet frag2 = makeFrag(5002);
658 linkService->sendLpPackets({frag1, frag2}); // First packet has 2 fragments
659 linkService->sendLpPackets({makeFrag(5003)});
660 linkService->sendLpPackets({makeFrag(5004)});
661 linkService->sendLpPackets({makeFrag(5005)});
662
663 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
664 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
665
666 lp::Sequence firstTxSeq = reliability->m_firstUnackedFrag->first;
667
668 // Ack the last 2 packets
669 lp::Packet ackPkt1;
670 ackPkt1.add<lp::AckField>(firstTxSeq + 4);
671 ackPkt1.add<lp::AckField>(firstTxSeq + 3);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800672 BOOST_CHECK(reliability->processIncomingPacket(ackPkt1));
Eric Newberry971d9622018-03-30 23:29:26 -0700673
674 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
675 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).nGreaterSeqAcks, 2);
676 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).nGreaterSeqAcks, 2);
677
678 // Ack the third packet (5003)
679 // This triggers a "loss by greater Acks" for packets 5001 and 5002
680 lp::Packet ackPkt2;
681 ackPkt2.add<lp::AckField>(firstTxSeq + 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800682 BOOST_CHECK(reliability->processIncomingPacket(ackPkt2)); // tests crash/assert reported in bug #4479
Eric Newberry971d9622018-03-30 23:29:26 -0700683
684 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
685}
686
Eric Newberry00d39fd2017-12-10 14:26:45 -0700687BOOST_AUTO_TEST_CASE(CancelLossNotificationOnAck)
688{
689 reliability->onDroppedInterest.connect([] (const Interest&) {
690 BOOST_FAIL("Packet loss timeout should be cancelled when packet acknowledged");
691 });
692
693 reliability->m_lastTxSeqNo = 0;
694
695 linkService->sendLpPackets({makeFrag(1, 50)});
696
Davide Pesavento14e71f02019-03-28 17:35:25 -0400697 advanceClocks(1_ms, 500);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700698
699 lp::Packet ackPkt;
700 ackPkt.add<lp::AckField>(1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800701 BOOST_CHECK(reliability->processIncomingPacket(ackPkt));
Eric Newberry00d39fd2017-12-10 14:26:45 -0700702
Davide Pesavento14e71f02019-03-28 17:35:25 -0400703 advanceClocks(1_ms, 1000);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700704
705 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
706 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
707 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry9d283ad2020-04-12 23:37:17 -0700708 BOOST_CHECK_EQUAL(linkService->getCounters().nInterestsExceededRetx, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000709}
710
Eric Newberry7b0071e2017-07-03 17:33:31 +0000711BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
712{
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400713 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000714 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
715
716 lp::Packet pkt1 = makeFrag(100, 40);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800717 pkt1.add<lp::SequenceField>(123456);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000718 pkt1.add<lp::TxSequenceField>(765432);
719
Eric Newberry32f7eac2020-02-07 14:40:17 -0800720 BOOST_CHECK(reliability->processIncomingPacket(pkt1));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000721
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400722 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000723 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
724 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800725 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
726 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(123456), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000727
728 lp::Packet pkt2 = makeFrag(276, 40);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800729 pkt2.add<lp::SequenceField>(654321);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000730 pkt2.add<lp::TxSequenceField>(234567);
731
Eric Newberry32f7eac2020-02-07 14:40:17 -0800732 BOOST_CHECK(reliability->processIncomingPacket(pkt2));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000733
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400734 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000735 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
736 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
737 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 234567);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800738 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
739 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(123456), 1);
740 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(654321), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000741
742 // T+5ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400743 advanceClocks(1_ms, 5);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400744 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000745}
746
747BOOST_AUTO_TEST_CASE(PiggybackAcks)
748{
749 reliability->m_ackQueue.push(256);
750 reliability->m_ackQueue.push(257);
751 reliability->m_ackQueue.push(10);
752
753 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000754 linkService->sendLpPackets({pkt});
755
756 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Teng Liang13d582a2020-07-21 20:23:11 -0700757 lp::Packet sentPkt(transport->sentPackets.front());
Eric Newberry185ab292017-03-28 06:45:39 +0000758
759 BOOST_REQUIRE_EQUAL(sentPkt.count<lp::AckField>(), 3);
760 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(0), 256);
761 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(1), 257);
762 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(2), 10);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000763 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Eric Newberry185ab292017-03-28 06:45:39 +0000764
765 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
766}
767
768BOOST_AUTO_TEST_CASE(PiggybackAcksMtu)
769{
Eric Newberry32f7eac2020-02-07 14:40:17 -0800770 // MTU is 1500, payload has 60 octets plus 6 octets for LpPacket and Fragment TL and 10 octets
771 // each for Sequence and TxSequence, leaving 1414 octets for piggybacking. Each Ack header is 12
772 // octets, so each LpPacket can carry 117 Acks, and it takes 9 LpPackets for 1000 Acks.
Eric Newberry185ab292017-03-28 06:45:39 +0000773
Eric Newberry7b0071e2017-07-03 17:33:31 +0000774 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000775
Junxiao Shi21e01932018-04-21 10:39:05 +0000776 std::unordered_set<lp::Sequence> expectedAcks;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000777 for (lp::Sequence i = 1000; i < 2000; i++) {
778 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000779 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000780 }
Eric Newberry185ab292017-03-28 06:45:39 +0000781
Junxiao Shi21e01932018-04-21 10:39:05 +0000782 for (uint32_t i = 1; i <= 9; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000783 lp::Packet pkt = makeFrag(i, 60);
784 linkService->sendLpPackets({pkt});
Eric Newberry185ab292017-03-28 06:45:39 +0000785
Junxiao Shi21e01932018-04-21 10:39:05 +0000786 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), i);
Teng Liang13d582a2020-07-21 20:23:11 -0700787 lp::Packet sentPkt(transport->sentPackets.back());
Eric Newberry32f7eac2020-02-07 14:40:17 -0800788 BOOST_CHECK_EQUAL(getPktNum(sentPkt), i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000789 BOOST_CHECK(sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000790
791 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
792 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
793 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000794 }
Eric Newberry185ab292017-03-28 06:45:39 +0000795
Eric Newberry7b0071e2017-07-03 17:33:31 +0000796 BOOST_CHECK(reliability->m_ackQueue.empty());
Junxiao Shi21e01932018-04-21 10:39:05 +0000797 BOOST_CHECK(expectedAcks.empty());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000798}
Eric Newberry185ab292017-03-28 06:45:39 +0000799
Eric Newberry7b0071e2017-07-03 17:33:31 +0000800BOOST_AUTO_TEST_CASE(PiggybackAcksMtuNoSpace)
801{
Eric Newberry32f7eac2020-02-07 14:40:17 -0800802 // MTU is 64, payload has 34 octets plus 4 octets for LpPacket and Fragment TL and 10 octets each
803 // for Sequence and TxSequence, leaving 6 octets for piggybacking. Each Ack header is 12 octets,
804 // so there's no room to piggyback any Ack in LpPacket.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000805
Eric Newberrycb6551e2020-03-02 14:12:16 -0800806 transport->setMtu(MIN_MTU);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000807
808 for (lp::Sequence i = 1000; i < 1100; i++) {
809 reliability->m_ackQueue.push(i);
810 }
811
Eric Newberry32f7eac2020-02-07 14:40:17 -0800812 lp::Packet pkt = makeFrag(1, 34);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000813 linkService->sendLpPackets({pkt});
814
Eric Newberry185ab292017-03-28 06:45:39 +0000815 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Teng Liang13d582a2020-07-21 20:23:11 -0700816 lp::Packet sentPkt(transport->sentPackets.back());
Eric Newberry32f7eac2020-02-07 14:40:17 -0800817 BOOST_CHECK_EQUAL(getPktNum(sentPkt), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000818 BOOST_CHECK(!sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000819
820 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 100);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000821}
Eric Newberry185ab292017-03-28 06:45:39 +0000822
Eric Newberry7b0071e2017-07-03 17:33:31 +0000823BOOST_AUTO_TEST_CASE(StartIdleAckTimer)
824{
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400825 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000826
Eric Newberry7b0071e2017-07-03 17:33:31 +0000827 lp::Packet pkt1 = makeFrag(1, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800828 pkt1.add<lp::SequenceField>(1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000829 pkt1.add<lp::TxSequenceField>(12);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800830 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400831 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000832
Eric Newberry7b0071e2017-07-03 17:33:31 +0000833 // T+1ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400834 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400835 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000836
Eric Newberry7b0071e2017-07-03 17:33:31 +0000837 lp::Packet pkt2 = makeFrag(2, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800838 pkt2.add<lp::SequenceField>(2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000839 pkt2.add<lp::TxSequenceField>(13);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800840 BOOST_CHECK(reliability->processIncomingPacket({pkt2}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400841 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000842
Eric Newberry7b0071e2017-07-03 17:33:31 +0000843 // T+5ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400844 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400845 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000846
Eric Newberry7b0071e2017-07-03 17:33:31 +0000847 lp::Packet pkt3 = makeFrag(3, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800848 pkt3.add<lp::SequenceField>(3);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000849 pkt3.add<lp::TxSequenceField>(15);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800850 BOOST_CHECK(reliability->processIncomingPacket({pkt3}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400851 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000852
Eric Newberry7b0071e2017-07-03 17:33:31 +0000853 // T+9ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400854 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400855 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000856
Eric Newberry7b0071e2017-07-03 17:33:31 +0000857 // T+10ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400858 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400859 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000860}
861
862BOOST_AUTO_TEST_CASE(IdleAckTimer)
863{
Junxiao Shi21e01932018-04-21 10:39:05 +0000864 // T+0ms: populate ack queue and start idle ack timer
865 std::unordered_set<lp::Sequence> expectedAcks;
866 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000867 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000868 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000869 }
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400870 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000871 reliability->startIdleAckTimer();
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400872 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000873
Junxiao Shi21e01932018-04-21 10:39:05 +0000874 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400875 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400876 BOOST_CHECK(reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000877 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000878 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
Junxiao Shi21e01932018-04-21 10:39:05 +0000879 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000880 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
881
Junxiao Shi21e01932018-04-21 10:39:05 +0000882 // T+5ms: idle ack timer expires, IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400883 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400884 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000885 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000886 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry185ab292017-03-28 06:45:39 +0000887
Teng Liang13d582a2020-07-21 20:23:11 -0700888 lp::Packet sentPkt(transport->sentPackets.back());
Junxiao Shi21e01932018-04-21 10:39:05 +0000889 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
890 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
891 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000892 }
Junxiao Shi21e01932018-04-21 10:39:05 +0000893 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000894}
895
896BOOST_AUTO_TEST_CASE(IdleAckTimerMtu)
897{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000898 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000899
Junxiao Shi21e01932018-04-21 10:39:05 +0000900 // T+0ms: populate ack queue and start idle ack timer
901 std::unordered_set<lp::Sequence> expectedAcks;
902 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000903 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000904 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000905 }
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400906 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000907 reliability->startIdleAckTimer();
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400908 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000909
Junxiao Shi21e01932018-04-21 10:39:05 +0000910 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400911 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400912 BOOST_CHECK(reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000913 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
914 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
915 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000916 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
917
Junxiao Shi21e01932018-04-21 10:39:05 +0000918 // T+5ms: idle ack timer expires, IDLE packets generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400919 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400920 BOOST_CHECK(!reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000921 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000922
Junxiao Shi21e01932018-04-21 10:39:05 +0000923 // MTU is 1500. LpPacket TL occupies 4 octets. Each Ack header is 12 octets. There are room for
924 // 124 Acks per LpPacket, and it takes 5 LpPackets to carry 500 Acks.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000925 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Junxiao Shi21e01932018-04-21 10:39:05 +0000926 for (size_t i = 0; i < 5; i++) {
Teng Liang13d582a2020-07-21 20:23:11 -0700927 lp::Packet sentPkt(transport->sentPackets[i]);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000928 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000929 BOOST_CHECK_EQUAL(sentPkt.count<lp::AckField>(), i == 4 ? 4 : 124);
930 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
931 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
932 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000933 }
934
Junxiao Shi21e01932018-04-21 10:39:05 +0000935 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000936}
937
Eric Newberry32f7eac2020-02-07 14:40:17 -0800938BOOST_AUTO_TEST_CASE(TrackRecentReceivedLpPackets)
939{
940 lp::Packet pkt1 = makeFrag(1, 100);
941 pkt1.add<lp::SequenceField>(7);
942 pkt1.add<lp::TxSequenceField>(12);
943 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
944 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 1);
945 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 7);
946 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
947 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
948
949 // T+500ms
950 // Estimated RTO starts at 1000ms and we are not adding any measurements, so it should remain
951 // this value throughout the test case
952 advanceClocks(500_ms, 1);
953 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
954 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
955 lp::Packet pkt2 = makeFrag(1, 100);
956 pkt2.add<lp::SequenceField>(23);
957 pkt2.add<lp::TxSequenceField>(13);
958 BOOST_CHECK(reliability->processIncomingPacket({pkt2}));
959 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
960 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 7);
961 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
962 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
963 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(23), 1);
964
965 // T+1250ms
966 // First received sequence should be removed after next received packet, but second should remain
967 advanceClocks(750_ms, 1);
968 lp::Packet pkt3 = makeFrag(1, 100);
969 pkt3.add<lp::SequenceField>(24);
970 pkt3.add<lp::TxSequenceField>(14);
971 BOOST_CHECK(reliability->processIncomingPacket({pkt3}));
972 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
973 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 23);
974 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
975 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(23), 1);
976 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(24), 1);
977
978 // T+1750ms
979 // Second received sequence should be removed
980 advanceClocks(500_ms, 1);
981 lp::Packet pkt4 = makeFrag(1, 100);
982 pkt4.add<lp::SequenceField>(25);
983 pkt4.add<lp::TxSequenceField>(15);
984 BOOST_CHECK(reliability->processIncomingPacket({pkt4}));
985 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
986 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 24);
987 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
988 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(24), 1);
989 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(25), 1);
990}
991
992BOOST_AUTO_TEST_CASE(DropDuplicateReceivedSequence)
993{
994 Interest interest("/test/prefix");
Eric Newberry32f7eac2020-02-07 14:40:17 -0800995 lp::Packet pkt1;
996 pkt1.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
997 pkt1.add<lp::SequenceField>(7);
998 pkt1.add<lp::TxSequenceField>(12);
999 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
1000 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
1001 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
1002
1003 lp::Packet pkt2;
1004 pkt2.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
1005 pkt2.add<lp::SequenceField>(7);
1006 pkt2.add<lp::TxSequenceField>(13);
1007 BOOST_CHECK(!reliability->processIncomingPacket({pkt2}));
1008 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
1009 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
1010}
1011
1012BOOST_AUTO_TEST_CASE(DropDuplicateAckForRetx)
1013{
1014 lp::Packet pkt1 = makeFrag(1024, 50);
1015 linkService->sendLpPackets({pkt1});
1016
1017 // Will send out a single fragment
1018 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
1019 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
1020 lp::Sequence firstTxSeq = reliability->m_firstUnackedFrag->first;
1021
1022 // RTO is initially 1 second, so will time out and retx
1023 advanceClocks(1250_ms, 1);
1024 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
1025 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
1026
1027 // Acknowledge first transmission (RTO underestimation)
1028 // Ack will be dropped because unknown
1029 lp::Packet ackPkt1;
1030 ackPkt1.add<lp::AckField>(firstTxSeq);
1031 reliability->processIncomingPacket(ackPkt1);
1032 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.size(), 1); // Required because collection used below
1033
1034 // Acknowledge second transmission
1035 // Ack will acknowledge retx and remove unacked frag
1036 lp::Packet ackPkt2;
1037 ackPkt2.add<lp::AckField>(reliability->m_firstUnackedFrag->first);
1038 reliability->processIncomingPacket(ackPkt2);
1039 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
1040}
1041
Eric Newberry7b0071e2017-07-03 17:33:31 +00001042BOOST_AUTO_TEST_SUITE_END() // TestLpReliability
Eric Newberry185ab292017-03-28 06:45:39 +00001043BOOST_AUTO_TEST_SUITE_END() // Face
1044
Davide Pesaventoe422f9e2022-06-03 01:30:23 -04001045} // namespace nfd::tests