blob: 18800744ed46a49426246f7f585b4ecbf65c9a20 [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/*
Eric Newberry32f7eac2020-02-07 14:40:17 -08003 * Copyright (c) 2014-2020, 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>
36
Eric Newberry185ab292017-03-28 06:45:39 +000037namespace nfd {
38namespace face {
39namespace tests {
40
41using namespace nfd::tests;
42
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");
Junxiao Shi9d727852019-05-14 13:44:22 -060057 interest.setCanBePrefix(false);
Eric Newberry41aba102017-11-01 16:42:13 -070058 lp::Packet pkt;
Davide Pesaventof190cfa2019-07-17 20:14:11 -040059 pkt.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
Eric Newberry32f7eac2020-02-07 14:40:17 -080060 assignSequences(frags);
Eric Newberry41aba102017-11-01 16:42:13 -070061 m_reliability.handleOutgoing(frags, std::move(pkt), true);
Eric Newberry185ab292017-03-28 06:45:39 +000062 }
63
Davide Pesaventof190cfa2019-07-17 20:14:11 -040064 for (auto frag : frags) {
ashiqopu075bb7d2019-03-10 01:38:21 +000065 this->sendLpPacket(std::move(frag), 0);
Eric Newberry185ab292017-03-28 06:45:39 +000066 }
67 }
68
69private:
70 void
ashiqopu075bb7d2019-03-10 01:38:21 +000071 doSendInterest(const Interest&, const EndpointId&) final
Eric Newberry185ab292017-03-28 06:45:39 +000072 {
Davide Pesavento5a897692019-10-31 01:28:43 -040073 BOOST_FAIL("unexpected doSendInterest");
Eric Newberry185ab292017-03-28 06:45:39 +000074 }
75
76 void
ashiqopu075bb7d2019-03-10 01:38:21 +000077 doSendData(const Data&, const EndpointId&) final
Eric Newberry185ab292017-03-28 06:45:39 +000078 {
Davide Pesavento5a897692019-10-31 01:28:43 -040079 BOOST_FAIL("unexpected doSendData");
Eric Newberry185ab292017-03-28 06:45:39 +000080 }
81
82 void
ashiqopu075bb7d2019-03-10 01:38:21 +000083 doSendNack(const lp::Nack&, const EndpointId&) final
Eric Newberry185ab292017-03-28 06:45:39 +000084 {
Davide Pesavento5a897692019-10-31 01:28:43 -040085 BOOST_FAIL("unexpected doSendNack");
Eric Newberry185ab292017-03-28 06:45:39 +000086 }
87
88 void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040089 doReceivePacket(const Block&, const EndpointId&) final
Eric Newberry185ab292017-03-28 06:45:39 +000090 {
Davide Pesavento5a897692019-10-31 01:28:43 -040091 BOOST_FAIL("unexpected doReceivePacket");
Eric Newberry185ab292017-03-28 06:45:39 +000092 }
93};
94
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040095class LpReliabilityFixture : public GlobalIoTimeFixture
Eric Newberry185ab292017-03-28 06:45:39 +000096{
97public:
98 LpReliabilityFixture()
99 : linkService(make_unique<DummyLpReliabilityLinkService>())
100 , transport(make_unique<DummyTransport>())
101 , face(make_unique<DummyFace>())
102 {
103 linkService->setFaceAndTransport(*face, *transport);
104 transport->setFaceAndLinkService(*face, *linkService);
105
106 GenericLinkService::Options options;
107 options.reliabilityOptions.isEnabled = true;
108 linkService->setOptions(options);
109
110 reliability = linkService->getLpReliability();
Eric Newberry7b0071e2017-07-03 17:33:31 +0000111 reliability->m_lastTxSeqNo = 1;
112 }
113
114 static bool
115 netPktHasUnackedFrag(const shared_ptr<LpReliability::NetPkt>& netPkt, lp::Sequence txSeq)
116 {
117 return std::any_of(netPkt->unackedFrags.begin(), netPkt->unackedFrags.end(),
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400118 [txSeq] (auto fragIt) { return fragIt->first == txSeq; });
Eric Newberry7b0071e2017-07-03 17:33:31 +0000119 }
120
Eric Newberry7b0071e2017-07-03 17:33:31 +0000121 /** \brief make an LpPacket with fragment of specified size
Eric Newberry32f7eac2020-02-07 14:40:17 -0800122 * \param pktNum packet identifier, which can be extracted with \p getPktNum
Eric Newberry7b0071e2017-07-03 17:33:31 +0000123 * \param payloadSize total payload size; if this is less than 4, 4 will be used
124 */
125 static lp::Packet
Eric Newberry32f7eac2020-02-07 14:40:17 -0800126 makeFrag(uint32_t pktNum, size_t payloadSize = 4)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000127 {
128 payloadSize = std::max(payloadSize, static_cast<size_t>(4));
129 BOOST_ASSERT(payloadSize <= 255);
130
131 lp::Packet pkt;
132 ndn::Buffer buf(payloadSize);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800133 std::memcpy(buf.data(), &pktNum, sizeof(pktNum));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400134 pkt.set<lp::FragmentField>({buf.cbegin(), buf.cend()});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000135 return pkt;
136 }
137
138 /** \brief extract packet identifier from LpPacket made with \p makeFrag
139 * \retval 0 packet identifier cannot be extracted
140 */
141 static uint32_t
Eric Newberry32f7eac2020-02-07 14:40:17 -0800142 getPktNum(const lp::Packet& pkt)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000143 {
144 BOOST_ASSERT(pkt.has<lp::FragmentField>());
145
146 ndn::Buffer::const_iterator begin, end;
147 std::tie(begin, end) = pkt.get<lp::FragmentField>();
148 if (std::distance(begin, end) < 4) {
149 return 0;
150 }
151
152 uint32_t value = 0;
153 std::memcpy(&value, &*begin, sizeof(value));
154 return value;
Eric Newberry185ab292017-03-28 06:45:39 +0000155 }
156
Eric Newberry971d9622018-03-30 23:29:26 -0700157protected:
Eric Newberry185ab292017-03-28 06:45:39 +0000158 unique_ptr<DummyLpReliabilityLinkService> linkService;
159 unique_ptr<DummyTransport> transport;
160 unique_ptr<DummyFace> face;
161 LpReliability* reliability;
162};
163
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400164BOOST_AUTO_TEST_SUITE(Face)
Eric Newberry185ab292017-03-28 06:45:39 +0000165BOOST_FIXTURE_TEST_SUITE(TestLpReliability, LpReliabilityFixture)
166
167BOOST_AUTO_TEST_CASE(SendNoFragmentField)
168{
169 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000170
171 linkService->sendLpPackets({pkt});
172 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000173 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700174 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
175 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
176 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700177 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000178}
179
Eric Newberry7b0071e2017-07-03 17:33:31 +0000180BOOST_AUTO_TEST_CASE(SendUnfragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000181{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000182 lp::Packet pkt1 = makeFrag(1024, 50);
183 lp::Packet pkt2 = makeFrag(3000, 30);
Eric Newberry185ab292017-03-28 06:45:39 +0000184
185 linkService->sendLpPackets({pkt1});
Eric Newberry971d9622018-03-30 23:29:26 -0700186 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000187 lp::Packet cached1(transport->sentPackets.front().packet);
188 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
Eric Newberry32f7eac2020-02-07 14:40:17 -0800189 BOOST_CHECK(cached1.has<lp::SequenceField>());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000190 lp::Sequence firstTxSeq = cached1.get<lp::TxSequenceField>();
Eric Newberry971d9622018-03-30 23:29:26 -0700191 BOOST_CHECK_EQUAL(firstTxSeq, 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800192 BOOST_CHECK_EQUAL(getPktNum(cached1), 1024);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700193 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
194 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
195 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700196 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000197
Eric Newberry185ab292017-03-28 06:45:39 +0000198 // T+500ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000199 // 1024 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400200 advanceClocks(1_ms, 500);
Eric Newberry185ab292017-03-28 06:45:39 +0000201 linkService->sendLpPackets({pkt2});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000202 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
Eric Newberry185ab292017-03-28 06:45:39 +0000203
Eric Newberry00d39fd2017-12-10 14:26:45 -0700204 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
205 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 1);
206 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000207 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq).netPkt);
208 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
209 BOOST_CHECK_NE(reliability->m_unackedFrags.at(firstTxSeq).netPkt,
Eric Newberry971d9622018-03-30 23:29:26 -0700210 reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000211 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).retxCount, 0);
212 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
213 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq);
214 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700215 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
216 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
217 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700218 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000219
220 // T+1250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000221 // 1024 rto: 1000ms, txSeq: 4, started T+1000ms, retx 1
222 // 3000 rto: 1000ms, txSeq: 3, started T+500ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400223 advanceClocks(1_ms, 750);
Eric Newberry185ab292017-03-28 06:45:39 +0000224
Eric Newberry00d39fd2017-12-10 14:26:45 -0700225 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000226 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700227 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000228 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 2).retxCount, 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700229 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000230 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
231 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 1);
232 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700233 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
234 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
235 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700236 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000237
238 // T+2250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000239 // 1024 rto: 1000ms, txSeq: 6, started T+2000ms, retx 2
240 // 3000 rto: 1000ms, txSeq: 5, started T+1500ms, retx 1
Davide Pesavento14e71f02019-03-28 17:35:25 -0400241 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000242
Eric Newberry00d39fd2017-12-10 14:26:45 -0700243 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000244 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 0);
245 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700246 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000247 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 4).retxCount, 2);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700248 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000249 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 3).retxCount, 1);
250 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 3);
251 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700252 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
253 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
254 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700255 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000256
257 // T+3250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000258 // 1024 rto: 1000ms, txSeq: 8, started T+3000ms, retx 3
259 // 3000 rto: 1000ms, txSeq: 7, started T+2500ms, retx 2
Davide Pesavento14e71f02019-03-28 17:35:25 -0400260 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000261
Eric Newberry00d39fd2017-12-10 14:26:45 -0700262 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000263 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 0);
264 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700265 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000266 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 6).retxCount, 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700267 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000268 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 5).retxCount, 2);
269 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 5);
270 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 7);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700271 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
272 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
273 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700274 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000275
276 // T+4250ms
277 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000278 // 3000 rto: 1000ms, txSeq: 9, started T+3500ms, retx 3
Davide Pesavento14e71f02019-03-28 17:35:25 -0400279 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000280
Eric Newberry00d39fd2017-12-10 14:26:45 -0700281 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000282 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 0);
283 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700284 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 7), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000285 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 7).retxCount, 3);
286 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 7);
287 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry185ab292017-03-28 06:45:39 +0000288
Eric Newberry00d39fd2017-12-10 14:26:45 -0700289 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
290 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
291 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 1);
Eric Newberry41aba102017-11-01 16:42:13 -0700292 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 1);
293
Eric Newberry185ab292017-03-28 06:45:39 +0000294 // T+4750ms
295 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000296 // 3000 rto: expired, removed
Davide Pesavento14e71f02019-03-28 17:35:25 -0400297 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000298
299 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000300 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
301 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700302 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
303 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
304 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 2);
Eric Newberry41aba102017-11-01 16:42:13 -0700305 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 2);
Eric Newberry185ab292017-03-28 06:45:39 +0000306}
307
Eric Newberry7b0071e2017-07-03 17:33:31 +0000308BOOST_AUTO_TEST_CASE(SendFragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000309{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000310 lp::Packet pkt1 = makeFrag(2048, 30);
311 lp::Packet pkt2 = makeFrag(2049, 30);
312 lp::Packet pkt3 = makeFrag(2050, 10);
Eric Newberry185ab292017-03-28 06:45:39 +0000313
Eric Newberry7b0071e2017-07-03 17:33:31 +0000314 linkService->sendLpPackets({pkt1, pkt2, pkt3});
315 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000316
Eric Newberry7b0071e2017-07-03 17:33:31 +0000317 lp::Packet cached1(transport->sentPackets.at(0).packet);
318 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
319 BOOST_CHECK_EQUAL(cached1.get<lp::TxSequenceField>(), 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800320 BOOST_CHECK(cached1.has<lp::SequenceField>());
321 BOOST_CHECK_EQUAL(getPktNum(cached1), 2048);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000322 lp::Packet cached2(transport->sentPackets.at(1).packet);
323 BOOST_REQUIRE(cached2.has<lp::TxSequenceField>());
324 BOOST_CHECK_EQUAL(cached2.get<lp::TxSequenceField>(), 3);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800325 BOOST_CHECK(cached2.has<lp::SequenceField>());
326 BOOST_CHECK_EQUAL(getPktNum(cached2), 2049);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000327 lp::Packet cached3(transport->sentPackets.at(2).packet);
328 BOOST_REQUIRE(cached3.has<lp::TxSequenceField>());
329 BOOST_CHECK_EQUAL(cached3.get<lp::TxSequenceField>(), 4);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800330 BOOST_CHECK(cached3.has<lp::SequenceField>());
331 BOOST_CHECK_EQUAL(getPktNum(cached3), 2050);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700332 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
333 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
334 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700335 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000336
Eric Newberry7b0071e2017-07-03 17:33:31 +0000337 // T+0ms
338 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
339 // 2049 rto: 1000ms, txSeq: 3, started T+0ms, retx 0
340 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Eric Newberry185ab292017-03-28 06:45:39 +0000341
Eric Newberry00d39fd2017-12-10 14:26:45 -0700342 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
343 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1);
344 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800345 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
346 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(3).pkt), 2049);
347 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000348 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
349 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
350 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
351 BOOST_REQUIRE(reliability->m_unackedFrags.at(3).netPkt);
352 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
353 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
354 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(3).netPkt);
355 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
356 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
357 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
358 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
359 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
360 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
361 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
362 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700363 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
364 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
365 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700366 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000367
Eric Newberry7b0071e2017-07-03 17:33:31 +0000368 // T+250ms
369 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
370 // 2049 rto: 1000ms, txSeq: 5, started T+250ms, retx 1
371 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400372 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800373 reliability->onLpPacketLost(3, true);
Eric Newberry185ab292017-03-28 06:45:39 +0000374
Eric Newberry00d39fd2017-12-10 14:26:45 -0700375 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000376 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700377 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 1);
378 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800379 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
380 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(5).pkt), 2049);
381 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000382 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
383 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
384 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(5).retxCount, 1);
385 BOOST_REQUIRE(reliability->m_unackedFrags.at(5).netPkt);
386 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
387 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
388 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(5).netPkt);
389 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
390 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
391 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
392 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
393 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
394 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
395 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
396 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700397 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
398 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
399 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700400 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000401
402 // T+500ms
403 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
404 // 2049 rto: 1000ms, txSeq: 6, started T+500ms, retx 2
405 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400406 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800407 reliability->onLpPacketLost(5, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000408
Eric Newberry00d39fd2017-12-10 14:26:45 -0700409 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000410 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700411 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 1);
412 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800413 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
414 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(6).pkt), 2049);
415 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000416 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
417 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
418 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(6).retxCount, 2);
419 BOOST_REQUIRE(reliability->m_unackedFrags.at(6).netPkt);
420 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
421 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
422 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(6).netPkt);
423 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
424 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
425 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
426 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
427 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
428 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
429 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
430 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700431 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
432 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
433 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700434 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000435
436 // T+750ms
437 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
438 // 2049 rto: 1000ms, txSeq: 7, started T+750ms, retx 3
439 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400440 advanceClocks(1_ms, 250);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800441 reliability->onLpPacketLost(6, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000442
443 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 1);
444 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700445 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(7), 1);
446 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800447 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(2).pkt), 2048);
448 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(7).pkt), 2049);
449 BOOST_CHECK_EQUAL(getPktNum(reliability->m_unackedFrags.at(4).pkt), 2050);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000450 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
451 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
452 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(7).retxCount, 3);
453 BOOST_REQUIRE(reliability->m_unackedFrags.at(7).netPkt);
454 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
455 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
456 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(7).netPkt);
457 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
458 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
459 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
460 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
461 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 7));
462 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
463 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
464 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700465 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
466 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
467 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700468 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000469
470 // T+850ms
471 // 2048 rto: expired, removed
472 // 2049 rto: expired, removed
473 // 2050 rto: expired, removed
Davide Pesavento14e71f02019-03-28 17:35:25 -0400474 advanceClocks(1_ms, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800475 reliability->onLpPacketLost(7, true);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000476
477 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
478 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700479 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
480 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
481 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 1);
Eric Newberry41aba102017-11-01 16:42:13 -0700482 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000483}
484
Eric Newberry00d39fd2017-12-10 14:26:45 -0700485BOOST_AUTO_TEST_CASE(AckUnknownTxSeq)
486{
487 linkService->sendLpPackets({makeFrag(1, 50)});
488
489 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
490 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
491 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
492 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
493 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
494 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
495 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
496 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
497 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
498
499 lp::Packet ackPkt;
500 ackPkt.add<lp::AckField>(10101010);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800501 BOOST_CHECK(reliability->processIncomingPacket(ackPkt));
Eric Newberry00d39fd2017-12-10 14:26:45 -0700502
503 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
504 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
505 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
506 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
507 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
508 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
509 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
510 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
511 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
512}
513
Eric Newberry971d9622018-03-30 23:29:26 -0700514BOOST_AUTO_TEST_CASE(LossByGreaterAcks)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000515{
Eric Newberry971d9622018-03-30 23:29:26 -0700516 // Detect loss by 3x greater Acks, also tests wraparound
517
Eric Newberry7b0071e2017-07-03 17:33:31 +0000518 reliability->m_lastTxSeqNo = 0xFFFFFFFFFFFFFFFE;
519
Eric Newberry971d9622018-03-30 23:29:26 -0700520 // Passed to sendLpPackets individually since they are
521 // from separate, non-fragmented network packets
Eric Newberry7b0071e2017-07-03 17:33:31 +0000522 linkService->sendLpPackets({makeFrag(1, 50)});
523 linkService->sendLpPackets({makeFrag(2, 50)});
524 linkService->sendLpPackets({makeFrag(3, 50)});
525 linkService->sendLpPackets({makeFrag(4, 50)});
526 linkService->sendLpPackets({makeFrag(5, 50)});
Eric Newberry185ab292017-03-28 06:45:39 +0000527
528 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000529 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
530 BOOST_CHECK(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).netPkt);
531 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 1); // pkt2
532 BOOST_CHECK(reliability->m_unackedFrags.at(0).netPkt);
533 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
534 BOOST_CHECK(reliability->m_unackedFrags.at(1).netPkt);
535 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
536 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
537 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
538 BOOST_CHECK(reliability->m_unackedFrags.at(3).netPkt);
Eric Newberry185ab292017-03-28 06:45:39 +0000539 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700540 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
541 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
542 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700543 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000544
545 lp::Packet ackPkt1;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000546 ackPkt1.add<lp::AckField>(0);
Eric Newberry185ab292017-03-28 06:45:39 +0000547
548 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
549
Eric Newberry32f7eac2020-02-07 14:40:17 -0800550 BOOST_CHECK(reliability->processIncomingPacket(ackPkt1));
Eric Newberry185ab292017-03-28 06:45:39 +0000551
552 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700553 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000554 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
555 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000556 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700557 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000558 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
559 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700560 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
Eric Newberry7b0071e2017-07-03 17:33:31 +0000561 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
562 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700563 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000564 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
565 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000566 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000567 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700568 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
569 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
570 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700571 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000572
573 lp::Packet ackPkt2;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000574 ackPkt2.add<lp::AckField>(2);
575 ackPkt1.add<lp::AckField>(101010); // Unknown TxSequence number - ignored
Eric Newberry185ab292017-03-28 06:45:39 +0000576
577 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
578
Eric Newberry32f7eac2020-02-07 14:40:17 -0800579 BOOST_CHECK(reliability->processIncomingPacket(ackPkt2));
Eric Newberry185ab292017-03-28 06:45:39 +0000580
581 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000582 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000583 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
584 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000585 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700586 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000587 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
588 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700589 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
590 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000591 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
592 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
593 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(101010), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000594 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000595 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700596 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 2);
597 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
598 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700599 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000600
601 lp::Packet ackPkt3;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000602 ackPkt3.add<lp::AckField>(1);
Eric Newberry185ab292017-03-28 06:45:39 +0000603
604 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
605
Eric Newberry32f7eac2020-02-07 14:40:17 -0800606 BOOST_CHECK(reliability->processIncomingPacket(ackPkt3));
Eric Newberry185ab292017-03-28 06:45:39 +0000607
608 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000609 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
610 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
611 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
612 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700613 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000614 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
615 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700616 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1); // pkt1 new TxSeq
Eric Newberry7b0071e2017-07-03 17:33:31 +0000617 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 1);
618 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).nGreaterSeqAcks, 0);
619 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000620 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry185ab292017-03-28 06:45:39 +0000621 lp::Packet sentRetxPkt(transport->sentPackets.back().packet);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000622 BOOST_REQUIRE(sentRetxPkt.has<lp::TxSequenceField>());
623 BOOST_CHECK_EQUAL(sentRetxPkt.get<lp::TxSequenceField>(), 4);
624 BOOST_REQUIRE(sentRetxPkt.has<lp::FragmentField>());
Eric Newberry32f7eac2020-02-07 14:40:17 -0800625 BOOST_CHECK_EQUAL(getPktNum(sentRetxPkt), 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700626 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
627 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
628 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700629 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000630
631 lp::Packet ackPkt4;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000632 ackPkt4.add<lp::AckField>(4);
Eric Newberry185ab292017-03-28 06:45:39 +0000633
634 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
635
Eric Newberry32f7eac2020-02-07 14:40:17 -0800636 BOOST_CHECK(reliability->processIncomingPacket(ackPkt4));
Eric Newberry185ab292017-03-28 06:45:39 +0000637
638 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000639 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
640 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
641 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
642 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700643 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000644 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
645 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 1);
646 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 0); // pkt1 new TxSeq
647 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000648 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700649 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
650 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 1);
651 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
652 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
653}
654
Eric Newberry971d9622018-03-30 23:29:26 -0700655BOOST_AUTO_TEST_CASE(SkipFragmentsRemovedInRtt)
656{
657 auto opts = linkService->getOptions();
658 opts.reliabilityOptions.maxRetx = 0; // just to make the test case shorter
659 opts.reliabilityOptions.seqNumLossThreshold = 3;
660 linkService->setOptions(opts);
661
662 lp::Packet frag1 = makeFrag(5001);
663 lp::Packet frag2 = makeFrag(5002);
664 linkService->sendLpPackets({frag1, frag2}); // First packet has 2 fragments
665 linkService->sendLpPackets({makeFrag(5003)});
666 linkService->sendLpPackets({makeFrag(5004)});
667 linkService->sendLpPackets({makeFrag(5005)});
668
669 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
670 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
671
672 lp::Sequence firstTxSeq = reliability->m_firstUnackedFrag->first;
673
674 // Ack the last 2 packets
675 lp::Packet ackPkt1;
676 ackPkt1.add<lp::AckField>(firstTxSeq + 4);
677 ackPkt1.add<lp::AckField>(firstTxSeq + 3);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800678 BOOST_CHECK(reliability->processIncomingPacket(ackPkt1));
Eric Newberry971d9622018-03-30 23:29:26 -0700679
680 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
681 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).nGreaterSeqAcks, 2);
682 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).nGreaterSeqAcks, 2);
683
684 // Ack the third packet (5003)
685 // This triggers a "loss by greater Acks" for packets 5001 and 5002
686 lp::Packet ackPkt2;
687 ackPkt2.add<lp::AckField>(firstTxSeq + 2);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800688 BOOST_CHECK(reliability->processIncomingPacket(ackPkt2)); // tests crash/assert reported in bug #4479
Eric Newberry971d9622018-03-30 23:29:26 -0700689
690 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
691}
692
Eric Newberry00d39fd2017-12-10 14:26:45 -0700693BOOST_AUTO_TEST_CASE(CancelLossNotificationOnAck)
694{
695 reliability->onDroppedInterest.connect([] (const Interest&) {
696 BOOST_FAIL("Packet loss timeout should be cancelled when packet acknowledged");
697 });
698
699 reliability->m_lastTxSeqNo = 0;
700
701 linkService->sendLpPackets({makeFrag(1, 50)});
702
Davide Pesavento14e71f02019-03-28 17:35:25 -0400703 advanceClocks(1_ms, 500);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700704
705 lp::Packet ackPkt;
706 ackPkt.add<lp::AckField>(1);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800707 BOOST_CHECK(reliability->processIncomingPacket(ackPkt));
Eric Newberry00d39fd2017-12-10 14:26:45 -0700708
Davide Pesavento14e71f02019-03-28 17:35:25 -0400709 advanceClocks(1_ms, 1000);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700710
711 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
712 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
713 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700714 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000715}
716
Eric Newberry7b0071e2017-07-03 17:33:31 +0000717BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
718{
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400719 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000720 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
721
722 lp::Packet pkt1 = makeFrag(100, 40);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800723 pkt1.add<lp::SequenceField>(123456);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000724 pkt1.add<lp::TxSequenceField>(765432);
725
Eric Newberry32f7eac2020-02-07 14:40:17 -0800726 BOOST_CHECK(reliability->processIncomingPacket(pkt1));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000727
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400728 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000729 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
730 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800731 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
732 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(123456), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000733
734 lp::Packet pkt2 = makeFrag(276, 40);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800735 pkt2.add<lp::SequenceField>(654321);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000736 pkt2.add<lp::TxSequenceField>(234567);
737
Eric Newberry32f7eac2020-02-07 14:40:17 -0800738 BOOST_CHECK(reliability->processIncomingPacket(pkt2));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000739
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400740 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000741 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
742 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
743 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 234567);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800744 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
745 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(123456), 1);
746 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(654321), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000747
748 // T+5ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400749 advanceClocks(1_ms, 5);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400750 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000751}
752
753BOOST_AUTO_TEST_CASE(PiggybackAcks)
754{
755 reliability->m_ackQueue.push(256);
756 reliability->m_ackQueue.push(257);
757 reliability->m_ackQueue.push(10);
758
759 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000760 linkService->sendLpPackets({pkt});
761
762 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
763 lp::Packet sentPkt(transport->sentPackets.front().packet);
764
765 BOOST_REQUIRE_EQUAL(sentPkt.count<lp::AckField>(), 3);
766 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(0), 256);
767 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(1), 257);
768 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(2), 10);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000769 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Eric Newberry185ab292017-03-28 06:45:39 +0000770
771 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
772}
773
774BOOST_AUTO_TEST_CASE(PiggybackAcksMtu)
775{
Eric Newberry32f7eac2020-02-07 14:40:17 -0800776 // MTU is 1500, payload has 60 octets plus 6 octets for LpPacket and Fragment TL and 10 octets
777 // each for Sequence and TxSequence, leaving 1414 octets for piggybacking. Each Ack header is 12
778 // octets, so each LpPacket can carry 117 Acks, and it takes 9 LpPackets for 1000 Acks.
Eric Newberry185ab292017-03-28 06:45:39 +0000779
Eric Newberry7b0071e2017-07-03 17:33:31 +0000780 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000781
Junxiao Shi21e01932018-04-21 10:39:05 +0000782 std::unordered_set<lp::Sequence> expectedAcks;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000783 for (lp::Sequence i = 1000; i < 2000; i++) {
784 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000785 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000786 }
Eric Newberry185ab292017-03-28 06:45:39 +0000787
Junxiao Shi21e01932018-04-21 10:39:05 +0000788 for (uint32_t i = 1; i <= 9; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000789 lp::Packet pkt = makeFrag(i, 60);
790 linkService->sendLpPackets({pkt});
Eric Newberry185ab292017-03-28 06:45:39 +0000791
Junxiao Shi21e01932018-04-21 10:39:05 +0000792 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000793 lp::Packet sentPkt(transport->sentPackets.back().packet);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800794 BOOST_CHECK_EQUAL(getPktNum(sentPkt), i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000795 BOOST_CHECK(sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000796
797 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
798 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
799 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000800 }
Eric Newberry185ab292017-03-28 06:45:39 +0000801
Eric Newberry7b0071e2017-07-03 17:33:31 +0000802 BOOST_CHECK(reliability->m_ackQueue.empty());
Junxiao Shi21e01932018-04-21 10:39:05 +0000803 BOOST_CHECK(expectedAcks.empty());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000804}
Eric Newberry185ab292017-03-28 06:45:39 +0000805
Eric Newberry7b0071e2017-07-03 17:33:31 +0000806BOOST_AUTO_TEST_CASE(PiggybackAcksMtuNoSpace)
807{
Eric Newberry32f7eac2020-02-07 14:40:17 -0800808 // MTU is 64, payload has 34 octets plus 4 octets for LpPacket and Fragment TL and 10 octets each
809 // for Sequence and TxSequence, leaving 6 octets for piggybacking. Each Ack header is 12 octets,
810 // so there's no room to piggyback any Ack in LpPacket.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000811
Eric Newberrycb6551e2020-03-02 14:12:16 -0800812 transport->setMtu(MIN_MTU);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000813
814 for (lp::Sequence i = 1000; i < 1100; i++) {
815 reliability->m_ackQueue.push(i);
816 }
817
Eric Newberry32f7eac2020-02-07 14:40:17 -0800818 lp::Packet pkt = makeFrag(1, 34);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000819 linkService->sendLpPackets({pkt});
820
Eric Newberry185ab292017-03-28 06:45:39 +0000821 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000822 lp::Packet sentPkt(transport->sentPackets.back().packet);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800823 BOOST_CHECK_EQUAL(getPktNum(sentPkt), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000824 BOOST_CHECK(!sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000825
826 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 100);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000827}
Eric Newberry185ab292017-03-28 06:45:39 +0000828
Eric Newberry7b0071e2017-07-03 17:33:31 +0000829BOOST_AUTO_TEST_CASE(StartIdleAckTimer)
830{
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 lp::Packet pkt1 = makeFrag(1, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800834 pkt1.add<lp::SequenceField>(1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000835 pkt1.add<lp::TxSequenceField>(12);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800836 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400837 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000838
Eric Newberry7b0071e2017-07-03 17:33:31 +0000839 // T+1ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400840 advanceClocks(1_ms, 1);
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 lp::Packet pkt2 = makeFrag(2, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800844 pkt2.add<lp::SequenceField>(2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000845 pkt2.add<lp::TxSequenceField>(13);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800846 BOOST_CHECK(reliability->processIncomingPacket({pkt2}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400847 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000848
Eric Newberry7b0071e2017-07-03 17:33:31 +0000849 // T+5ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400850 advanceClocks(1_ms, 4);
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 lp::Packet pkt3 = makeFrag(3, 100);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800854 pkt3.add<lp::SequenceField>(3);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000855 pkt3.add<lp::TxSequenceField>(15);
Eric Newberry32f7eac2020-02-07 14:40:17 -0800856 BOOST_CHECK(reliability->processIncomingPacket({pkt3}));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400857 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000858
Eric Newberry7b0071e2017-07-03 17:33:31 +0000859 // T+9ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400860 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400861 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000862
Eric Newberry7b0071e2017-07-03 17:33:31 +0000863 // T+10ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400864 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400865 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000866}
867
868BOOST_AUTO_TEST_CASE(IdleAckTimer)
869{
Junxiao Shi21e01932018-04-21 10:39:05 +0000870 // T+0ms: populate ack queue and start idle ack timer
871 std::unordered_set<lp::Sequence> expectedAcks;
872 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000873 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000874 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000875 }
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400876 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000877 reliability->startIdleAckTimer();
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400878 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000879
Junxiao Shi21e01932018-04-21 10:39:05 +0000880 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400881 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400882 BOOST_CHECK(reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000883 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000884 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
Junxiao Shi21e01932018-04-21 10:39:05 +0000885 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000886 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
887
Junxiao Shi21e01932018-04-21 10:39:05 +0000888 // T+5ms: idle ack timer expires, IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400889 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400890 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000891 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000892 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry185ab292017-03-28 06:45:39 +0000893
Junxiao Shi21e01932018-04-21 10:39:05 +0000894 lp::Packet sentPkt(transport->sentPackets.back().packet);
895 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
896 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
897 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000898 }
Junxiao Shi21e01932018-04-21 10:39:05 +0000899 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000900}
901
902BOOST_AUTO_TEST_CASE(IdleAckTimerMtu)
903{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000904 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000905
Junxiao Shi21e01932018-04-21 10:39:05 +0000906 // T+0ms: populate ack queue and start idle ack timer
907 std::unordered_set<lp::Sequence> expectedAcks;
908 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000909 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000910 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000911 }
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400912 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000913 reliability->startIdleAckTimer();
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400914 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000915
Junxiao Shi21e01932018-04-21 10:39:05 +0000916 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400917 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400918 BOOST_CHECK(reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000919 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
920 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
921 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000922 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
923
Junxiao Shi21e01932018-04-21 10:39:05 +0000924 // T+5ms: idle ack timer expires, IDLE packets generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400925 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400926 BOOST_CHECK(!reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000927 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000928
Junxiao Shi21e01932018-04-21 10:39:05 +0000929 // MTU is 1500. LpPacket TL occupies 4 octets. Each Ack header is 12 octets. There are room for
930 // 124 Acks per LpPacket, and it takes 5 LpPackets to carry 500 Acks.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000931 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Junxiao Shi21e01932018-04-21 10:39:05 +0000932 for (size_t i = 0; i < 5; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000933 lp::Packet sentPkt(transport->sentPackets[i].packet);
934 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000935 BOOST_CHECK_EQUAL(sentPkt.count<lp::AckField>(), i == 4 ? 4 : 124);
936 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
937 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
938 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000939 }
940
Junxiao Shi21e01932018-04-21 10:39:05 +0000941 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000942}
943
Eric Newberry32f7eac2020-02-07 14:40:17 -0800944BOOST_AUTO_TEST_CASE(TrackRecentReceivedLpPackets)
945{
946 lp::Packet pkt1 = makeFrag(1, 100);
947 pkt1.add<lp::SequenceField>(7);
948 pkt1.add<lp::TxSequenceField>(12);
949 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
950 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 1);
951 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 7);
952 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
953 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
954
955 // T+500ms
956 // Estimated RTO starts at 1000ms and we are not adding any measurements, so it should remain
957 // this value throughout the test case
958 advanceClocks(500_ms, 1);
959 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
960 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
961 lp::Packet pkt2 = makeFrag(1, 100);
962 pkt2.add<lp::SequenceField>(23);
963 pkt2.add<lp::TxSequenceField>(13);
964 BOOST_CHECK(reliability->processIncomingPacket({pkt2}));
965 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
966 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 7);
967 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
968 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
969 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(23), 1);
970
971 // T+1250ms
972 // First received sequence should be removed after next received packet, but second should remain
973 advanceClocks(750_ms, 1);
974 lp::Packet pkt3 = makeFrag(1, 100);
975 pkt3.add<lp::SequenceField>(24);
976 pkt3.add<lp::TxSequenceField>(14);
977 BOOST_CHECK(reliability->processIncomingPacket({pkt3}));
978 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
979 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 23);
980 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
981 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(23), 1);
982 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(24), 1);
983
984 // T+1750ms
985 // Second received sequence should be removed
986 advanceClocks(500_ms, 1);
987 lp::Packet pkt4 = makeFrag(1, 100);
988 pkt4.add<lp::SequenceField>(25);
989 pkt4.add<lp::TxSequenceField>(15);
990 BOOST_CHECK(reliability->processIncomingPacket({pkt4}));
991 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.size(), 2);
992 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqsQueue.front(), 24);
993 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 2);
994 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(24), 1);
995 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(25), 1);
996}
997
998BOOST_AUTO_TEST_CASE(DropDuplicateReceivedSequence)
999{
1000 Interest interest("/test/prefix");
1001 interest.setCanBePrefix(false);
1002 lp::Packet pkt1;
1003 pkt1.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
1004 pkt1.add<lp::SequenceField>(7);
1005 pkt1.add<lp::TxSequenceField>(12);
1006 BOOST_CHECK(reliability->processIncomingPacket({pkt1}));
1007 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
1008 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
1009
1010 lp::Packet pkt2;
1011 pkt2.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
1012 pkt2.add<lp::SequenceField>(7);
1013 pkt2.add<lp::TxSequenceField>(13);
1014 BOOST_CHECK(!reliability->processIncomingPacket({pkt2}));
1015 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.size(), 1);
1016 BOOST_CHECK_EQUAL(reliability->m_recentRecvSeqs.count(7), 1);
1017}
1018
1019BOOST_AUTO_TEST_CASE(DropDuplicateAckForRetx)
1020{
1021 lp::Packet pkt1 = makeFrag(1024, 50);
1022 linkService->sendLpPackets({pkt1});
1023
1024 // Will send out a single fragment
1025 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
1026 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
1027 lp::Sequence firstTxSeq = reliability->m_firstUnackedFrag->first;
1028
1029 // RTO is initially 1 second, so will time out and retx
1030 advanceClocks(1250_ms, 1);
1031 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
1032 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
1033
1034 // Acknowledge first transmission (RTO underestimation)
1035 // Ack will be dropped because unknown
1036 lp::Packet ackPkt1;
1037 ackPkt1.add<lp::AckField>(firstTxSeq);
1038 reliability->processIncomingPacket(ackPkt1);
1039 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.size(), 1); // Required because collection used below
1040
1041 // Acknowledge second transmission
1042 // Ack will acknowledge retx and remove unacked frag
1043 lp::Packet ackPkt2;
1044 ackPkt2.add<lp::AckField>(reliability->m_firstUnackedFrag->first);
1045 reliability->processIncomingPacket(ackPkt2);
1046 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
1047}
1048
Eric Newberry7b0071e2017-07-03 17:33:31 +00001049BOOST_AUTO_TEST_SUITE_END() // TestLpReliability
Eric Newberry185ab292017-03-28 06:45:39 +00001050BOOST_AUTO_TEST_SUITE_END() // Face
1051
1052} // namespace tests
1053} // namespace face
1054} // namespace nfd