blob: 82e1f79f74f7df083767ae3eb2dd7ff7a57b7b89 [file] [log] [blame]
Eric Newberry185ab292017-03-28 06:45:39 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2017, Regents of the University of California,
4 * 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"
28#include "face/lp-fragmenter.hpp"
29#include "face/generic-link-service.hpp"
30
31#include "tests/test-common.hpp"
32#include "dummy-face.hpp"
33#include "dummy-transport.hpp"
34
35namespace nfd {
36namespace face {
37namespace tests {
38
39using namespace nfd::tests;
40
41BOOST_AUTO_TEST_SUITE(Face)
42
43class 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>()) {
56 m_reliability.observeOutgoing(frags);
57 }
58
59 for (lp::Packet& frag : frags) {
60 this->sendLpPacket(std::move(frag));
61 }
62 }
63
64private:
65 void
66 doSendInterest(const Interest& interest) override
67 {
68 BOOST_ASSERT(false);
69 }
70
71 void
72 doSendData(const Data& data) override
73 {
74 BOOST_ASSERT(false);
75 }
76
77 void
78 doSendNack(const lp::Nack& nack) override
79 {
80 BOOST_ASSERT(false);
81 }
82
83 void
84 doReceivePacket(Transport::Packet&& packet) override
85 {
86 BOOST_ASSERT(false);
87 }
88};
89
90class LpReliabilityFixture : public UnitTestTimeFixture
91{
92public:
93 LpReliabilityFixture()
94 : linkService(make_unique<DummyLpReliabilityLinkService>())
95 , transport(make_unique<DummyTransport>())
96 , face(make_unique<DummyFace>())
97 {
98 linkService->setFaceAndTransport(*face, *transport);
99 transport->setFaceAndLinkService(*face, *linkService);
100
101 GenericLinkService::Options options;
102 options.reliabilityOptions.isEnabled = true;
103 linkService->setOptions(options);
104
105 reliability = linkService->getLpReliability();
106 }
107
108public:
109 unique_ptr<DummyLpReliabilityLinkService> linkService;
110 unique_ptr<DummyTransport> transport;
111 unique_ptr<DummyFace> face;
112 LpReliability* reliability;
113};
114
115BOOST_FIXTURE_TEST_SUITE(TestLpReliability, LpReliabilityFixture)
116
117BOOST_AUTO_TEST_CASE(SendNoFragmentField)
118{
119 lp::Packet pkt;
120 pkt.add<lp::AckField>(0);
121
122 linkService->sendLpPackets({pkt});
123 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
124 BOOST_CHECK_EQUAL(reliability->m_netPkts.size(), 0);
125}
126
127BOOST_AUTO_TEST_CASE(SendNotFragmented)
128{
129 shared_ptr<Interest> interest = makeInterest("/abc/def");
130
131 lp::Packet pkt;
132 pkt.add<lp::SequenceField>(123);
133 pkt.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
134
135 linkService->sendLpPackets({pkt});
136
137 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.size(), 1);
138 lp::Packet cached;
139 BOOST_REQUIRE_NO_THROW(cached.wireDecode(transport->sentPackets.front().packet));
140 BOOST_REQUIRE(cached.has<lp::SequenceField>());
141 BOOST_CHECK_EQUAL(cached.get<lp::SequenceField>(), 123);
142 lp::Sequence seq = cached.get<lp::SequenceField>();
143 ndn::Buffer::const_iterator begin, end;
144 std::tie(begin, end) = cached.get<lp::FragmentField>();
145 Block block(&*begin, std::distance(begin, end));
146 Interest decodedInterest(block);
147 BOOST_CHECK_EQUAL(decodedInterest, *interest);
148
149 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(seq), 1);
150 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(seq).retxCount, 0);
151
152 BOOST_REQUIRE_EQUAL(reliability->m_netPkts.size(), 1);
153 BOOST_REQUIRE_EQUAL(reliability->m_netPkts.count(seq), 1);
154 BOOST_REQUIRE_EQUAL(reliability->m_netPkts.at(seq).unackedFrags.size(), 1);
155 BOOST_CHECK_EQUAL(reliability->m_netPkts.at(seq).unackedFrags.count(seq), 1);
156
157 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
158}
159
160BOOST_AUTO_TEST_CASE(SendFragmented)
161{
162 // Limit MTU
163 transport->setMtu(100);
164
165 Data data("/abc/def");
166
167 // Create a Data block containing 60 octets of content, which should fragment into 2 packets
168 uint8_t content[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
169 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
170 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
171 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
172 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
173 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
174
175 data.setContent(content, sizeof(content));
176 signData(data);
177
178 lp::Packet pkt;
179 pkt.add<lp::FragmentField>(make_pair(data.wireEncode().begin(), data.wireEncode().end()));
180
181 LpFragmenter fragmenter;
182 bool wasFragmentSuccessful;
183 std::vector<lp::Packet> frags;
184 std::tie(wasFragmentSuccessful, frags) = fragmenter.fragmentPacket(pkt, 100);
185 BOOST_REQUIRE(wasFragmentSuccessful);
186 BOOST_REQUIRE_EQUAL(frags.size(), 2);
187
188 frags.at(0).add<lp::SequenceField>(123);
189 frags.at(1).add<lp::SequenceField>(124);
190 linkService->sendLpPackets(std::move(frags));
191
192 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.size(), 2);
193 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(123), 1);
194 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(124), 1);
195 lp::Packet cached1;
196 BOOST_REQUIRE_NO_THROW(cached1.wireDecode(transport->sentPackets.front().packet));
197 BOOST_REQUIRE(cached1.has<lp::SequenceField>());
198 BOOST_CHECK_EQUAL(cached1.get<lp::SequenceField>(), 123);
199 lp::Packet cached2;
200 BOOST_REQUIRE_NO_THROW(cached2.wireDecode(transport->sentPackets.back().packet));
201 BOOST_REQUIRE(cached2.has<lp::SequenceField>());
202 BOOST_CHECK_EQUAL(cached2.get<lp::SequenceField>(), 124);
203 lp::Sequence firstSeq = cached1.get<lp::SequenceField>();
204
205 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstSeq).retxCount, 0);
206 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstSeq + 1).retxCount, 0);
207
208 BOOST_REQUIRE_EQUAL(reliability->m_netPkts.size(), 1);
209 BOOST_REQUIRE_EQUAL(reliability->m_netPkts.count(firstSeq), 1);
210 BOOST_REQUIRE_EQUAL(reliability->m_netPkts.at(firstSeq).unackedFrags.size(), 2);
211 BOOST_CHECK_EQUAL(reliability->m_netPkts.at(firstSeq).unackedFrags.count(firstSeq), 1);
212 BOOST_CHECK_EQUAL(reliability->m_netPkts.at(firstSeq).unackedFrags.count(firstSeq + 1), 1);
213
214 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
215}
216
217BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
218{
219 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
220
221 shared_ptr<Interest> interest = makeInterest("/abc/def");
222
223 lp::Packet pkt1;
224 pkt1.add<lp::SequenceField>(999888);
225 pkt1.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
226
227 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
228
229 reliability->processIncomingPacket(pkt1);
230
231 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
232 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
233 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 999888);
234
235 lp::Packet pkt2;
236 pkt2.add<lp::SequenceField>(111222);
237 pkt2.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
238
239 reliability->processIncomingPacket(pkt2);
240
241 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
242 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
243 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 999888);
244 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 111222);
245
246 // T+5ms
247 advanceClocks(time::milliseconds(1), 5);
248 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
249}
250
251BOOST_AUTO_TEST_CASE(ProcessReceivedAcks)
252{
253 shared_ptr<Interest> interest = makeInterest("/abc/def");
254
255 lp::Packet pkt1;
256 pkt1.add<lp::SequenceField>(1024);
257 pkt1.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
258
259 lp::Packet pkt2;
260 pkt2.add<lp::SequenceField>(1025);
261 pkt2.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
262
263 linkService->sendLpPackets({pkt1, pkt2});
264
265 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1024), 1);
266 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1025), 1);
267 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1024).retxCount, 0);
268 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1025).retxCount, 0);
269 BOOST_REQUIRE_EQUAL(reliability->m_netPkts.count(1024), 1);
270 BOOST_CHECK_EQUAL(reliability->m_netPkts[1024].unackedFrags.size(), 2);
271 BOOST_CHECK_EQUAL(reliability->m_netPkts[1024].unackedFrags.count(1024), 1);
272 BOOST_CHECK_EQUAL(reliability->m_netPkts[1024].unackedFrags.count(1025), 1);
273
274 advanceClocks(time::milliseconds(1), 500);
275
276 lp::Packet ackPkt1;
277 ackPkt1.add<lp::AckField>(101010); // Unknown sequence number - ignored
278 ackPkt1.add<lp::AckField>(1025);
279
280 reliability->processIncomingPacket(ackPkt1);
281
282 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1024), 1);
283 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1025), 0);
284 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1024).retxCount, 0);
285 BOOST_REQUIRE_EQUAL(reliability->m_netPkts.count(1024), 1);
286 BOOST_CHECK_EQUAL(reliability->m_netPkts[1024].unackedFrags.size(), 1);
287 BOOST_CHECK_EQUAL(reliability->m_netPkts[1024].unackedFrags.count(1024), 1);
288
289 lp::Packet ackPkt2;
290 ackPkt2.add<lp::AckField>(1024);
291
292 reliability->processIncomingPacket(ackPkt2);
293
294 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
295 BOOST_CHECK_EQUAL(reliability->m_netPkts.size(), 0);
296}
297
298BOOST_AUTO_TEST_CASE(RetxUnackedSequence)
299{
300 shared_ptr<Interest> interest = makeInterest("/abc/def");
301
302 lp::Packet pkt1;
303 pkt1.add<lp::SequenceField>(1024);
304 pkt1.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
305
306 lp::Packet pkt2;
307 pkt2.add<lp::SequenceField>(1025);
308 pkt2.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
309
310 linkService->sendLpPackets({pkt1});
311 // T+500ms
312 // 1024 rto: 1000ms, started T+0ms, retx 0
313 advanceClocks(time::milliseconds(1), 500);
314 linkService->sendLpPackets({pkt2});
315
316 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1024), 1);
317 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1025), 1);
318 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1024).retxCount, 0);
319 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1025).retxCount, 0);
320 BOOST_REQUIRE_EQUAL(reliability->m_netPkts.count(1024), 1);
321 BOOST_REQUIRE_EQUAL(reliability->m_netPkts.count(1025), 1);
322 BOOST_CHECK_EQUAL(reliability->m_netPkts[1024].unackedFrags.size(), 1);
323 BOOST_CHECK_EQUAL(reliability->m_netPkts[1024].unackedFrags.count(1024), 1);
324 BOOST_CHECK_EQUAL(reliability->m_netPkts[1025].unackedFrags.size(), 1);
325 BOOST_CHECK_EQUAL(reliability->m_netPkts[1025].unackedFrags.count(1025), 1);
326
327 // T+1250ms
328 // 1024 rto: 1000ms, started T+1000ms, retx 1
329 // 1025 rto: 1000ms, started T+500ms, retx 0
330 advanceClocks(time::milliseconds(1), 750);
331
332 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1024), 1);
333 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1024).retxCount, 1);
334 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1025), 1);
335 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1025).retxCount, 0);
336
337 // T+2250ms
338 // 1024 rto: 1000ms, started T+2000ms, retx 2
339 // 1025 rto: 1000ms, started T+1500ms, retx 1
340 advanceClocks(time::milliseconds(1), 1000);
341
342 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1024), 1);
343 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1024).retxCount, 2);
344 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1025), 1);
345 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1025).retxCount, 1);
346
347 // T+3250ms
348 // 1024 rto: 1000ms, started T+3000ms, retx 3
349 // 1025 rto: 1000ms, started T+2500ms, retx 2
350 advanceClocks(time::milliseconds(1), 1000);
351
352 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1024), 1);
353 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1024).retxCount, 3);
354 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1025), 1);
355 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1025).retxCount, 2);
356
357 // T+4250ms
358 // 1024 rto: expired, removed
359 // 1025 rto: 1000ms, started T+3500ms, retx 3
360 advanceClocks(time::milliseconds(1), 1000);
361
362 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1024), 0);
363 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1025), 1);
364
365 // T+4750ms
366 // 1024 rto: expired, removed
367 // 1025 rto: expired, removed
368 advanceClocks(time::milliseconds(1), 1000);
369
370 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
371 BOOST_CHECK_EQUAL(reliability->m_netPkts.size(), 0);
372}
373
374BOOST_AUTO_TEST_CASE(LostPacketsWraparound)
375{
376 shared_ptr<Interest> interest = makeInterest("/abc/def");
377
378 lp::Packet pkt1;
379 pkt1.add<lp::SequenceField>(0xFFFFFFFFFFFFFFFF);
380 pkt1.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
381
382 lp::Packet pkt2;
383 pkt2.add<lp::SequenceField>(4);
384 pkt2.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
385
386 lp::Packet pkt3;
387 pkt3.add<lp::SequenceField>(5);
388 pkt3.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
389
390 lp::Packet pkt4;
391 pkt4.add<lp::SequenceField>(7);
392 pkt4.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
393
394 lp::Packet pkt5;
395 pkt5.add<lp::SequenceField>(8);
396 pkt5.add<lp::FragmentField>(make_pair(interest->wireEncode().begin(), interest->wireEncode().end()));
397
398 // Passed to sendLpPackets individually since they are from separate (encoded) network packets
399 linkService->sendLpPackets({pkt1});
400 linkService->sendLpPackets({pkt2});
401 linkService->sendLpPackets({pkt3});
402 linkService->sendLpPackets({pkt4});
403 linkService->sendLpPackets({pkt5});
404
405 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
406 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1);
407 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 1);
408 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 1);
409 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(7), 1);
410 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(8), 1);
411 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
412
413 lp::Packet ackPkt1;
414 ackPkt1.add<lp::AckField>(4);
415
416 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
417
418 reliability->processIncomingPacket(ackPkt1);
419
420 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 4);
421 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1);
422 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
423 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 1);
424 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 0);
425 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(5), 1);
426 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(5).retxCount, 0);
427 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(5).nGreaterSeqAcks, 0);
428 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(7), 1);
429 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(7).retxCount, 0);
430 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(7).nGreaterSeqAcks, 0);
431 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(8), 1);
432 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(8).retxCount, 0);
433 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(8).nGreaterSeqAcks, 0);
434 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
435 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
436
437 lp::Packet ackPkt2;
438 ackPkt2.add<lp::AckField>(7);
439
440 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
441
442 reliability->processIncomingPacket(ackPkt2);
443
444 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
445 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1);
446 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
447 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 2);
448 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 0);
449 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(5), 1);
450 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(5).retxCount, 0);
451 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(5).nGreaterSeqAcks, 1);
452 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(7), 0);
453 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(8), 1);
454 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(8).retxCount, 0);
455 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(8).nGreaterSeqAcks, 0);
456 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
457 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
458
459 lp::Packet ackPkt3;
460 ackPkt3.add<lp::AckField>(5);
461
462 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
463
464 reliability->processIncomingPacket(ackPkt3);
465
466 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
467 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1);
468 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 1);
469 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 3);
470 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 0);
471 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 0);
472 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(7), 0);
473 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(8), 1);
474 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(8).retxCount, 0);
475 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(8).nGreaterSeqAcks, 0);
476 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
477 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
478 lp::Packet sentRetxPkt(transport->sentPackets.back().packet);
479 BOOST_REQUIRE(sentRetxPkt.has<lp::SequenceField>());
480 BOOST_CHECK_EQUAL(sentRetxPkt.get<lp::SequenceField>(), 0xFFFFFFFFFFFFFFFF);
481
482 lp::Packet ackPkt4;
483 ackPkt4.add<lp::AckField>(0xFFFFFFFFFFFFFFFF);
484
485 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
486
487 reliability->processIncomingPacket(ackPkt4);
488
489 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
490 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0);
491 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 0);
492 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 0);
493 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(7), 0);
494 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(8), 1);
495 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(8).retxCount, 0);
496 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(8).nGreaterSeqAcks, 0);
497 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
498 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 8);
499}
500
501BOOST_AUTO_TEST_CASE(PiggybackAcks)
502{
503 reliability->m_ackQueue.push(256);
504 reliability->m_ackQueue.push(257);
505 reliability->m_ackQueue.push(10);
506
507 lp::Packet pkt;
508 pkt.add<lp::SequenceField>(123456);
509 linkService->sendLpPackets({pkt});
510
511 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
512 lp::Packet sentPkt(transport->sentPackets.front().packet);
513
514 BOOST_REQUIRE_EQUAL(sentPkt.count<lp::AckField>(), 3);
515 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(0), 256);
516 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(1), 257);
517 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(2), 10);
518
519 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
520}
521
522BOOST_AUTO_TEST_CASE(PiggybackAcksMtu)
523{
524 // This test case tests for piggybacking Acks when there is an MTU on the link.
525
526 reliability->m_ackQueue.push(1010);
527 reliability->m_ackQueue.push(1011);
528 reliability->m_ackQueue.push(1013);
529 reliability->m_ackQueue.push(1014);
530
531 Data data("/abc/def");
532
533 // Create a Data block containing 60 octets of content, which should fragment into 2 packets
534 uint8_t content[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
535 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
536 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
537 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
538 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
539 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
540
541 data.setContent(content, sizeof(content));
542 signData(data);
543
544 lp::Packet pkt1;
545 pkt1.add<lp::SequenceField>(123);
546 pkt1.add<lp::FragmentField>(make_pair(data.wireEncode().begin(), data.wireEncode().end()));
547
548 // Allow 2 Acks per packet, plus a little bit of extra space
549 // sizeof(lp::Sequence) + Ack Type (3 octets) + Ack Length (1 octet)
550 transport->setMtu(pkt1.wireEncode().size() + 2 * (sizeof(lp::Sequence) + 3 + 1) + 3);
551
552 linkService->sendLpPackets({pkt1});
553
554 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
555 lp::Packet sentPkt1(transport->sentPackets.front().packet);
556
557 BOOST_REQUIRE_EQUAL(sentPkt1.count<lp::AckField>(), 2);
558 BOOST_CHECK_EQUAL(sentPkt1.get<lp::AckField>(0), 1010);
559 BOOST_CHECK_EQUAL(sentPkt1.get<lp::AckField>(1), 1011);
560
561 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
562 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1013);
563 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1014);
564
565 lp::Packet pkt2;
566 pkt2.add<lp::SequenceField>(105623);
567 pkt2.add<lp::FragmentField>(make_pair(data.wireEncode().begin(), data.wireEncode().end()));
568
569 // Allow 1 Acks per packet, plus a little bit of extra space (1 Ack - 1 octet)
570 // sizeof(lp::Sequence) + Ack Type (3 octets) + Ack Length (1 octet)
571 transport->setMtu(pkt2.wireEncode().size() + 2 * (sizeof(lp::Sequence) + 3 + 1) - 1);
572
573 linkService->sendLpPackets({pkt2});
574
575 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 2);
576 lp::Packet sentPkt2(transport->sentPackets.back().packet);
577
578 BOOST_REQUIRE_EQUAL(sentPkt2.count<lp::AckField>(), 1);
579 BOOST_CHECK_EQUAL(sentPkt2.get<lp::AckField>(), 1013);
580
581 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
582 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1014);
583
584 lp::Packet pkt3;
585 pkt3.add<lp::SequenceField>(969456);
586 pkt3.add<lp::FragmentField>(make_pair(data.wireEncode().begin(), data.wireEncode().end()));
587
588 // Allow 3 Acks per packet
589 // sizeof(lp::Sequence) + Ack Type (3 octets) + Ack Length (1 octet)
590 transport->setMtu(pkt3.wireEncode().size() + 3 * (sizeof(lp::Sequence) + 3 + 1));
591
592 linkService->sendLpPackets({pkt3});
593
594 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 3);
595 lp::Packet sentPkt3(transport->sentPackets.back().packet);
596
597 BOOST_REQUIRE_EQUAL(sentPkt3.count<lp::AckField>(), 1);
598 BOOST_CHECK_EQUAL(sentPkt3.get<lp::AckField>(), 1014);
599
600 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
601}
602
603BOOST_AUTO_TEST_CASE(IdleAckTimer)
604{
605 // T+1ms
606 advanceClocks(time::milliseconds(1), 1);
607
608 reliability->m_ackQueue.push(5000);
609 reliability->m_ackQueue.push(5001);
610 reliability->m_ackQueue.push(5002);
611 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
612 reliability->startIdleAckTimer();
613 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
614
615 // T+5ms
616 advanceClocks(time::milliseconds(1), 4);
617 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
618 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
619
620 // T+6ms
621 advanceClocks(time::milliseconds(1), 1);
622
623 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
624 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
625 lp::Packet sentPkt1(transport->sentPackets.back().packet);
626
627 BOOST_REQUIRE_EQUAL(sentPkt1.count<lp::AckField>(), 3);
628 BOOST_CHECK_EQUAL(sentPkt1.get<lp::AckField>(0), 5000);
629 BOOST_CHECK_EQUAL(sentPkt1.get<lp::AckField>(1), 5001);
630 BOOST_CHECK_EQUAL(sentPkt1.get<lp::AckField>(2), 5002);
631
632 reliability->m_ackQueue.push(5003);
633 reliability->m_ackQueue.push(5004);
634 reliability->startIdleAckTimer();
635 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
636
637 // T+10ms
638 advanceClocks(time::milliseconds(1), 4);
639 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
640 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
641
642 // T+11ms
643 advanceClocks(time::milliseconds(1), 1);
644
645 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
646 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 2);
647 lp::Packet sentPkt2(transport->sentPackets.back().packet);
648
649 BOOST_REQUIRE_EQUAL(sentPkt2.count<lp::AckField>(), 2);
650 BOOST_CHECK_EQUAL(sentPkt2.get<lp::AckField>(0), 5003);
651 BOOST_CHECK_EQUAL(sentPkt2.get<lp::AckField>(1), 5004);
652
653 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
654
655 // T+16ms
656 advanceClocks(time::milliseconds(1), 5);
657
658 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
659 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
660 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
661}
662
663BOOST_AUTO_TEST_CASE(IdleAckTimerMtu)
664{
665 // 1 (LpPacket Type) + 1 (LpPacket Length) + 2 Acks
666 transport->setMtu(lp::Packet().wireEncode().size() + 2 * (sizeof(lp::Sequence) + 3 + 1));
667
668 // T+1ms
669 advanceClocks(time::milliseconds(1), 1);
670
671 reliability->m_ackQueue.push(3000);
672 reliability->m_ackQueue.push(3001);
673 reliability->m_ackQueue.push(3002);
674 reliability->m_ackQueue.push(3003);
675 reliability->m_ackQueue.push(3004);
676 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
677 reliability->startIdleAckTimer();
678 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
679
680 // T+5ms
681 advanceClocks(time::milliseconds(1), 4);
682 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
683 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
684
685 // T+6ms
686 advanceClocks(time::milliseconds(1), 1);
687
688 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
689
690 reliability->m_ackQueue.push(3005);
691 reliability->m_ackQueue.push(3006);
692 reliability->startIdleAckTimer();
693 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
694
695 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 3);
696 lp::Packet sentPkt1(transport->sentPackets[0].packet);
697 BOOST_REQUIRE_EQUAL(sentPkt1.count<lp::AckField>(), 2);
698 BOOST_CHECK_EQUAL(sentPkt1.get<lp::AckField>(0), 3000);
699 BOOST_CHECK_EQUAL(sentPkt1.get<lp::AckField>(1), 3001);
700 lp::Packet sentPkt2(transport->sentPackets[1].packet);
701 BOOST_REQUIRE_EQUAL(sentPkt2.count<lp::AckField>(), 2);
702 BOOST_CHECK_EQUAL(sentPkt2.get<lp::AckField>(0), 3002);
703 BOOST_CHECK_EQUAL(sentPkt2.get<lp::AckField>(1), 3003);
704 lp::Packet sentPkt3(transport->sentPackets[2].packet);
705 BOOST_REQUIRE_EQUAL(sentPkt3.count<lp::AckField>(), 1);
706 BOOST_CHECK_EQUAL(sentPkt3.get<lp::AckField>(), 3004);
707
708 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
709 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 3005);
710 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 3006);
711
712 // T+10ms
713 advanceClocks(time::milliseconds(1), 4);
714 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
715 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
716
717 // T+11ms
718 advanceClocks(time::milliseconds(1), 1);
719
720 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
721
722 reliability->m_ackQueue.push(3007);
723 reliability->startIdleAckTimer();
724
725 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
726 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 4);
727 lp::Packet sentPkt4(transport->sentPackets[3].packet);
728 BOOST_REQUIRE_EQUAL(sentPkt4.count<lp::AckField>(), 2);
729 BOOST_CHECK_EQUAL(sentPkt4.get<lp::AckField>(0), 3005);
730 BOOST_CHECK_EQUAL(sentPkt4.get<lp::AckField>(1), 3006);
731
732 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
733 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 3007);
734 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
735
736 // T+15ms
737 advanceClocks(time::milliseconds(1), 4);
738 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
739 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 4);
740
741 // T+16ms
742 advanceClocks(time::milliseconds(1), 1);
743
744 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
745 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
746 lp::Packet sentPkt5(transport->sentPackets[4].packet);
747 BOOST_REQUIRE_EQUAL(sentPkt5.count<lp::AckField>(), 1);
748 BOOST_CHECK_EQUAL(sentPkt5.get<lp::AckField>(), 3007);
749
750 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
751
752 // T+21ms
753 advanceClocks(time::milliseconds(1), 5);
754
755 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
756 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
757 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
758}
759
760BOOST_AUTO_TEST_SUITE_END() // TestLpReliability
761
762BOOST_AUTO_TEST_SUITE_END() // Face
763
764} // namespace tests
765} // namespace face
766} // namespace nfd