blob: e814042e63b5eb1d7083d83fb86740e2439afc9a [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 Pesaventocf7db2f2019-03-24 23:17:28 -04003 * Copyright (c) 2014-2019, 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 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) {
ashiqopu075bb7d2019-03-10 01:38:21 +000064 this->sendLpPacket(std::move(frag), 0);
Eric Newberry185ab292017-03-28 06:45:39 +000065 }
66 }
67
68private:
69 void
ashiqopu075bb7d2019-03-10 01:38:21 +000070 doSendInterest(const Interest&, const EndpointId&) final
Eric Newberry185ab292017-03-28 06:45:39 +000071 {
72 BOOST_ASSERT(false);
73 }
74
75 void
ashiqopu075bb7d2019-03-10 01:38:21 +000076 doSendData(const Data&, const EndpointId&) final
Eric Newberry185ab292017-03-28 06:45:39 +000077 {
78 BOOST_ASSERT(false);
79 }
80
81 void
ashiqopu075bb7d2019-03-10 01:38:21 +000082 doSendNack(const lp::Nack&, const EndpointId&) final
Eric Newberry185ab292017-03-28 06:45:39 +000083 {
84 BOOST_ASSERT(false);
85 }
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 {
90 BOOST_ASSERT(false);
91 }
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
Eric Newberry7b0071e2017-07-03 17:33:31 +0000120 /** \brief make an LpPacket with fragment of specified size
121 * \param pktNo packet identifier, which can be extracted with \p getPktNo
122 * \param payloadSize total payload size; if this is less than 4, 4 will be used
123 */
124 static lp::Packet
125 makeFrag(uint32_t pktNo, size_t payloadSize = 4)
126 {
127 payloadSize = std::max(payloadSize, static_cast<size_t>(4));
128 BOOST_ASSERT(payloadSize <= 255);
129
130 lp::Packet pkt;
131 ndn::Buffer buf(payloadSize);
Davide Pesavento6d1c1c32017-10-08 21:44:05 -0400132 std::memcpy(buf.data(), &pktNo, sizeof(pktNo));
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400133 pkt.set<lp::FragmentField>({buf.cbegin(), buf.cend()});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000134 return pkt;
135 }
136
137 /** \brief extract packet identifier from LpPacket made with \p makeFrag
138 * \retval 0 packet identifier cannot be extracted
139 */
140 static uint32_t
141 getPktNo(const lp::Packet& pkt)
142 {
143 BOOST_ASSERT(pkt.has<lp::FragmentField>());
144
145 ndn::Buffer::const_iterator begin, end;
146 std::tie(begin, end) = pkt.get<lp::FragmentField>();
147 if (std::distance(begin, end) < 4) {
148 return 0;
149 }
150
151 uint32_t value = 0;
152 std::memcpy(&value, &*begin, sizeof(value));
153 return value;
Eric Newberry185ab292017-03-28 06:45:39 +0000154 }
155
Eric Newberry971d9622018-03-30 23:29:26 -0700156protected:
Eric Newberry185ab292017-03-28 06:45:39 +0000157 unique_ptr<DummyLpReliabilityLinkService> linkService;
158 unique_ptr<DummyTransport> transport;
159 unique_ptr<DummyFace> face;
160 LpReliability* reliability;
161};
162
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400163BOOST_AUTO_TEST_SUITE(Face)
Eric Newberry185ab292017-03-28 06:45:39 +0000164BOOST_FIXTURE_TEST_SUITE(TestLpReliability, LpReliabilityFixture)
165
166BOOST_AUTO_TEST_CASE(SendNoFragmentField)
167{
168 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000169
170 linkService->sendLpPackets({pkt});
171 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000172 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700173 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
174 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
175 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700176 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000177}
178
Eric Newberry7b0071e2017-07-03 17:33:31 +0000179BOOST_AUTO_TEST_CASE(SendUnfragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000180{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000181 lp::Packet pkt1 = makeFrag(1024, 50);
182 lp::Packet pkt2 = makeFrag(3000, 30);
Eric Newberry185ab292017-03-28 06:45:39 +0000183
184 linkService->sendLpPackets({pkt1});
Eric Newberry971d9622018-03-30 23:29:26 -0700185 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000186 lp::Packet cached1(transport->sentPackets.front().packet);
187 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000188 BOOST_CHECK(!cached1.has<lp::SequenceField>());
189 lp::Sequence firstTxSeq = cached1.get<lp::TxSequenceField>();
Eric Newberry971d9622018-03-30 23:29:26 -0700190 BOOST_CHECK_EQUAL(firstTxSeq, 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000191 BOOST_CHECK_EQUAL(getPktNo(cached1), 1024);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700192 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
193 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
194 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700195 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000196
Eric Newberry185ab292017-03-28 06:45:39 +0000197 // T+500ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000198 // 1024 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400199 advanceClocks(1_ms, 500);
Eric Newberry185ab292017-03-28 06:45:39 +0000200 linkService->sendLpPackets({pkt2});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000201 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
Eric Newberry185ab292017-03-28 06:45:39 +0000202
Eric Newberry00d39fd2017-12-10 14:26:45 -0700203 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
204 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 1);
205 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000206 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq).netPkt);
207 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
208 BOOST_CHECK_NE(reliability->m_unackedFrags.at(firstTxSeq).netPkt,
Eric Newberry971d9622018-03-30 23:29:26 -0700209 reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000210 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).retxCount, 0);
211 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
212 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq);
213 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700214 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
215 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
216 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700217 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000218
219 // T+1250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000220 // 1024 rto: 1000ms, txSeq: 4, started T+1000ms, retx 1
221 // 3000 rto: 1000ms, txSeq: 3, started T+500ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400222 advanceClocks(1_ms, 750);
Eric Newberry185ab292017-03-28 06:45:39 +0000223
Eric Newberry00d39fd2017-12-10 14:26:45 -0700224 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000225 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700226 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000227 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 2).retxCount, 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700228 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000229 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
230 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 1);
231 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700232 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
233 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
234 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700235 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000236
237 // T+2250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000238 // 1024 rto: 1000ms, txSeq: 6, started T+2000ms, retx 2
239 // 3000 rto: 1000ms, txSeq: 5, started T+1500ms, retx 1
Davide Pesavento14e71f02019-03-28 17:35:25 -0400240 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000241
Eric Newberry00d39fd2017-12-10 14:26:45 -0700242 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000243 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 0);
244 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700245 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000246 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 4).retxCount, 2);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700247 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000248 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 3).retxCount, 1);
249 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 3);
250 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700251 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
252 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
253 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700254 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000255
256 // T+3250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000257 // 1024 rto: 1000ms, txSeq: 8, started T+3000ms, retx 3
258 // 3000 rto: 1000ms, txSeq: 7, started T+2500ms, retx 2
Davide Pesavento14e71f02019-03-28 17:35:25 -0400259 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000260
Eric Newberry00d39fd2017-12-10 14:26:45 -0700261 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000262 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 0);
263 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700264 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000265 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 6).retxCount, 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700266 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000267 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 5).retxCount, 2);
268 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 5);
269 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 7);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700270 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
271 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
272 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700273 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000274
275 // T+4250ms
276 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000277 // 3000 rto: 1000ms, txSeq: 9, started T+3500ms, retx 3
Davide Pesavento14e71f02019-03-28 17:35:25 -0400278 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000279
Eric Newberry00d39fd2017-12-10 14:26:45 -0700280 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000281 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 0);
282 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700283 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 7), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000284 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 7).retxCount, 3);
285 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 7);
286 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry185ab292017-03-28 06:45:39 +0000287
Eric Newberry00d39fd2017-12-10 14:26:45 -0700288 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
289 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
290 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 1);
Eric Newberry41aba102017-11-01 16:42:13 -0700291 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 1);
292
Eric Newberry185ab292017-03-28 06:45:39 +0000293 // T+4750ms
294 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000295 // 3000 rto: expired, removed
Davide Pesavento14e71f02019-03-28 17:35:25 -0400296 advanceClocks(1_ms, 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000297
298 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000299 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
300 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700301 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
302 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
303 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 2);
Eric Newberry41aba102017-11-01 16:42:13 -0700304 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 2);
Eric Newberry185ab292017-03-28 06:45:39 +0000305}
306
Eric Newberry7b0071e2017-07-03 17:33:31 +0000307BOOST_AUTO_TEST_CASE(SendFragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000308{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000309 lp::Packet pkt1 = makeFrag(2048, 30);
310 lp::Packet pkt2 = makeFrag(2049, 30);
311 lp::Packet pkt3 = makeFrag(2050, 10);
Eric Newberry185ab292017-03-28 06:45:39 +0000312
Eric Newberry7b0071e2017-07-03 17:33:31 +0000313 linkService->sendLpPackets({pkt1, pkt2, pkt3});
314 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000315
Eric Newberry7b0071e2017-07-03 17:33:31 +0000316 lp::Packet cached1(transport->sentPackets.at(0).packet);
317 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
318 BOOST_CHECK_EQUAL(cached1.get<lp::TxSequenceField>(), 2);
319 BOOST_CHECK_EQUAL(getPktNo(cached1), 2048);
320 lp::Packet cached2(transport->sentPackets.at(1).packet);
321 BOOST_REQUIRE(cached2.has<lp::TxSequenceField>());
322 BOOST_CHECK_EQUAL(cached2.get<lp::TxSequenceField>(), 3);
323 BOOST_CHECK_EQUAL(getPktNo(cached2), 2049);
324 lp::Packet cached3(transport->sentPackets.at(2).packet);
325 BOOST_REQUIRE(cached3.has<lp::TxSequenceField>());
326 BOOST_CHECK_EQUAL(cached3.get<lp::TxSequenceField>(), 4);
327 BOOST_CHECK_EQUAL(getPktNo(cached3), 2050);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700328 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
329 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
330 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700331 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000332
Eric Newberry7b0071e2017-07-03 17:33:31 +0000333 // T+0ms
334 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
335 // 2049 rto: 1000ms, txSeq: 3, started T+0ms, retx 0
336 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Eric Newberry185ab292017-03-28 06:45:39 +0000337
Eric Newberry00d39fd2017-12-10 14:26:45 -0700338 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
339 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1);
340 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000341 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
342 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(3).pkt), 2049);
343 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
344 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
345 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
346 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
347 BOOST_REQUIRE(reliability->m_unackedFrags.at(3).netPkt);
348 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
349 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
350 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(3).netPkt);
351 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
352 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
353 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
354 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
355 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
356 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
357 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
358 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700359 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
360 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
361 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700362 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000363
Eric Newberry7b0071e2017-07-03 17:33:31 +0000364 // T+250ms
365 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
366 // 2049 rto: 1000ms, txSeq: 5, started T+250ms, retx 1
367 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400368 advanceClocks(1_ms, 250);
Eric Newberry971d9622018-03-30 23:29:26 -0700369 reliability->onLpPacketLost(3);
Eric Newberry185ab292017-03-28 06:45:39 +0000370
Eric Newberry00d39fd2017-12-10 14:26:45 -0700371 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000372 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700373 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 1);
374 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000375 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
376 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(5).pkt), 2049);
377 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
378 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
379 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
380 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(5).retxCount, 1);
381 BOOST_REQUIRE(reliability->m_unackedFrags.at(5).netPkt);
382 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
383 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
384 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(5).netPkt);
385 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
386 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
387 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
388 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
389 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
390 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
391 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
392 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700393 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
394 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
395 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700396 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000397
398 // T+500ms
399 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
400 // 2049 rto: 1000ms, txSeq: 6, started T+500ms, retx 2
401 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400402 advanceClocks(1_ms, 250);
Eric Newberry971d9622018-03-30 23:29:26 -0700403 reliability->onLpPacketLost(5);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000404
Eric Newberry00d39fd2017-12-10 14:26:45 -0700405 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000406 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700407 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 1);
408 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000409 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
410 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(6).pkt), 2049);
411 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
412 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
413 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
414 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(6).retxCount, 2);
415 BOOST_REQUIRE(reliability->m_unackedFrags.at(6).netPkt);
416 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
417 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
418 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(6).netPkt);
419 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
420 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
421 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
422 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
423 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
424 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
425 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
426 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700427 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
428 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
429 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700430 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000431
432 // T+750ms
433 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
434 // 2049 rto: 1000ms, txSeq: 7, started T+750ms, retx 3
435 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Davide Pesavento14e71f02019-03-28 17:35:25 -0400436 advanceClocks(1_ms, 250);
Eric Newberry971d9622018-03-30 23:29:26 -0700437 reliability->onLpPacketLost(6);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000438
439 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 1);
440 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700441 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(7), 1);
442 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000443 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
444 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(7).pkt), 2049);
445 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
446 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
447 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
448 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(7).retxCount, 3);
449 BOOST_REQUIRE(reliability->m_unackedFrags.at(7).netPkt);
450 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
451 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
452 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(7).netPkt);
453 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
454 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
455 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
456 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
457 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 7));
458 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
459 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
460 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700461 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
462 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
463 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700464 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000465
466 // T+850ms
467 // 2048 rto: expired, removed
468 // 2049 rto: expired, removed
469 // 2050 rto: expired, removed
Davide Pesavento14e71f02019-03-28 17:35:25 -0400470 advanceClocks(1_ms, 100);
Eric Newberry971d9622018-03-30 23:29:26 -0700471 reliability->onLpPacketLost(7);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000472
473 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
474 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700475 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
476 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
477 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 1);
Eric Newberry41aba102017-11-01 16:42:13 -0700478 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000479}
480
Eric Newberry00d39fd2017-12-10 14:26:45 -0700481BOOST_AUTO_TEST_CASE(AckUnknownTxSeq)
482{
483 linkService->sendLpPackets({makeFrag(1, 50)});
484
485 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
486 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
487 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
488 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
489 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
490 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
491 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
492 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
493 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
494
495 lp::Packet ackPkt;
496 ackPkt.add<lp::AckField>(10101010);
497 reliability->processIncomingPacket(ackPkt);
498
499 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
500 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
501 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
502 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
503 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
504 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
505 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
506 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
507 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
508}
509
Eric Newberry971d9622018-03-30 23:29:26 -0700510BOOST_AUTO_TEST_CASE(LossByGreaterAcks)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000511{
Eric Newberry971d9622018-03-30 23:29:26 -0700512 // Detect loss by 3x greater Acks, also tests wraparound
513
Eric Newberry7b0071e2017-07-03 17:33:31 +0000514 reliability->m_lastTxSeqNo = 0xFFFFFFFFFFFFFFFE;
515
Eric Newberry971d9622018-03-30 23:29:26 -0700516 // Passed to sendLpPackets individually since they are
517 // from separate, non-fragmented network packets
Eric Newberry7b0071e2017-07-03 17:33:31 +0000518 linkService->sendLpPackets({makeFrag(1, 50)});
519 linkService->sendLpPackets({makeFrag(2, 50)});
520 linkService->sendLpPackets({makeFrag(3, 50)});
521 linkService->sendLpPackets({makeFrag(4, 50)});
522 linkService->sendLpPackets({makeFrag(5, 50)});
Eric Newberry185ab292017-03-28 06:45:39 +0000523
524 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000525 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
526 BOOST_CHECK(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).netPkt);
527 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 1); // pkt2
528 BOOST_CHECK(reliability->m_unackedFrags.at(0).netPkt);
529 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
530 BOOST_CHECK(reliability->m_unackedFrags.at(1).netPkt);
531 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
532 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
533 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
534 BOOST_CHECK(reliability->m_unackedFrags.at(3).netPkt);
Eric Newberry185ab292017-03-28 06:45:39 +0000535 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700536 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
537 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
538 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700539 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000540
541 lp::Packet ackPkt1;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000542 ackPkt1.add<lp::AckField>(0);
Eric Newberry185ab292017-03-28 06:45:39 +0000543
544 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
545
546 reliability->processIncomingPacket(ackPkt1);
547
548 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700549 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000550 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
551 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000552 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700553 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000554 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
555 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700556 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
Eric Newberry7b0071e2017-07-03 17:33:31 +0000557 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
558 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700559 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000560 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
561 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000562 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000563 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700564 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
565 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
566 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700567 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000568
569 lp::Packet ackPkt2;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000570 ackPkt2.add<lp::AckField>(2);
571 ackPkt1.add<lp::AckField>(101010); // Unknown TxSequence number - ignored
Eric Newberry185ab292017-03-28 06:45:39 +0000572
573 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
574
575 reliability->processIncomingPacket(ackPkt2);
576
577 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000578 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000579 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
580 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000581 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700582 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000583 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
584 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700585 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
586 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000587 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
588 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
589 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(101010), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000590 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000591 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700592 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 2);
593 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
594 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700595 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000596
597 lp::Packet ackPkt3;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000598 ackPkt3.add<lp::AckField>(1);
Eric Newberry185ab292017-03-28 06:45:39 +0000599
600 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
601
602 reliability->processIncomingPacket(ackPkt3);
603
604 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000605 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
606 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
607 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
608 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700609 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000610 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
611 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700612 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1); // pkt1 new TxSeq
Eric Newberry7b0071e2017-07-03 17:33:31 +0000613 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 1);
614 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).nGreaterSeqAcks, 0);
615 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000616 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry185ab292017-03-28 06:45:39 +0000617 lp::Packet sentRetxPkt(transport->sentPackets.back().packet);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000618 BOOST_REQUIRE(sentRetxPkt.has<lp::TxSequenceField>());
619 BOOST_CHECK_EQUAL(sentRetxPkt.get<lp::TxSequenceField>(), 4);
620 BOOST_REQUIRE(sentRetxPkt.has<lp::FragmentField>());
621 BOOST_CHECK_EQUAL(getPktNo(sentRetxPkt), 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700622 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
623 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
624 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700625 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000626
627 lp::Packet ackPkt4;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000628 ackPkt4.add<lp::AckField>(4);
Eric Newberry185ab292017-03-28 06:45:39 +0000629
630 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
631
632 reliability->processIncomingPacket(ackPkt4);
633
634 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000635 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
636 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
637 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
638 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700639 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000640 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
641 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 1);
642 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 0); // pkt1 new TxSeq
643 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000644 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700645 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
646 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 1);
647 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
648 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
649}
650
Eric Newberry971d9622018-03-30 23:29:26 -0700651BOOST_AUTO_TEST_CASE(SkipFragmentsRemovedInRtt)
652{
653 auto opts = linkService->getOptions();
654 opts.reliabilityOptions.maxRetx = 0; // just to make the test case shorter
655 opts.reliabilityOptions.seqNumLossThreshold = 3;
656 linkService->setOptions(opts);
657
658 lp::Packet frag1 = makeFrag(5001);
659 lp::Packet frag2 = makeFrag(5002);
660 linkService->sendLpPackets({frag1, frag2}); // First packet has 2 fragments
661 linkService->sendLpPackets({makeFrag(5003)});
662 linkService->sendLpPackets({makeFrag(5004)});
663 linkService->sendLpPackets({makeFrag(5005)});
664
665 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
666 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
667
668 lp::Sequence firstTxSeq = reliability->m_firstUnackedFrag->first;
669
670 // Ack the last 2 packets
671 lp::Packet ackPkt1;
672 ackPkt1.add<lp::AckField>(firstTxSeq + 4);
673 ackPkt1.add<lp::AckField>(firstTxSeq + 3);
674 reliability->processIncomingPacket(ackPkt1);
675
676 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
677 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).nGreaterSeqAcks, 2);
678 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).nGreaterSeqAcks, 2);
679
680 // Ack the third packet (5003)
681 // This triggers a "loss by greater Acks" for packets 5001 and 5002
682 lp::Packet ackPkt2;
683 ackPkt2.add<lp::AckField>(firstTxSeq + 2);
684 reliability->processIncomingPacket(ackPkt2); // tests crash/assert reported in bug #4479
685
686 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
687}
688
Eric Newberry00d39fd2017-12-10 14:26:45 -0700689BOOST_AUTO_TEST_CASE(CancelLossNotificationOnAck)
690{
691 reliability->onDroppedInterest.connect([] (const Interest&) {
692 BOOST_FAIL("Packet loss timeout should be cancelled when packet acknowledged");
693 });
694
695 reliability->m_lastTxSeqNo = 0;
696
697 linkService->sendLpPackets({makeFrag(1, 50)});
698
Davide Pesavento14e71f02019-03-28 17:35:25 -0400699 advanceClocks(1_ms, 500);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700700
701 lp::Packet ackPkt;
702 ackPkt.add<lp::AckField>(1);
703 reliability->processIncomingPacket(ackPkt);
704
Davide Pesavento14e71f02019-03-28 17:35:25 -0400705 advanceClocks(1_ms, 1000);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700706
707 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
708 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
709 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700710 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000711}
712
Eric Newberry7b0071e2017-07-03 17:33:31 +0000713BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
714{
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400715 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000716 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
717
718 lp::Packet pkt1 = makeFrag(100, 40);
719 pkt1.add<lp::TxSequenceField>(765432);
720
721 reliability->processIncomingPacket(pkt1);
722
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400723 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000724 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
725 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
726
727 lp::Packet pkt2 = makeFrag(276, 40);
728 pkt2.add<lp::TxSequenceField>(234567);
729
730 reliability->processIncomingPacket(pkt2);
731
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400732 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000733 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
734 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
735 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 234567);
736
737 // T+5ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400738 advanceClocks(1_ms, 5);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400739 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000740}
741
742BOOST_AUTO_TEST_CASE(PiggybackAcks)
743{
744 reliability->m_ackQueue.push(256);
745 reliability->m_ackQueue.push(257);
746 reliability->m_ackQueue.push(10);
747
748 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000749 linkService->sendLpPackets({pkt});
750
751 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
752 lp::Packet sentPkt(transport->sentPackets.front().packet);
753
754 BOOST_REQUIRE_EQUAL(sentPkt.count<lp::AckField>(), 3);
755 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(0), 256);
756 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(1), 257);
757 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(2), 10);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000758 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Eric Newberry185ab292017-03-28 06:45:39 +0000759
760 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
761}
762
763BOOST_AUTO_TEST_CASE(PiggybackAcksMtu)
764{
Junxiao Shi21e01932018-04-21 10:39:05 +0000765 // MTU is 1500, payload has 60 octets plus 6 octets for LpPacket and Fragment TL and 10 octets for
766 // TxSequence, leaving 1426 octets for piggybacking. Each Ack header is 12 octets, so each
767 // LpPacket can carry 118 Acks, and it takes 9 LpPackets for 1000 Acks.
Eric Newberry185ab292017-03-28 06:45:39 +0000768
Eric Newberry7b0071e2017-07-03 17:33:31 +0000769 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000770
Junxiao Shi21e01932018-04-21 10:39:05 +0000771 std::unordered_set<lp::Sequence> expectedAcks;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000772 for (lp::Sequence i = 1000; i < 2000; i++) {
773 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000774 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000775 }
Eric Newberry185ab292017-03-28 06:45:39 +0000776
Junxiao Shi21e01932018-04-21 10:39:05 +0000777 for (uint32_t i = 1; i <= 9; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000778 lp::Packet pkt = makeFrag(i, 60);
779 linkService->sendLpPackets({pkt});
Eric Newberry185ab292017-03-28 06:45:39 +0000780
Junxiao Shi21e01932018-04-21 10:39:05 +0000781 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000782 lp::Packet sentPkt(transport->sentPackets.back().packet);
783 BOOST_CHECK_EQUAL(getPktNo(sentPkt), i);
784 BOOST_CHECK(sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000785
786 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
787 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
788 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000789 }
Eric Newberry185ab292017-03-28 06:45:39 +0000790
Eric Newberry7b0071e2017-07-03 17:33:31 +0000791 BOOST_CHECK(reliability->m_ackQueue.empty());
Junxiao Shi21e01932018-04-21 10:39:05 +0000792 BOOST_CHECK(expectedAcks.empty());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000793}
Eric Newberry185ab292017-03-28 06:45:39 +0000794
Eric Newberry7b0071e2017-07-03 17:33:31 +0000795BOOST_AUTO_TEST_CASE(PiggybackAcksMtuNoSpace)
796{
Eric Newberry812d6152018-06-06 15:06:01 -0700797 // MTU is 64, payload has 44 octets plus 4 octets for LpPacket and Fragment TL and 10 octets for
Junxiao Shi21e01932018-04-21 10:39:05 +0000798 // TxSequence, leaving 6 octets for piggybacking. Each Ack header is 12 octets, so there's no room
799 // to piggyback any Ack in LpPacket.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000800
Eric Newberry812d6152018-06-06 15:06:01 -0700801 transport->setMtu(Transport::MIN_MTU);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000802
803 for (lp::Sequence i = 1000; i < 1100; i++) {
804 reliability->m_ackQueue.push(i);
805 }
806
Eric Newberry812d6152018-06-06 15:06:01 -0700807 lp::Packet pkt = makeFrag(1, 44);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000808 linkService->sendLpPackets({pkt});
809
Eric Newberry185ab292017-03-28 06:45:39 +0000810 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000811 lp::Packet sentPkt(transport->sentPackets.back().packet);
812 BOOST_CHECK_EQUAL(getPktNo(sentPkt), 1);
813 BOOST_CHECK(!sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000814
815 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 100);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000816}
Eric Newberry185ab292017-03-28 06:45:39 +0000817
Eric Newberry7b0071e2017-07-03 17:33:31 +0000818BOOST_AUTO_TEST_CASE(StartIdleAckTimer)
819{
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400820 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000821
Eric Newberry7b0071e2017-07-03 17:33:31 +0000822 lp::Packet pkt1 = makeFrag(1, 100);
823 pkt1.add<lp::TxSequenceField>(12);
824 reliability->processIncomingPacket({pkt1});
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 // T+1ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400828 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400829 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000830
Eric Newberry7b0071e2017-07-03 17:33:31 +0000831 lp::Packet pkt2 = makeFrag(2, 100);
832 pkt2.add<lp::TxSequenceField>(13);
833 reliability->processIncomingPacket({pkt2});
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400834 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000835
Eric Newberry7b0071e2017-07-03 17:33:31 +0000836 // T+5ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400837 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400838 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000839
Eric Newberry7b0071e2017-07-03 17:33:31 +0000840 lp::Packet pkt3 = makeFrag(3, 100);
841 pkt3.add<lp::TxSequenceField>(15);
842 reliability->processIncomingPacket({pkt3});
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400843 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000844
Eric Newberry7b0071e2017-07-03 17:33:31 +0000845 // T+9ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400846 advanceClocks(1_ms, 4);
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+10ms
Davide Pesavento14e71f02019-03-28 17:35:25 -0400850 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400851 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000852}
853
854BOOST_AUTO_TEST_CASE(IdleAckTimer)
855{
Junxiao Shi21e01932018-04-21 10:39:05 +0000856 // T+0ms: populate ack queue and start idle ack timer
857 std::unordered_set<lp::Sequence> expectedAcks;
858 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000859 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000860 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000861 }
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400862 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000863 reliability->startIdleAckTimer();
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400864 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000865
Junxiao Shi21e01932018-04-21 10:39:05 +0000866 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400867 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400868 BOOST_CHECK(reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000869 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000870 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
Junxiao Shi21e01932018-04-21 10:39:05 +0000871 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000872 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
873
Junxiao Shi21e01932018-04-21 10:39:05 +0000874 // T+5ms: idle ack timer expires, IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400875 advanceClocks(1_ms, 1);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400876 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000877 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000878 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry185ab292017-03-28 06:45:39 +0000879
Junxiao Shi21e01932018-04-21 10:39:05 +0000880 lp::Packet sentPkt(transport->sentPackets.back().packet);
881 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
882 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
883 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000884 }
Junxiao Shi21e01932018-04-21 10:39:05 +0000885 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000886}
887
888BOOST_AUTO_TEST_CASE(IdleAckTimerMtu)
889{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000890 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000891
Junxiao Shi21e01932018-04-21 10:39:05 +0000892 // T+0ms: populate ack queue and start idle ack timer
893 std::unordered_set<lp::Sequence> expectedAcks;
894 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000895 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000896 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000897 }
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400898 BOOST_CHECK(!reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000899 reliability->startIdleAckTimer();
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400900 BOOST_CHECK(reliability->m_idleAckTimer);
Eric Newberry185ab292017-03-28 06:45:39 +0000901
Junxiao Shi21e01932018-04-21 10:39:05 +0000902 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400903 advanceClocks(1_ms, 4);
Davide Pesaventof190cfa2019-07-17 20:14:11 -0400904 BOOST_CHECK(reliability->m_idleAckTimer);
Junxiao Shi21e01932018-04-21 10:39:05 +0000905 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
906 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
907 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000908 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
909
Junxiao Shi21e01932018-04-21 10:39:05 +0000910 // T+5ms: idle ack timer expires, IDLE packets generated
Davide Pesavento14e71f02019-03-28 17:35:25 -0400911 advanceClocks(1_ms, 1);
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(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000914
Junxiao Shi21e01932018-04-21 10:39:05 +0000915 // MTU is 1500. LpPacket TL occupies 4 octets. Each Ack header is 12 octets. There are room for
916 // 124 Acks per LpPacket, and it takes 5 LpPackets to carry 500 Acks.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000917 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Junxiao Shi21e01932018-04-21 10:39:05 +0000918 for (size_t i = 0; i < 5; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000919 lp::Packet sentPkt(transport->sentPackets[i].packet);
920 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000921 BOOST_CHECK_EQUAL(sentPkt.count<lp::AckField>(), i == 4 ? 4 : 124);
922 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
923 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
924 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000925 }
926
Junxiao Shi21e01932018-04-21 10:39:05 +0000927 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000928}
929
Eric Newberry7b0071e2017-07-03 17:33:31 +0000930BOOST_AUTO_TEST_SUITE_END() // TestLpReliability
Eric Newberry185ab292017-03-28 06:45:39 +0000931BOOST_AUTO_TEST_SUITE_END() // Face
932
933} // namespace tests
934} // namespace face
935} // namespace nfd