blob: d2b9f2222c0d2e60ef1c4f20e9668f50662b5dfc [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 Newberry971d9622018-03-30 23:29:26 -07003 * Copyright (c) 2014-2018, 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"
31#include "dummy-face.hpp"
32#include "dummy-transport.hpp"
33
Eric Newberry7b0071e2017-07-03 17:33:31 +000034#include <cstring>
35
Eric Newberry185ab292017-03-28 06:45:39 +000036namespace nfd {
37namespace face {
38namespace tests {
39
40using namespace nfd::tests;
41
42BOOST_AUTO_TEST_SUITE(Face)
43
44class DummyLpReliabilityLinkService : public GenericLinkService
45{
46public:
47 LpReliability*
48 getLpReliability()
49 {
50 return &m_reliability;
51 }
52
53 void
54 sendLpPackets(std::vector<lp::Packet> frags)
55 {
56 if (frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -070057 Interest interest("/test/prefix");
58 lp::Packet pkt;
59 pkt.add<lp::FragmentField>(make_pair(interest.wireEncode().begin(), interest.wireEncode().end()));
60 m_reliability.handleOutgoing(frags, std::move(pkt), true);
Eric Newberry185ab292017-03-28 06:45:39 +000061 }
62
Eric Newberry7b0071e2017-07-03 17:33:31 +000063 for (lp::Packet frag : frags) {
Eric Newberry185ab292017-03-28 06:45:39 +000064 this->sendLpPacket(std::move(frag));
65 }
66 }
67
68private:
69 void
Eric Newberry971d9622018-03-30 23:29:26 -070070 doSendInterest(const Interest&) final
Eric Newberry185ab292017-03-28 06:45:39 +000071 {
72 BOOST_ASSERT(false);
73 }
74
75 void
Eric Newberry971d9622018-03-30 23:29:26 -070076 doSendData(const Data&) final
Eric Newberry185ab292017-03-28 06:45:39 +000077 {
78 BOOST_ASSERT(false);
79 }
80
81 void
Eric Newberry971d9622018-03-30 23:29:26 -070082 doSendNack(const lp::Nack&) final
Eric Newberry185ab292017-03-28 06:45:39 +000083 {
84 BOOST_ASSERT(false);
85 }
86
87 void
Eric Newberry971d9622018-03-30 23:29:26 -070088 doReceivePacket(Transport::Packet&&) final
Eric Newberry185ab292017-03-28 06:45:39 +000089 {
90 BOOST_ASSERT(false);
91 }
92};
93
94class LpReliabilityFixture : public UnitTestTimeFixture
95{
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(),
117 [txSeq] (const LpReliability::UnackedFrags::iterator& frag) {
118 return frag->first == txSeq;
119 });
120 }
121
Eric Newberry7b0071e2017-07-03 17:33:31 +0000122 /** \brief make an LpPacket with fragment of specified size
123 * \param pktNo packet identifier, which can be extracted with \p getPktNo
124 * \param payloadSize total payload size; if this is less than 4, 4 will be used
125 */
126 static lp::Packet
127 makeFrag(uint32_t pktNo, size_t payloadSize = 4)
128 {
129 payloadSize = std::max(payloadSize, static_cast<size_t>(4));
130 BOOST_ASSERT(payloadSize <= 255);
131
132 lp::Packet pkt;
133 ndn::Buffer buf(payloadSize);
Davide Pesavento6d1c1c32017-10-08 21:44:05 -0400134 std::memcpy(buf.data(), &pktNo, sizeof(pktNo));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000135 pkt.set<lp::FragmentField>(make_pair(buf.cbegin(), buf.cend()));
136 return pkt;
137 }
138
139 /** \brief extract packet identifier from LpPacket made with \p makeFrag
140 * \retval 0 packet identifier cannot be extracted
141 */
142 static uint32_t
143 getPktNo(const lp::Packet& pkt)
144 {
145 BOOST_ASSERT(pkt.has<lp::FragmentField>());
146
147 ndn::Buffer::const_iterator begin, end;
148 std::tie(begin, end) = pkt.get<lp::FragmentField>();
149 if (std::distance(begin, end) < 4) {
150 return 0;
151 }
152
153 uint32_t value = 0;
154 std::memcpy(&value, &*begin, sizeof(value));
155 return value;
Eric Newberry185ab292017-03-28 06:45:39 +0000156 }
157
Eric Newberry971d9622018-03-30 23:29:26 -0700158protected:
Eric Newberry185ab292017-03-28 06:45:39 +0000159 unique_ptr<DummyLpReliabilityLinkService> linkService;
160 unique_ptr<DummyTransport> transport;
161 unique_ptr<DummyFace> face;
162 LpReliability* reliability;
163};
164
165BOOST_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 Newberry7b0071e2017-07-03 17:33:31 +0000189 BOOST_CHECK(!cached1.has<lp::SequenceField>());
190 lp::Sequence firstTxSeq = cached1.get<lp::TxSequenceField>();
Eric Newberry971d9622018-03-30 23:29:26 -0700191 BOOST_CHECK_EQUAL(firstTxSeq, 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000192 BOOST_CHECK_EQUAL(getPktNo(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
Eric Newberry185ab292017-03-28 06:45:39 +0000200 advanceClocks(time::milliseconds(1), 500);
201 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
Eric Newberry185ab292017-03-28 06:45:39 +0000223 advanceClocks(time::milliseconds(1), 750);
224
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
Eric Newberry185ab292017-03-28 06:45:39 +0000241 advanceClocks(time::milliseconds(1), 1000);
242
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
Eric Newberry185ab292017-03-28 06:45:39 +0000260 advanceClocks(time::milliseconds(1), 1000);
261
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
Eric Newberry185ab292017-03-28 06:45:39 +0000279 advanceClocks(time::milliseconds(1), 1000);
280
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
Eric Newberry185ab292017-03-28 06:45:39 +0000297 advanceClocks(time::milliseconds(1), 1000);
298
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);
320 BOOST_CHECK_EQUAL(getPktNo(cached1), 2048);
321 lp::Packet cached2(transport->sentPackets.at(1).packet);
322 BOOST_REQUIRE(cached2.has<lp::TxSequenceField>());
323 BOOST_CHECK_EQUAL(cached2.get<lp::TxSequenceField>(), 3);
324 BOOST_CHECK_EQUAL(getPktNo(cached2), 2049);
325 lp::Packet cached3(transport->sentPackets.at(2).packet);
326 BOOST_REQUIRE(cached3.has<lp::TxSequenceField>());
327 BOOST_CHECK_EQUAL(cached3.get<lp::TxSequenceField>(), 4);
328 BOOST_CHECK_EQUAL(getPktNo(cached3), 2050);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700329 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
330 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
331 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700332 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000333
Eric Newberry7b0071e2017-07-03 17:33:31 +0000334 // T+0ms
335 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
336 // 2049 rto: 1000ms, txSeq: 3, started T+0ms, retx 0
337 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Eric Newberry185ab292017-03-28 06:45:39 +0000338
Eric Newberry00d39fd2017-12-10 14:26:45 -0700339 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
340 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1);
341 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000342 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
343 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(3).pkt), 2049);
344 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
345 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
346 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
347 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
348 BOOST_REQUIRE(reliability->m_unackedFrags.at(3).netPkt);
349 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
350 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
351 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(3).netPkt);
352 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
353 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
354 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
355 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
356 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
357 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
358 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
359 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700360 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
361 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
362 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700363 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000364
Eric Newberry7b0071e2017-07-03 17:33:31 +0000365 // T+250ms
366 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
367 // 2049 rto: 1000ms, txSeq: 5, started T+250ms, retx 1
368 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
369 advanceClocks(time::milliseconds(1), 250);
Eric Newberry971d9622018-03-30 23:29:26 -0700370 reliability->onLpPacketLost(3);
Eric Newberry185ab292017-03-28 06:45:39 +0000371
Eric Newberry00d39fd2017-12-10 14:26:45 -0700372 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000373 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700374 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 1);
375 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000376 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
377 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(5).pkt), 2049);
378 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
379 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
380 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
381 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(5).retxCount, 1);
382 BOOST_REQUIRE(reliability->m_unackedFrags.at(5).netPkt);
383 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
384 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
385 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(5).netPkt);
386 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
387 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
388 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
389 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
390 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
391 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
392 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
393 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700394 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
395 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
396 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700397 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000398
399 // T+500ms
400 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
401 // 2049 rto: 1000ms, txSeq: 6, started T+500ms, retx 2
402 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
403 advanceClocks(time::milliseconds(1), 250);
Eric Newberry971d9622018-03-30 23:29:26 -0700404 reliability->onLpPacketLost(5);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000405
Eric Newberry00d39fd2017-12-10 14:26:45 -0700406 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000407 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700408 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 1);
409 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000410 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
411 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(6).pkt), 2049);
412 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
413 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
414 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
415 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(6).retxCount, 2);
416 BOOST_REQUIRE(reliability->m_unackedFrags.at(6).netPkt);
417 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
418 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
419 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(6).netPkt);
420 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
421 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
422 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
423 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
424 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
425 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
426 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
427 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700428 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
429 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
430 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700431 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000432
433 // T+750ms
434 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
435 // 2049 rto: 1000ms, txSeq: 7, started T+750ms, retx 3
436 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
437 advanceClocks(time::milliseconds(1), 250);
Eric Newberry971d9622018-03-30 23:29:26 -0700438 reliability->onLpPacketLost(6);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000439
440 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 1);
441 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700442 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(7), 1);
443 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000444 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
445 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(7).pkt), 2049);
446 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
447 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
448 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
449 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(7).retxCount, 3);
450 BOOST_REQUIRE(reliability->m_unackedFrags.at(7).netPkt);
451 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
452 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
453 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(7).netPkt);
454 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
455 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
456 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
457 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
458 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 7));
459 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
460 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
461 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700462 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
463 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
464 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700465 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000466
467 // T+850ms
468 // 2048 rto: expired, removed
469 // 2049 rto: expired, removed
470 // 2050 rto: expired, removed
471 advanceClocks(time::milliseconds(1), 100);
Eric Newberry971d9622018-03-30 23:29:26 -0700472 reliability->onLpPacketLost(7);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000473
474 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
475 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700476 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
477 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
478 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 1);
Eric Newberry41aba102017-11-01 16:42:13 -0700479 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000480}
481
Eric Newberry00d39fd2017-12-10 14:26:45 -0700482BOOST_AUTO_TEST_CASE(AckUnknownTxSeq)
483{
484 linkService->sendLpPackets({makeFrag(1, 50)});
485
486 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
487 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
488 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
489 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
490 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
491 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
492 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
493 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
494 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
495
496 lp::Packet ackPkt;
497 ackPkt.add<lp::AckField>(10101010);
498 reliability->processIncomingPacket(ackPkt);
499
500 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
501 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1);
502 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
503 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
504 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
505 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
506 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
507 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
508 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
509}
510
Eric Newberry971d9622018-03-30 23:29:26 -0700511BOOST_AUTO_TEST_CASE(LossByGreaterAcks)
Eric Newberry7b0071e2017-07-03 17:33:31 +0000512{
Eric Newberry971d9622018-03-30 23:29:26 -0700513 // Detect loss by 3x greater Acks, also tests wraparound
514
Eric Newberry7b0071e2017-07-03 17:33:31 +0000515 reliability->m_lastTxSeqNo = 0xFFFFFFFFFFFFFFFE;
516
Eric Newberry971d9622018-03-30 23:29:26 -0700517 // Passed to sendLpPackets individually since they are
518 // from separate, non-fragmented network packets
Eric Newberry7b0071e2017-07-03 17:33:31 +0000519 linkService->sendLpPackets({makeFrag(1, 50)});
520 linkService->sendLpPackets({makeFrag(2, 50)});
521 linkService->sendLpPackets({makeFrag(3, 50)});
522 linkService->sendLpPackets({makeFrag(4, 50)});
523 linkService->sendLpPackets({makeFrag(5, 50)});
Eric Newberry185ab292017-03-28 06:45:39 +0000524
525 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000526 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
527 BOOST_CHECK(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).netPkt);
528 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 1); // pkt2
529 BOOST_CHECK(reliability->m_unackedFrags.at(0).netPkt);
530 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
531 BOOST_CHECK(reliability->m_unackedFrags.at(1).netPkt);
532 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
533 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
534 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
535 BOOST_CHECK(reliability->m_unackedFrags.at(3).netPkt);
Eric Newberry185ab292017-03-28 06:45:39 +0000536 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700537 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 0);
538 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
539 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700540 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000541
542 lp::Packet ackPkt1;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000543 ackPkt1.add<lp::AckField>(0);
Eric Newberry185ab292017-03-28 06:45:39 +0000544
545 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
546
547 reliability->processIncomingPacket(ackPkt1);
548
549 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 4);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700550 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000551 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
552 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000553 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700554 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000555 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
556 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700557 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
Eric Newberry7b0071e2017-07-03 17:33:31 +0000558 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
559 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700560 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000561 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
562 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000563 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000564 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700565 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
566 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
567 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700568 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000569
570 lp::Packet ackPkt2;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000571 ackPkt2.add<lp::AckField>(2);
572 ackPkt1.add<lp::AckField>(101010); // Unknown TxSequence number - ignored
Eric Newberry185ab292017-03-28 06:45:39 +0000573
574 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
575
576 reliability->processIncomingPacket(ackPkt2);
577
578 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000579 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000580 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
581 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000582 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
Eric Newberry00d39fd2017-12-10 14:26:45 -0700583 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
Eric Newberry7b0071e2017-07-03 17:33:31 +0000584 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
585 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700586 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
587 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000588 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
589 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
590 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(101010), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000591 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000592 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700593 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 2);
594 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
595 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700596 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000597
598 lp::Packet ackPkt3;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000599 ackPkt3.add<lp::AckField>(1);
Eric Newberry185ab292017-03-28 06:45:39 +0000600
601 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
602
603 reliability->processIncomingPacket(ackPkt3);
604
605 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000606 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
607 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
608 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
609 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700610 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000611 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
612 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700613 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1); // pkt1 new TxSeq
Eric Newberry7b0071e2017-07-03 17:33:31 +0000614 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 1);
615 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).nGreaterSeqAcks, 0);
616 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000617 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry185ab292017-03-28 06:45:39 +0000618 lp::Packet sentRetxPkt(transport->sentPackets.back().packet);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000619 BOOST_REQUIRE(sentRetxPkt.has<lp::TxSequenceField>());
620 BOOST_CHECK_EQUAL(sentRetxPkt.get<lp::TxSequenceField>(), 4);
621 BOOST_REQUIRE(sentRetxPkt.has<lp::FragmentField>());
622 BOOST_CHECK_EQUAL(getPktNo(sentRetxPkt), 1);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700623 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
624 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
625 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700626 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000627
628 lp::Packet ackPkt4;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000629 ackPkt4.add<lp::AckField>(4);
Eric Newberry185ab292017-03-28 06:45:39 +0000630
631 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
632
633 reliability->processIncomingPacket(ackPkt4);
634
635 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000636 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
637 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
638 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
639 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
Eric Newberry00d39fd2017-12-10 14:26:45 -0700640 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
Eric Newberry7b0071e2017-07-03 17:33:31 +0000641 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
642 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 1);
643 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 0); // pkt1 new TxSeq
644 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000645 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry00d39fd2017-12-10 14:26:45 -0700646 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 3);
647 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 1);
648 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
649 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
650}
651
Eric Newberry971d9622018-03-30 23:29:26 -0700652BOOST_AUTO_TEST_CASE(SkipFragmentsRemovedInRtt)
653{
654 auto opts = linkService->getOptions();
655 opts.reliabilityOptions.maxRetx = 0; // just to make the test case shorter
656 opts.reliabilityOptions.seqNumLossThreshold = 3;
657 linkService->setOptions(opts);
658
659 lp::Packet frag1 = makeFrag(5001);
660 lp::Packet frag2 = makeFrag(5002);
661 linkService->sendLpPackets({frag1, frag2}); // First packet has 2 fragments
662 linkService->sendLpPackets({makeFrag(5003)});
663 linkService->sendLpPackets({makeFrag(5004)});
664 linkService->sendLpPackets({makeFrag(5005)});
665
666 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
667 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
668
669 lp::Sequence firstTxSeq = reliability->m_firstUnackedFrag->first;
670
671 // Ack the last 2 packets
672 lp::Packet ackPkt1;
673 ackPkt1.add<lp::AckField>(firstTxSeq + 4);
674 ackPkt1.add<lp::AckField>(firstTxSeq + 3);
675 reliability->processIncomingPacket(ackPkt1);
676
677 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
678 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).nGreaterSeqAcks, 2);
679 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).nGreaterSeqAcks, 2);
680
681 // Ack the third packet (5003)
682 // This triggers a "loss by greater Acks" for packets 5001 and 5002
683 lp::Packet ackPkt2;
684 ackPkt2.add<lp::AckField>(firstTxSeq + 2);
685 reliability->processIncomingPacket(ackPkt2); // tests crash/assert reported in bug #4479
686
687 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
688}
689
Eric Newberry00d39fd2017-12-10 14:26:45 -0700690BOOST_AUTO_TEST_CASE(CancelLossNotificationOnAck)
691{
692 reliability->onDroppedInterest.connect([] (const Interest&) {
693 BOOST_FAIL("Packet loss timeout should be cancelled when packet acknowledged");
694 });
695
696 reliability->m_lastTxSeqNo = 0;
697
698 linkService->sendLpPackets({makeFrag(1, 50)});
699
700 advanceClocks(time::milliseconds(1), 500);
701
702 lp::Packet ackPkt;
703 ackPkt.add<lp::AckField>(1);
704 reliability->processIncomingPacket(ackPkt);
705
706 advanceClocks(time::milliseconds(1), 1000);
707
708 BOOST_CHECK_EQUAL(linkService->getCounters().nAcknowledged, 1);
709 BOOST_CHECK_EQUAL(linkService->getCounters().nRetransmitted, 0);
710 BOOST_CHECK_EQUAL(linkService->getCounters().nRetxExhausted, 0);
Eric Newberry41aba102017-11-01 16:42:13 -0700711 BOOST_CHECK_EQUAL(linkService->getCounters().nDroppedInterests, 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000712}
713
Eric Newberry7b0071e2017-07-03 17:33:31 +0000714BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
715{
716 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
717 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
718
719 lp::Packet pkt1 = makeFrag(100, 40);
720 pkt1.add<lp::TxSequenceField>(765432);
721
722 reliability->processIncomingPacket(pkt1);
723
724 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
725 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
726 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
727
728 lp::Packet pkt2 = makeFrag(276, 40);
729 pkt2.add<lp::TxSequenceField>(234567);
730
731 reliability->processIncomingPacket(pkt2);
732
733 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
734 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
735 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
736 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 234567);
737
738 // T+5ms
739 advanceClocks(time::milliseconds(1), 5);
740 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000741}
742
743BOOST_AUTO_TEST_CASE(PiggybackAcks)
744{
745 reliability->m_ackQueue.push(256);
746 reliability->m_ackQueue.push(257);
747 reliability->m_ackQueue.push(10);
748
749 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000750 linkService->sendLpPackets({pkt});
751
752 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
753 lp::Packet sentPkt(transport->sentPackets.front().packet);
754
755 BOOST_REQUIRE_EQUAL(sentPkt.count<lp::AckField>(), 3);
756 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(0), 256);
757 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(1), 257);
758 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(2), 10);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000759 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Eric Newberry185ab292017-03-28 06:45:39 +0000760
761 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
762}
763
764BOOST_AUTO_TEST_CASE(PiggybackAcksMtu)
765{
Junxiao Shi21e01932018-04-21 10:39:05 +0000766 // MTU is 1500, payload has 60 octets plus 6 octets for LpPacket and Fragment TL and 10 octets for
767 // TxSequence, leaving 1426 octets for piggybacking. Each Ack header is 12 octets, so each
768 // LpPacket can carry 118 Acks, and it takes 9 LpPackets for 1000 Acks.
Eric Newberry185ab292017-03-28 06:45:39 +0000769
Eric Newberry7b0071e2017-07-03 17:33:31 +0000770 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000771
Junxiao Shi21e01932018-04-21 10:39:05 +0000772 std::unordered_set<lp::Sequence> expectedAcks;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000773 for (lp::Sequence i = 1000; i < 2000; i++) {
774 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000775 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000776 }
Eric Newberry185ab292017-03-28 06:45:39 +0000777
Junxiao Shi21e01932018-04-21 10:39:05 +0000778 for (uint32_t i = 1; i <= 9; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000779 lp::Packet pkt = makeFrag(i, 60);
780 linkService->sendLpPackets({pkt});
Eric Newberry185ab292017-03-28 06:45:39 +0000781
Junxiao Shi21e01932018-04-21 10:39:05 +0000782 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000783 lp::Packet sentPkt(transport->sentPackets.back().packet);
784 BOOST_CHECK_EQUAL(getPktNo(sentPkt), i);
785 BOOST_CHECK(sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000786
787 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
788 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
789 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000790 }
Eric Newberry185ab292017-03-28 06:45:39 +0000791
Eric Newberry7b0071e2017-07-03 17:33:31 +0000792 BOOST_CHECK(reliability->m_ackQueue.empty());
Junxiao Shi21e01932018-04-21 10:39:05 +0000793 BOOST_CHECK(expectedAcks.empty());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000794}
Eric Newberry185ab292017-03-28 06:45:39 +0000795
Eric Newberry7b0071e2017-07-03 17:33:31 +0000796BOOST_AUTO_TEST_CASE(PiggybackAcksMtuNoSpace)
797{
Eric Newberry812d6152018-06-06 15:06:01 -0700798 // 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 +0000799 // TxSequence, leaving 6 octets for piggybacking. Each Ack header is 12 octets, so there's no room
800 // to piggyback any Ack in LpPacket.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000801
Eric Newberry812d6152018-06-06 15:06:01 -0700802 transport->setMtu(Transport::MIN_MTU);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000803
804 for (lp::Sequence i = 1000; i < 1100; i++) {
805 reliability->m_ackQueue.push(i);
806 }
807
Eric Newberry812d6152018-06-06 15:06:01 -0700808 lp::Packet pkt = makeFrag(1, 44);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000809 linkService->sendLpPackets({pkt});
810
Eric Newberry185ab292017-03-28 06:45:39 +0000811 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000812 lp::Packet sentPkt(transport->sentPackets.back().packet);
813 BOOST_CHECK_EQUAL(getPktNo(sentPkt), 1);
814 BOOST_CHECK(!sentPkt.has<lp::AckField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000815
816 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 100);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000817}
Eric Newberry185ab292017-03-28 06:45:39 +0000818
Eric Newberry7b0071e2017-07-03 17:33:31 +0000819BOOST_AUTO_TEST_CASE(StartIdleAckTimer)
820{
821 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000822
Eric Newberry7b0071e2017-07-03 17:33:31 +0000823 lp::Packet pkt1 = makeFrag(1, 100);
824 pkt1.add<lp::TxSequenceField>(12);
825 reliability->processIncomingPacket({pkt1});
826 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000827
Eric Newberry7b0071e2017-07-03 17:33:31 +0000828 // T+1ms
829 advanceClocks(time::milliseconds(1), 1);
830 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000831
Eric Newberry7b0071e2017-07-03 17:33:31 +0000832 lp::Packet pkt2 = makeFrag(2, 100);
833 pkt2.add<lp::TxSequenceField>(13);
834 reliability->processIncomingPacket({pkt2});
835 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000836
Eric Newberry7b0071e2017-07-03 17:33:31 +0000837 // T+5ms
838 advanceClocks(time::milliseconds(1), 4);
839 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000840
Eric Newberry7b0071e2017-07-03 17:33:31 +0000841 lp::Packet pkt3 = makeFrag(3, 100);
842 pkt3.add<lp::TxSequenceField>(15);
843 reliability->processIncomingPacket({pkt3});
844 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000845
Eric Newberry7b0071e2017-07-03 17:33:31 +0000846 // T+9ms
847 advanceClocks(time::milliseconds(1), 4);
848 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000849
Eric Newberry7b0071e2017-07-03 17:33:31 +0000850 // T+10ms
851 advanceClocks(time::milliseconds(1), 1);
852 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000853}
854
855BOOST_AUTO_TEST_CASE(IdleAckTimer)
856{
Junxiao Shi21e01932018-04-21 10:39:05 +0000857 // T+0ms: populate ack queue and start idle ack timer
858 std::unordered_set<lp::Sequence> expectedAcks;
859 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000860 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000861 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000862 }
Eric Newberry185ab292017-03-28 06:45:39 +0000863 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
864 reliability->startIdleAckTimer();
865 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
866
Junxiao Shi21e01932018-04-21 10:39:05 +0000867 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Eric Newberry185ab292017-03-28 06:45:39 +0000868 advanceClocks(time::milliseconds(1), 4);
869 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Junxiao Shi21e01932018-04-21 10:39:05 +0000870 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000871 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
Junxiao Shi21e01932018-04-21 10:39:05 +0000872 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000873 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
874
Junxiao Shi21e01932018-04-21 10:39:05 +0000875 // T+5ms: idle ack timer expires, IDLE packet generated
Eric Newberry185ab292017-03-28 06:45:39 +0000876 advanceClocks(time::milliseconds(1), 1);
Eric Newberry185ab292017-03-28 06:45:39 +0000877 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000878 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000879 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry185ab292017-03-28 06:45:39 +0000880
Junxiao Shi21e01932018-04-21 10:39:05 +0000881 lp::Packet sentPkt(transport->sentPackets.back().packet);
882 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
883 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
884 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000885 }
Junxiao Shi21e01932018-04-21 10:39:05 +0000886 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000887}
888
889BOOST_AUTO_TEST_CASE(IdleAckTimerMtu)
890{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000891 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000892
Junxiao Shi21e01932018-04-21 10:39:05 +0000893 // T+0ms: populate ack queue and start idle ack timer
894 std::unordered_set<lp::Sequence> expectedAcks;
895 for (lp::Sequence i = 1000; i < 1500; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000896 reliability->m_ackQueue.push(i);
Junxiao Shi21e01932018-04-21 10:39:05 +0000897 expectedAcks.insert(i);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000898 }
Eric Newberry185ab292017-03-28 06:45:39 +0000899 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
900 reliability->startIdleAckTimer();
901 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
902
Junxiao Shi21e01932018-04-21 10:39:05 +0000903 // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
Eric Newberry185ab292017-03-28 06:45:39 +0000904 advanceClocks(time::milliseconds(1), 4);
905 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Junxiao Shi21e01932018-04-21 10:39:05 +0000906 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
907 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
908 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
Eric Newberry185ab292017-03-28 06:45:39 +0000909 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
910
Junxiao Shi21e01932018-04-21 10:39:05 +0000911 // T+5ms: idle ack timer expires, IDLE packets generated
Eric Newberry185ab292017-03-28 06:45:39 +0000912 advanceClocks(time::milliseconds(1), 1);
Eric Newberry185ab292017-03-28 06:45:39 +0000913 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Junxiao Shi21e01932018-04-21 10:39:05 +0000914 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000915
Junxiao Shi21e01932018-04-21 10:39:05 +0000916 // MTU is 1500. LpPacket TL occupies 4 octets. Each Ack header is 12 octets. There are room for
917 // 124 Acks per LpPacket, and it takes 5 LpPackets to carry 500 Acks.
Eric Newberry7b0071e2017-07-03 17:33:31 +0000918 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Junxiao Shi21e01932018-04-21 10:39:05 +0000919 for (size_t i = 0; i < 5; i++) {
Eric Newberry7b0071e2017-07-03 17:33:31 +0000920 lp::Packet sentPkt(transport->sentPackets[i].packet);
921 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Junxiao Shi21e01932018-04-21 10:39:05 +0000922 BOOST_CHECK_EQUAL(sentPkt.count<lp::AckField>(), i == 4 ? 4 : 124);
923 for (lp::Sequence ack : sentPkt.list<lp::AckField>()) {
924 BOOST_CHECK_EQUAL(expectedAcks.erase(ack), 1);
925 }
Eric Newberry7b0071e2017-07-03 17:33:31 +0000926 }
927
Junxiao Shi21e01932018-04-21 10:39:05 +0000928 BOOST_CHECK(expectedAcks.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000929}
930
Eric Newberry7b0071e2017-07-03 17:33:31 +0000931BOOST_AUTO_TEST_SUITE_END() // TestLpReliability
Eric Newberry185ab292017-03-28 06:45:39 +0000932BOOST_AUTO_TEST_SUITE_END() // Face
933
934} // namespace tests
935} // namespace face
936} // namespace nfd