blob: 8006fbb254250f4109c0debed500e4cfff8257a0 [file] [log] [blame]
Eric Newberrya98bf932015-09-21 00:58:47 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberry7b0071e2017-07-03 17:33:31 +00002/*
Davide Pesavento1d12d2f2019-03-22 12:44:14 -04003 * Copyright (c) 2014-2019, Regents of the University of California,
Eric Newberrya98bf932015-09-21 00:58:47 -07004 * 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/generic-link-service.hpp"
Junxiao Shicde37ad2015-12-24 01:02:05 -070027#include "face/face.hpp"
Eric Newberrya98bf932015-09-21 00:58:47 -070028
Davide Pesavento0064c1d2018-03-03 18:43:53 -050029#include "tests/test-common.hpp"
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040030#include "tests/key-chain-fixture.hpp"
31#include "tests/daemon/global-io-fixture.hpp"
32#include "dummy-transport.hpp"
Eric Newberryb49313d2017-12-24 20:22:27 -070033
Teng Liangfdcbb4d2018-01-27 16:01:35 -070034#include <ndn-cxx/lp/empty-value.hpp>
Teng Liangbce3cb52018-09-05 20:08:27 -070035#include <ndn-cxx/lp/prefix-announcement-header.hpp>
Eric Newberryb49313d2017-12-24 20:22:27 -070036#include <ndn-cxx/lp/tags.hpp>
Teng Liangbce3cb52018-09-05 20:08:27 -070037#include <ndn-cxx/security/signing-helpers.hpp>
Eric Newberrya98bf932015-09-21 00:58:47 -070038
39namespace nfd {
40namespace face {
41namespace tests {
42
43using namespace nfd::tests;
44
45BOOST_AUTO_TEST_SUITE(Face)
46
Junxiao Shicde37ad2015-12-24 01:02:05 -070047using nfd::Face;
48
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040049class GenericLinkServiceFixture : public GlobalIoTimeFixture, public KeyChainFixture
Eric Newberrya98bf932015-09-21 00:58:47 -070050{
51protected:
52 GenericLinkServiceFixture()
Eric Newberrya98bf932015-09-21 00:58:47 -070053 {
Eric Newberrya98bf932015-09-21 00:58:47 -070054 // By default, GenericLinkService is created with default options.
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040055 // Test cases may invoke initialize() with alternate options.
56 initialize({});
Eric Newberrya98bf932015-09-21 00:58:47 -070057 }
58
59 void
Eric Newberryb49313d2017-12-24 20:22:27 -070060 initialize(const GenericLinkService::Options& options,
61 ssize_t mtu = MTU_UNLIMITED,
62 ssize_t sendQueueCapacity = QUEUE_UNSUPPORTED)
Eric Newberrya98bf932015-09-21 00:58:47 -070063 {
Davide Pesaventoe4b22382018-06-10 14:37:24 -040064 face = make_unique<Face>(make_unique<GenericLinkService>(options),
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040065 make_unique<DummyTransport>("dummy://", "dummy://",
Davide Pesaventoe4b22382018-06-10 14:37:24 -040066 ndn::nfd::FACE_SCOPE_NON_LOCAL,
67 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
68 ndn::nfd::LINK_TYPE_POINT_TO_POINT,
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040069 mtu, sendQueueCapacity));
Eric Newberrya98bf932015-09-21 00:58:47 -070070 service = static_cast<GenericLinkService*>(face->getLinkService());
71 transport = static_cast<DummyTransport*>(face->getTransport());
72
73 face->afterReceiveInterest.connect(
ashiqopu075bb7d2019-03-10 01:38:21 +000074 [this] (const Interest& interest, const EndpointId&) { receivedInterests.push_back(interest); });
Eric Newberrya98bf932015-09-21 00:58:47 -070075 face->afterReceiveData.connect(
ashiqopu075bb7d2019-03-10 01:38:21 +000076 [this] (const Data& data, const EndpointId&) { receivedData.push_back(data); });
Eric Newberrya98bf932015-09-21 00:58:47 -070077 face->afterReceiveNack.connect(
ashiqopu075bb7d2019-03-10 01:38:21 +000078 [this] (const lp::Nack& nack, const EndpointId&) { receivedNacks.push_back(nack); });
Eric Newberrya98bf932015-09-21 00:58:47 -070079 }
80
Teng Liangbce3cb52018-09-05 20:08:27 -070081 lp::PrefixAnnouncementHeader
82 makePrefixAnnHeader(const Name& announcedName)
83 {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040084 return lp::PrefixAnnouncementHeader{signPrefixAnn(makePrefixAnn(announcedName, 1_h),
85 m_keyChain, ndn::signingWithSha256())};
Teng Liangbce3cb52018-09-05 20:08:27 -070086 }
87
Eric Newberrya98bf932015-09-21 00:58:47 -070088protected:
Junxiao Shicde37ad2015-12-24 01:02:05 -070089 unique_ptr<Face> face;
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040090 GenericLinkService* service = nullptr;
91 DummyTransport* transport = nullptr;
Eric Newberrya98bf932015-09-21 00:58:47 -070092 std::vector<Interest> receivedInterests;
93 std::vector<Data> receivedData;
94 std::vector<lp::Nack> receivedNacks;
95};
96
97BOOST_FIXTURE_TEST_SUITE(TestGenericLinkService, GenericLinkServiceFixture)
98
Eric Newberrya98bf932015-09-21 00:58:47 -070099BOOST_AUTO_TEST_SUITE(SimpleSendReceive) // send and receive without other fields
100
101BOOST_AUTO_TEST_CASE(SendInterest)
102{
Eric Newberry86d31872015-09-23 16:24:59 -0700103 // Initialize with Options that disables all services
104 GenericLinkService::Options options;
105 options.allowLocalFields = false;
106 initialize(options);
Eric Newberrya98bf932015-09-21 00:58:47 -0700107
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400108 auto interest1 = makeInterest("/localhost/test");
ashiqopu075bb7d2019-03-10 01:38:21 +0000109 face->sendInterest(*interest1, 0);
Eric Newberrya98bf932015-09-21 00:58:47 -0700110
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700111 BOOST_CHECK_EQUAL(service->getCounters().nOutInterests, 1);
Eric Newberrya98bf932015-09-21 00:58:47 -0700112 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400113 lp::Packet interest1pkt(transport->sentPackets.back().packet);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700114 BOOST_CHECK(interest1pkt.has<lp::FragmentField>());
115 BOOST_CHECK(!interest1pkt.has<lp::SequenceField>());
Eric Newberrya98bf932015-09-21 00:58:47 -0700116}
117
118BOOST_AUTO_TEST_CASE(SendData)
119{
Eric Newberry86d31872015-09-23 16:24:59 -0700120 // Initialize with Options that disables all services
121 GenericLinkService::Options options;
122 options.allowLocalFields = false;
123 initialize(options);
Eric Newberrya98bf932015-09-21 00:58:47 -0700124
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400125 auto data1 = makeData("/localhost/test");
ashiqopu075bb7d2019-03-10 01:38:21 +0000126 face->sendData(*data1, 0);
Eric Newberrya98bf932015-09-21 00:58:47 -0700127
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700128 BOOST_CHECK_EQUAL(service->getCounters().nOutData, 1);
Eric Newberrya98bf932015-09-21 00:58:47 -0700129 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400130 lp::Packet data1pkt(transport->sentPackets.back().packet);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700131 BOOST_CHECK(data1pkt.has<lp::FragmentField>());
132 BOOST_CHECK(!data1pkt.has<lp::SequenceField>());
Eric Newberrya98bf932015-09-21 00:58:47 -0700133}
134
135BOOST_AUTO_TEST_CASE(SendNack)
136{
Eric Newberry86d31872015-09-23 16:24:59 -0700137 // Initialize with Options that disables all services
138 GenericLinkService::Options options;
139 options.allowLocalFields = false;
140 initialize(options);
Eric Newberrya98bf932015-09-21 00:58:47 -0700141
Junxiao Shi9d727852019-05-14 13:44:22 -0600142 auto nack1 = makeNack(*makeInterest("/localhost/test", false, nullopt, 323),
143 lp::NackReason::NO_ROUTE);
ashiqopu075bb7d2019-03-10 01:38:21 +0000144 face->sendNack(nack1, 0);
Eric Newberrya98bf932015-09-21 00:58:47 -0700145
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700146 BOOST_CHECK_EQUAL(service->getCounters().nOutNacks, 1);
Eric Newberrya98bf932015-09-21 00:58:47 -0700147 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400148 lp::Packet nack1pkt(transport->sentPackets.back().packet);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700149 BOOST_CHECK(nack1pkt.has<lp::NackField>());
150 BOOST_CHECK(nack1pkt.has<lp::FragmentField>());
151 BOOST_CHECK(!nack1pkt.has<lp::SequenceField>());
Eric Newberrya98bf932015-09-21 00:58:47 -0700152}
153
154BOOST_AUTO_TEST_CASE(ReceiveBareInterest)
155{
Eric Newberry86d31872015-09-23 16:24:59 -0700156 // Initialize with Options that disables all services
157 GenericLinkService::Options options;
158 options.allowLocalFields = false;
159 initialize(options);
Eric Newberrya98bf932015-09-21 00:58:47 -0700160
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400161 auto interest1 = makeInterest("/23Rd9hEiR");
Eric Newberrya98bf932015-09-21 00:58:47 -0700162 transport->receivePacket(interest1->wireEncode());
163
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700164 BOOST_CHECK_EQUAL(service->getCounters().nInInterests, 1);
Eric Newberrya98bf932015-09-21 00:58:47 -0700165 BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400166 BOOST_CHECK_EQUAL(receivedInterests.back().wireEncode(), interest1->wireEncode());
Eric Newberrya98bf932015-09-21 00:58:47 -0700167}
168
169BOOST_AUTO_TEST_CASE(ReceiveInterest)
170{
Eric Newberry86d31872015-09-23 16:24:59 -0700171 // Initialize with Options that disables all services
172 GenericLinkService::Options options;
173 options.allowLocalFields = false;
174 initialize(options);
Eric Newberrya98bf932015-09-21 00:58:47 -0700175
Junxiao Shi9d727852019-05-14 13:44:22 -0600176 auto interest1 = makeInterest("/23Rd9hEiR");
Eric Newberrya98bf932015-09-21 00:58:47 -0700177 lp::Packet lpPacket;
178 lpPacket.set<lp::FragmentField>(std::make_pair(
179 interest1->wireEncode().begin(), interest1->wireEncode().end()));
180 lpPacket.set<lp::SequenceField>(0); // force LpPacket encoding
181
182 transport->receivePacket(lpPacket.wireEncode());
183
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700184 BOOST_CHECK_EQUAL(service->getCounters().nInInterests, 1);
Eric Newberrya98bf932015-09-21 00:58:47 -0700185 BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400186 BOOST_CHECK_EQUAL(receivedInterests.back().wireEncode(), interest1->wireEncode());
Eric Newberrya98bf932015-09-21 00:58:47 -0700187}
188
189BOOST_AUTO_TEST_CASE(ReceiveBareData)
190{
Eric Newberry86d31872015-09-23 16:24:59 -0700191 // Initialize with Options that disables all services
192 GenericLinkService::Options options;
193 options.allowLocalFields = false;
194 initialize(options);
Eric Newberrya98bf932015-09-21 00:58:47 -0700195
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400196 auto data1 = makeData("/12345678");
Eric Newberrya98bf932015-09-21 00:58:47 -0700197 transport->receivePacket(data1->wireEncode());
198
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700199 BOOST_CHECK_EQUAL(service->getCounters().nInData, 1);
Eric Newberrya98bf932015-09-21 00:58:47 -0700200 BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400201 BOOST_CHECK_EQUAL(receivedData.back().wireEncode(), data1->wireEncode());
Eric Newberrya98bf932015-09-21 00:58:47 -0700202}
203
204BOOST_AUTO_TEST_CASE(ReceiveData)
205{
Eric Newberry86d31872015-09-23 16:24:59 -0700206 // Initialize with Options that disables all services
207 GenericLinkService::Options options;
208 options.allowLocalFields = false;
209 initialize(options);
Eric Newberrya98bf932015-09-21 00:58:47 -0700210
Junxiao Shi9d727852019-05-14 13:44:22 -0600211 auto data1 = makeData("/12345689");
Eric Newberrya98bf932015-09-21 00:58:47 -0700212 lp::Packet lpPacket;
213 lpPacket.set<lp::FragmentField>(std::make_pair(
214 data1->wireEncode().begin(), data1->wireEncode().end()));
215 lpPacket.set<lp::SequenceField>(0); // force LpPacket encoding
216
217 transport->receivePacket(lpPacket.wireEncode());
218
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700219 BOOST_CHECK_EQUAL(service->getCounters().nInData, 1);
Eric Newberrya98bf932015-09-21 00:58:47 -0700220 BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400221 BOOST_CHECK_EQUAL(receivedData.back().wireEncode(), data1->wireEncode());
Eric Newberrya98bf932015-09-21 00:58:47 -0700222}
223
224BOOST_AUTO_TEST_CASE(ReceiveNack)
225{
Eric Newberry86d31872015-09-23 16:24:59 -0700226 // Initialize with Options that disables all services
227 GenericLinkService::Options options;
228 options.allowLocalFields = false;
229 initialize(options);
Eric Newberrya98bf932015-09-21 00:58:47 -0700230
Junxiao Shi9d727852019-05-14 13:44:22 -0600231 lp::Nack nack1 = makeNack(*makeInterest("/localhost/test", false, nullopt, 323),
232 lp::NackReason::NO_ROUTE);
Eric Newberrya98bf932015-09-21 00:58:47 -0700233 lp::Packet lpPacket;
234 lpPacket.set<lp::FragmentField>(std::make_pair(
235 nack1.getInterest().wireEncode().begin(), nack1.getInterest().wireEncode().end()));
236 lpPacket.set<lp::NackField>(nack1.getHeader());
237
238 transport->receivePacket(lpPacket.wireEncode());
239
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700240 BOOST_CHECK_EQUAL(service->getCounters().nInNacks, 1);
Eric Newberrya98bf932015-09-21 00:58:47 -0700241 BOOST_REQUIRE_EQUAL(receivedNacks.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400242 BOOST_CHECK_EQUAL(receivedNacks.back().getReason(), nack1.getReason());
243 BOOST_CHECK_EQUAL(receivedNacks.back().getInterest().wireEncode(), nack1.getInterest().wireEncode());
Eric Newberrya98bf932015-09-21 00:58:47 -0700244}
245
Eric Newberrya1939ba2015-10-09 12:35:03 -0700246BOOST_AUTO_TEST_CASE(ReceiveIdlePacket)
247{
248 // Initialize with Options that disables all services
249 GenericLinkService::Options options;
250 options.allowLocalFields = false;
251 initialize(options);
252
253 lp::Packet lpPacket;
254 lpPacket.set<lp::SequenceField>(0);
255
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400256 transport->receivePacket(lpPacket.wireEncode());
Eric Newberrya1939ba2015-10-09 12:35:03 -0700257
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700258 // IDLE packet should be ignored, but is not an error
259 BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 0);
Eric Newberrya1939ba2015-10-09 12:35:03 -0700260 BOOST_CHECK_EQUAL(receivedInterests.size(), 0);
261 BOOST_CHECK_EQUAL(receivedData.size(), 0);
262 BOOST_CHECK_EQUAL(receivedNacks.size(), 0);
263}
264
Eric Newberrya98bf932015-09-21 00:58:47 -0700265BOOST_AUTO_TEST_SUITE_END() // SimpleSendReceive
266
Eric Newberry86d31872015-09-23 16:24:59 -0700267BOOST_AUTO_TEST_SUITE(Fragmentation)
268
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700269BOOST_AUTO_TEST_CASE(FragmentationDisabledExceedMtuDrop)
270{
271 // Initialize with Options that disable fragmentation
272 GenericLinkService::Options options;
273 options.allowFragmentation = false;
274 initialize(options);
275
276 transport->setMtu(55);
277
Junxiao Shi9d727852019-05-14 13:44:22 -0600278 auto data = makeData("/test/data/123456789/987654321/123456789");
ashiqopu075bb7d2019-03-10 01:38:21 +0000279 face->sendData(*data, 0);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700280
281 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
282 BOOST_CHECK_EQUAL(service->getCounters().nOutOverMtu, 1);
283}
284
285BOOST_AUTO_TEST_CASE(FragmentationUnlimitedMtu)
286{
287 // Initialize with Options that enable fragmentation
288 GenericLinkService::Options options;
289 options.allowFragmentation = true;
290 initialize(options);
291
292 transport->setMtu(MTU_UNLIMITED);
293
Junxiao Shi9d727852019-05-14 13:44:22 -0600294 auto data = makeData("/test/data/123456789/987654321/123456789");
ashiqopu075bb7d2019-03-10 01:38:21 +0000295 face->sendData(*data, 0);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700296
297 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
298}
299
300BOOST_AUTO_TEST_CASE(FragmentationUnderMtu)
301{
302 // Initialize with Options that enable fragmentation
303 GenericLinkService::Options options;
304 options.allowFragmentation = true;
305 initialize(options);
306
307 transport->setMtu(105);
308
Junxiao Shi9d727852019-05-14 13:44:22 -0600309 auto data = makeData("/test/data/123456789/987654321/123456789");
ashiqopu075bb7d2019-03-10 01:38:21 +0000310 face->sendData(*data, 0);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700311
312 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
313}
314
315BOOST_AUTO_TEST_CASE(FragmentationOverMtu)
316{
317 // Initialize with Options that enable fragmentation
318 GenericLinkService::Options options;
319 options.allowFragmentation = true;
320 initialize(options);
321
322 transport->setMtu(60);
323
Junxiao Shi9d727852019-05-14 13:44:22 -0600324 auto data = makeData("/test/data/123456789/987654321/123456789");
ashiqopu075bb7d2019-03-10 01:38:21 +0000325 face->sendData(*data, 0);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700326
327 BOOST_CHECK_GT(transport->sentPackets.size(), 1);
328}
329
330BOOST_AUTO_TEST_CASE(ReassembleFragments)
331{
332 // Initialize with Options that enables reassembly
333 GenericLinkService::Options options;
334 options.allowReassembly = true;
335 initialize(options);
336
Junxiao Shi9d727852019-05-14 13:44:22 -0600337 auto interest = makeInterest(
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700338 "/mt7P130BHXmtLm5dwaY5dpUM6SWYNN2B05g7y3UhsQuLvDdnTWdNnTeEiLuW3FAbJRSG3tzQ0UfaSEgG9rvYHmsKtgPMag1Hj4Tr");
339 lp::Packet packet(interest->wireEncode());
340
341 // fragment the packet
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400342 LpFragmenter fragmenter({});
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700343 size_t mtu = 100;
344 bool isOk = false;
345 std::vector<lp::Packet> frags;
346 std::tie(isOk, frags) = fragmenter.fragmentPacket(packet, mtu);
347 BOOST_REQUIRE(isOk);
348 BOOST_CHECK_GT(frags.size(), 1);
349
350 // receive the fragments
351 for (ssize_t fragIndex = frags.size() - 1; fragIndex >= 0; --fragIndex) {
352 size_t sequence = 1000 + fragIndex;
353 frags[fragIndex].add<lp::SequenceField>(sequence);
354
355 transport->receivePacket(frags[fragIndex].wireEncode());
356
357 if (fragIndex > 0) {
358 BOOST_CHECK(receivedInterests.empty());
359 BOOST_CHECK_EQUAL(service->getCounters().nReassembling, 1);
360 }
361 else {
362 BOOST_CHECK_EQUAL(receivedInterests.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400363 BOOST_CHECK_EQUAL(receivedInterests.back().wireEncode(), interest->wireEncode());
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700364 BOOST_CHECK_EQUAL(service->getCounters().nReassembling, 0);
365 }
366 }
367}
368
Eric Newberry86d31872015-09-23 16:24:59 -0700369BOOST_AUTO_TEST_CASE(ReassemblyDisabledDropFragIndex)
370{
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700371 // Initialize with Options that disables reassembly
372 GenericLinkService::Options options;
373 options.allowReassembly = false;
374 initialize(options);
Eric Newberry86d31872015-09-23 16:24:59 -0700375
Junxiao Shi9d727852019-05-14 13:44:22 -0600376 auto interest = makeInterest("/IgFe6NvH");
Eric Newberry86d31872015-09-23 16:24:59 -0700377 lp::Packet packet(interest->wireEncode());
378 packet.set<lp::FragIndexField>(140);
379
380 transport->receivePacket(packet.wireEncode());
381
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700382 BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 0); // not an error
Eric Newberry86d31872015-09-23 16:24:59 -0700383 BOOST_CHECK(receivedInterests.empty());
384}
385
386BOOST_AUTO_TEST_CASE(ReassemblyDisabledDropFragCount)
387{
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700388 // Initialize with Options that disables reassembly
389 GenericLinkService::Options options;
390 options.allowReassembly = false;
391 initialize(options);
Eric Newberry86d31872015-09-23 16:24:59 -0700392
Junxiao Shi9d727852019-05-14 13:44:22 -0600393 auto interest = makeInterest("/SeGmEjvIVX");
Eric Newberry86d31872015-09-23 16:24:59 -0700394 lp::Packet packet(interest->wireEncode());
395 packet.set<lp::FragCountField>(276);
396
397 transport->receivePacket(packet.wireEncode());
398
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700399 BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 0); // not an error
Eric Newberry86d31872015-09-23 16:24:59 -0700400 BOOST_CHECK(receivedInterests.empty());
401}
402
403BOOST_AUTO_TEST_SUITE_END() // Fragmentation
404
Eric Newberry185ab292017-03-28 06:45:39 +0000405BOOST_AUTO_TEST_SUITE(Reliability)
406
Eric Newberry7b0071e2017-07-03 17:33:31 +0000407BOOST_AUTO_TEST_CASE(SendInterest)
Eric Newberry185ab292017-03-28 06:45:39 +0000408{
409 // Initialize with Options that enables reliability
410 GenericLinkService::Options options;
411 options.allowLocalFields = false;
412 options.reliabilityOptions.isEnabled = true;
413 initialize(options);
414
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400415 auto interest1 = makeInterest("/localhost/test");
ashiqopu075bb7d2019-03-10 01:38:21 +0000416 face->sendInterest(*interest1, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000417
418 BOOST_CHECK_EQUAL(service->getCounters().nOutInterests, 1);
419 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400420 lp::Packet interest1pkt(transport->sentPackets.back().packet);
Eric Newberry185ab292017-03-28 06:45:39 +0000421 BOOST_CHECK(interest1pkt.has<lp::FragmentField>());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000422 BOOST_CHECK(interest1pkt.has<lp::TxSequenceField>());
Eric Newberry185ab292017-03-28 06:45:39 +0000423}
424
Eric Newberry7b0071e2017-07-03 17:33:31 +0000425BOOST_AUTO_TEST_CASE(SendData)
Eric Newberry185ab292017-03-28 06:45:39 +0000426{
427 // Initialize with Options that enables reliability
428 GenericLinkService::Options options;
429 options.allowLocalFields = false;
430 options.reliabilityOptions.isEnabled = true;
431 initialize(options);
432
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400433 auto data1 = makeData("/localhost/test");
ashiqopu075bb7d2019-03-10 01:38:21 +0000434 face->sendData(*data1, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000435
436 BOOST_CHECK_EQUAL(service->getCounters().nOutData, 1);
437 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400438 lp::Packet data1pkt(transport->sentPackets.back().packet);
Eric Newberry185ab292017-03-28 06:45:39 +0000439 BOOST_CHECK(data1pkt.has<lp::FragmentField>());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000440 BOOST_CHECK(data1pkt.has<lp::TxSequenceField>());
Eric Newberry185ab292017-03-28 06:45:39 +0000441}
442
Eric Newberry7b0071e2017-07-03 17:33:31 +0000443BOOST_AUTO_TEST_CASE(SendNack)
Eric Newberry185ab292017-03-28 06:45:39 +0000444{
445 // Initialize with Options that enables reliability
446 GenericLinkService::Options options;
447 options.allowLocalFields = false;
448 options.reliabilityOptions.isEnabled = true;
449 initialize(options);
450
Junxiao Shi9d727852019-05-14 13:44:22 -0600451 auto nack1 = makeNack(*makeInterest("/localhost/test", false, nullopt, 323),
452 lp::NackReason::NO_ROUTE);
ashiqopu075bb7d2019-03-10 01:38:21 +0000453 face->sendNack(nack1, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000454
455 BOOST_CHECK_EQUAL(service->getCounters().nOutNacks, 1);
456 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400457 lp::Packet nack1pkt(transport->sentPackets.back().packet);
Eric Newberry185ab292017-03-28 06:45:39 +0000458 BOOST_CHECK(nack1pkt.has<lp::NackField>());
459 BOOST_CHECK(nack1pkt.has<lp::FragmentField>());
Eric Newberry7b0071e2017-07-03 17:33:31 +0000460 BOOST_CHECK(nack1pkt.has<lp::TxSequenceField>());
Eric Newberry185ab292017-03-28 06:45:39 +0000461}
462
463BOOST_AUTO_TEST_SUITE_END() // Reliability
Eric Newberry86d31872015-09-23 16:24:59 -0700464
Eric Newberryb49313d2017-12-24 20:22:27 -0700465// congestion detection and marking
466BOOST_AUTO_TEST_SUITE(CongestionMark)
467
468BOOST_AUTO_TEST_CASE(NoCongestion)
469{
470 GenericLinkService::Options options;
471 options.allowCongestionMarking = true;
Davide Pesavento14e71f02019-03-28 17:35:25 -0400472 options.baseCongestionMarkingInterval = 100_ms;
Eric Newberryb49313d2017-12-24 20:22:27 -0700473 initialize(options, MTU_UNLIMITED, 65536);
474 BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
475 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
476 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);
477
Junxiao Shi9d727852019-05-14 13:44:22 -0600478 auto interest = makeInterest("/12345678");
Eric Newberryb49313d2017-12-24 20:22:27 -0700479
480 // congestion threshold will be 32768 bytes, since min(65536, 65536 / 2) = 32768 bytes
481
482 // no congestion
483 transport->setSendQueueLength(0);
ashiqopu075bb7d2019-03-10 01:38:21 +0000484 face->sendInterest(*interest, 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700485 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400486 lp::Packet pkt1(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700487 BOOST_CHECK_EQUAL(pkt1.count<lp::CongestionMarkField>(), 0);
488 BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
489 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
490 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);
491
492 // no congestion
493 transport->setSendQueueLength(32768);
ashiqopu075bb7d2019-03-10 01:38:21 +0000494 face->sendInterest(*interest, 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700495 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 2);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400496 lp::Packet pkt2(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700497 BOOST_CHECK_EQUAL(pkt2.count<lp::CongestionMarkField>(), 0);
498 BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
499 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
500 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);
501}
502
503BOOST_AUTO_TEST_CASE(CongestionCoDel)
504{
505 GenericLinkService::Options options;
506 options.allowCongestionMarking = true;
Davide Pesavento14e71f02019-03-28 17:35:25 -0400507 options.baseCongestionMarkingInterval = 100_ms;
Eric Newberryb49313d2017-12-24 20:22:27 -0700508 initialize(options, MTU_UNLIMITED, 65536);
509 BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
Eric Newberryb49313d2017-12-24 20:22:27 -0700510 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
511 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);
512
Junxiao Shi9d727852019-05-14 13:44:22 -0600513 auto interest = makeInterest("/12345678");
Eric Newberryb49313d2017-12-24 20:22:27 -0700514
Klaus Schneider380668b2019-10-02 01:21:13 -0700515 // first congested packet, will not be marked
516 transport->setSendQueueLength(65537);
ashiqopu075bb7d2019-03-10 01:38:21 +0000517 face->sendInterest(*interest, 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700518 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Klaus Schneider380668b2019-10-02 01:21:13 -0700519 lp::Packet pkt0(transport->sentPackets.back().packet);
520 BOOST_REQUIRE_EQUAL(pkt0.count<lp::CongestionMarkField>(), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400521 time::steady_clock::TimePoint nextMarkTime = time::steady_clock::now() + 100_ms;
Eric Newberryb49313d2017-12-24 20:22:27 -0700522 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Klaus Schneider380668b2019-10-02 01:21:13 -0700523
524 time::nanoseconds markingInterval(
525 static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
526 std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
527
528 advanceClocks(markingInterval + 1_ms);
529 face->sendInterest(*interest, 0);
530 lp::Packet pkt1(transport->sentPackets.back().packet);
531
532 // First congestion mark appears after one interval (100 ms)
533 BOOST_REQUIRE_EQUAL(pkt1.count<lp::CongestionMarkField>(), 1);
534 BOOST_CHECK_EQUAL(pkt1.get<lp::CongestionMarkField>(), 1);
Eric Newberryb49313d2017-12-24 20:22:27 -0700535 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 1);
536 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 1);
537
538 // advance clock to half of marking interval cycle
Klaus Schneider380668b2019-10-02 01:21:13 -0700539 advanceClocks(markingInterval / 2); // 50ms
Eric Newberryb49313d2017-12-24 20:22:27 -0700540
541 // second congested packet, but within marking interval, will not be marked
Klaus Schneider380668b2019-10-02 01:21:13 -0700542 transport->setSendQueueLength(66000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000543 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700544 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 3);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400545 lp::Packet pkt2(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700546 BOOST_CHECK_EQUAL(pkt2.count<lp::CongestionMarkField>(), 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700547
548 markingInterval = time::nanoseconds(
549 static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
550 std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
551 nextMarkTime += markingInterval;
552
Eric Newberryb49313d2017-12-24 20:22:27 -0700553 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Eric Newberryb49313d2017-12-24 20:22:27 -0700554 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 1);
555 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 1);
556
557 // advance clocks past end of initial interval cycle
Klaus Schneider380668b2019-10-02 01:21:13 -0700558 this->advanceClocks((markingInterval / 2) + 1_ms);
Eric Newberryb49313d2017-12-24 20:22:27 -0700559
560 // first congested packet after waiting marking interval, will be marked
Klaus Schneider380668b2019-10-02 01:21:13 -0700561 transport->setSendQueueLength(66000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000562 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700563 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 4);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400564 lp::Packet pkt3(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700565 BOOST_REQUIRE_EQUAL(pkt3.count<lp::CongestionMarkField>(), 1);
566 BOOST_CHECK_EQUAL(pkt3.get<lp::CongestionMarkField>(), 1);
Klaus Schneider380668b2019-10-02 01:21:13 -0700567 markingInterval = time::nanoseconds(
568 static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
569 std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
Eric Newberryb49313d2017-12-24 20:22:27 -0700570 nextMarkTime += markingInterval;
571 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Eric Newberryb49313d2017-12-24 20:22:27 -0700572 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 2);
573 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 2);
574
575 // advance clock partway through current marking interval
Klaus Schneider380668b2019-10-02 01:21:13 -0700576 this->advanceClocks(markingInterval - 20_ms);
Eric Newberryb49313d2017-12-24 20:22:27 -0700577
578 // still congested, but within marking interval cycle
Klaus Schneider380668b2019-10-02 01:21:13 -0700579 transport->setSendQueueLength(66000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000580 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700581 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400582 lp::Packet pkt4(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700583 BOOST_CHECK_EQUAL(pkt4.count<lp::CongestionMarkField>(), 0);
584 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Eric Newberryb49313d2017-12-24 20:22:27 -0700585 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 2);
586 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 2);
587
588 // advance clocks past end of current marking interval cycle
Klaus Schneider380668b2019-10-02 01:21:13 -0700589 this->advanceClocks(21_ms);
Eric Newberryb49313d2017-12-24 20:22:27 -0700590
591 // still congested, after marking interval cycle
Klaus Schneider380668b2019-10-02 01:21:13 -0700592 transport->setSendQueueLength(66000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000593 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700594 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 6);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400595 lp::Packet pkt5(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700596 BOOST_REQUIRE_EQUAL(pkt5.count<lp::CongestionMarkField>(), 1);
597 BOOST_CHECK_EQUAL(pkt5.get<lp::CongestionMarkField>(), 1);
598 markingInterval = time::nanoseconds(
599 static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
Klaus Schneider380668b2019-10-02 01:21:13 -0700600 std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
Eric Newberryb49313d2017-12-24 20:22:27 -0700601 nextMarkTime += markingInterval;
602 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Eric Newberryb49313d2017-12-24 20:22:27 -0700603 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 3);
604 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 3);
605
Davide Pesavento14e71f02019-03-28 17:35:25 -0400606 this->advanceClocks(1_ms);
Eric Newberryb49313d2017-12-24 20:22:27 -0700607
608 // still congested, but within marking interval cycle
Klaus Schneider380668b2019-10-02 01:21:13 -0700609 transport->setSendQueueLength(66000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000610 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700611 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 7);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400612 lp::Packet pkt6(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700613 BOOST_CHECK_EQUAL(pkt6.count<lp::CongestionMarkField>(), 0);
614 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Eric Newberryb49313d2017-12-24 20:22:27 -0700615 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 3);
616 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 3);
617
618 this->advanceClocks(markingInterval);
619
620 // still congested, after marking interval cycle
Klaus Schneider380668b2019-10-02 01:21:13 -0700621 transport->setSendQueueLength(66000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000622 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700623 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 8);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400624 lp::Packet pkt7(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700625 BOOST_REQUIRE_EQUAL(pkt7.count<lp::CongestionMarkField>(), 1);
626 BOOST_CHECK_EQUAL(pkt7.get<lp::CongestionMarkField>(), 1);
627 markingInterval = time::nanoseconds(
628 static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
Klaus Schneider380668b2019-10-02 01:21:13 -0700629 std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
Eric Newberryb49313d2017-12-24 20:22:27 -0700630 nextMarkTime += markingInterval;
631 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Eric Newberryb49313d2017-12-24 20:22:27 -0700632 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 4);
633 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 4);
634
635 // no more congestion
636 transport->setSendQueueLength(30000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000637 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700638 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 9);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400639 lp::Packet pkt8(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700640 BOOST_CHECK_EQUAL(pkt8.count<lp::CongestionMarkField>(), 0);
641 BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
Eric Newberryb49313d2017-12-24 20:22:27 -0700642 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
643 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 4);
644
Davide Pesavento14e71f02019-03-28 17:35:25 -0400645 this->advanceClocks(50_ms);
Eric Newberryb49313d2017-12-24 20:22:27 -0700646
647 // send queue congested again, but can't mark packet because within one full interval of last mark
Klaus Schneider380668b2019-10-02 01:21:13 -0700648 transport->setSendQueueLength(66000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000649 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700650 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 10);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400651 lp::Packet pkt9(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700652 BOOST_CHECK_EQUAL(pkt9.count<lp::CongestionMarkField>(), 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700653 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
654 markingInterval = time::nanoseconds(
655 static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
656 std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
657 nextMarkTime = time::steady_clock::now() + markingInterval;
658 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Eric Newberryb49313d2017-12-24 20:22:27 -0700659 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
660 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 4);
661
662 // advance clock past full 100ms interval since last mark
Klaus Schneider380668b2019-10-02 01:21:13 -0700663 this->advanceClocks(markingInterval + 2_ms);
664 BOOST_CHECK_GT(time::steady_clock::now(), nextMarkTime);
Eric Newberryb49313d2017-12-24 20:22:27 -0700665
Klaus Schneider380668b2019-10-02 01:21:13 -0700666 transport->setSendQueueLength(66000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000667 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700668 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 11);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400669 lp::Packet pkt10(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700670 BOOST_REQUIRE_EQUAL(pkt10.count<lp::CongestionMarkField>(), 1);
671 BOOST_CHECK_EQUAL(pkt10.get<lp::CongestionMarkField>(), 1);
Klaus Schneider380668b2019-10-02 01:21:13 -0700672 markingInterval = time::nanoseconds(
673 static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
674 std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
675 nextMarkTime += markingInterval;
Eric Newberryb49313d2017-12-24 20:22:27 -0700676 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Eric Newberryb49313d2017-12-24 20:22:27 -0700677 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 1);
678 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 5);
679
680 // advance clock partway through 100ms marking interval
Davide Pesavento14e71f02019-03-28 17:35:25 -0400681 this->advanceClocks(50_ms);
Eric Newberryb49313d2017-12-24 20:22:27 -0700682
683 // not marked since within 100ms window before can mark again
Klaus Schneider380668b2019-10-02 01:21:13 -0700684 transport->setSendQueueLength(66000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000685 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700686 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 12);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400687 lp::Packet pkt11(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700688 BOOST_CHECK_EQUAL(pkt11.count<lp::CongestionMarkField>(), 0);
689 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Eric Newberryb49313d2017-12-24 20:22:27 -0700690 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 1);
691 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 5);
692
693 // advance clocks past m_nextMarkTime
Davide Pesavento14e71f02019-03-28 17:35:25 -0400694 this->advanceClocks(51_ms);
Eric Newberryb49313d2017-12-24 20:22:27 -0700695
696 // markable packet, queue length still above threshold
Klaus Schneider380668b2019-10-02 01:21:13 -0700697 transport->setSendQueueLength(66000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000698 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700699 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 13);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400700 lp::Packet pkt12(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700701 BOOST_REQUIRE_EQUAL(pkt12.count<lp::CongestionMarkField>(), 1);
702 BOOST_CHECK_EQUAL(pkt12.get<lp::CongestionMarkField>(), 1);
703 markingInterval = time::nanoseconds(
704 static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
Klaus Schneider380668b2019-10-02 01:21:13 -0700705 std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
Eric Newberryb49313d2017-12-24 20:22:27 -0700706 nextMarkTime += markingInterval;
707 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Eric Newberryb49313d2017-12-24 20:22:27 -0700708 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 2);
709 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 6);
710
711 // no more congestion
712 transport->setSendQueueLength(10000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000713 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700714 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 14);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400715 lp::Packet pkt13(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700716 BOOST_CHECK_EQUAL(pkt13.count<lp::CongestionMarkField>(), 0);
717 BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
Eric Newberryb49313d2017-12-24 20:22:27 -0700718 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
719 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 6);
720
721 // advance clocks past one full interval since last mark
Klaus Schneider380668b2019-10-02 01:21:13 -0700722 this->advanceClocks(102_ms);
Eric Newberryb49313d2017-12-24 20:22:27 -0700723
724 // start congestion again
Klaus Schneider380668b2019-10-02 01:21:13 -0700725 transport->setSendQueueLength(66000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000726 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700727 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 15);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400728 lp::Packet pkt14(transport->sentPackets.back().packet);
Klaus Schneider380668b2019-10-02 01:21:13 -0700729 BOOST_REQUIRE_EQUAL(pkt14.count<lp::CongestionMarkField>(), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400730 nextMarkTime = time::steady_clock::now() + 100_ms;
Eric Newberryb49313d2017-12-24 20:22:27 -0700731 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Klaus Schneider380668b2019-10-02 01:21:13 -0700732 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
733 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 6);
Eric Newberryb49313d2017-12-24 20:22:27 -0700734
735 // no more congestion, cancel marking interval
736 transport->setSendQueueLength(5000);
ashiqopu075bb7d2019-03-10 01:38:21 +0000737 face->sendInterest(*interest, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700738 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 16);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400739 lp::Packet pkt15(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700740 BOOST_CHECK_EQUAL(pkt15.count<lp::CongestionMarkField>(), 0);
741 BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
Eric Newberryb49313d2017-12-24 20:22:27 -0700742 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
Klaus Schneider380668b2019-10-02 01:21:13 -0700743 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 6);
Eric Newberryb49313d2017-12-24 20:22:27 -0700744}
745
746BOOST_AUTO_TEST_CASE(DefaultThreshold)
747{
748 GenericLinkService::Options options;
749 options.allowCongestionMarking = true;
Davide Pesavento14e71f02019-03-28 17:35:25 -0400750 options.baseCongestionMarkingInterval = 100_ms;
Eric Newberryb49313d2017-12-24 20:22:27 -0700751 initialize(options, MTU_UNLIMITED, QUEUE_UNSUPPORTED);
752 BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
753 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
754 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);
755
Junxiao Shi9d727852019-05-14 13:44:22 -0600756 auto interest = makeInterest("/12345678");
Eric Newberryb49313d2017-12-24 20:22:27 -0700757
758 // congestion threshold will be 65536 bytes, since the transport reports that it cannot measure
759 // the queue capacity
760
761 // no congestion
762 transport->setSendQueueLength(0);
ashiqopu075bb7d2019-03-10 01:38:21 +0000763 face->sendInterest(*interest, 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700764 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400765 lp::Packet pkt1(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700766 BOOST_CHECK_EQUAL(pkt1.count<lp::CongestionMarkField>(), 0);
767 BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
768 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
769 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);
770
771 // no congestion
772 transport->setSendQueueLength(65536);
ashiqopu075bb7d2019-03-10 01:38:21 +0000773 face->sendInterest(*interest, 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700774 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 2);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400775 lp::Packet pkt2(transport->sentPackets.back().packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700776 BOOST_CHECK_EQUAL(pkt2.count<lp::CongestionMarkField>(), 0);
777 BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
778 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
779 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);
780
Klaus Schneider380668b2019-10-02 01:21:13 -0700781 // first congested (not marked yet) packet
Eric Newberryb49313d2017-12-24 20:22:27 -0700782 transport->setSendQueueLength(65537);
ashiqopu075bb7d2019-03-10 01:38:21 +0000783 face->sendInterest(*interest, 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700784 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 3);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400785 lp::Packet pkt3(transport->sentPackets.back().packet);
Klaus Schneider380668b2019-10-02 01:21:13 -0700786 BOOST_REQUIRE_EQUAL(pkt3.count<lp::CongestionMarkField>(), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400787 time::steady_clock::TimePoint nextMarkTime = time::steady_clock::now() + 100_ms;
Eric Newberryb49313d2017-12-24 20:22:27 -0700788 BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
Klaus Schneider380668b2019-10-02 01:21:13 -0700789 BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
790 BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700791}
792
793BOOST_AUTO_TEST_SUITE_END() // CongestionMark
794
Eric Newberryee400b52016-11-24 14:12:48 +0000795BOOST_AUTO_TEST_SUITE(LpFields)
Eric Newberrya98bf932015-09-21 00:58:47 -0700796
Eric Newberrya98bf932015-09-21 00:58:47 -0700797BOOST_AUTO_TEST_CASE(ReceiveNextHopFaceId)
798{
Eric Newberry86d31872015-09-23 16:24:59 -0700799 // Initialize with Options that enables local fields
800 GenericLinkService::Options options;
801 options.allowLocalFields = true;
802 initialize(options);
803
Junxiao Shi9d727852019-05-14 13:44:22 -0600804 auto interest = makeInterest("/12345678");
Eric Newberry86d31872015-09-23 16:24:59 -0700805 lp::Packet packet(interest->wireEncode());
806 packet.set<lp::NextHopFaceIdField>(1000);
807
808 transport->receivePacket(packet.wireEncode());
809
810 BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400811 auto tag = receivedInterests.back().getTag<lp::NextHopFaceIdTag>();
Junxiao Shi0de23a22015-12-03 20:07:02 +0000812 BOOST_REQUIRE(tag != nullptr);
813 BOOST_CHECK_EQUAL(*tag, 1000);
Eric Newberrya98bf932015-09-21 00:58:47 -0700814}
815
816BOOST_AUTO_TEST_CASE(ReceiveNextHopFaceIdDisabled)
817{
Eric Newberry86d31872015-09-23 16:24:59 -0700818 // Initialize with Options that disables local fields
819 GenericLinkService::Options options;
820 options.allowLocalFields = false;
821 initialize(options);
822
Junxiao Shi9d727852019-05-14 13:44:22 -0600823 auto interest = makeInterest("/12345678");
Eric Newberry86d31872015-09-23 16:24:59 -0700824 lp::Packet packet(interest->wireEncode());
825 packet.set<lp::NextHopFaceIdField>(1000);
826
827 transport->receivePacket(packet.wireEncode());
828
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700829 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
Eric Newberry86d31872015-09-23 16:24:59 -0700830 BOOST_CHECK(receivedInterests.empty());
Eric Newberrya98bf932015-09-21 00:58:47 -0700831}
832
833BOOST_AUTO_TEST_CASE(ReceiveNextHopFaceIdDropData)
834{
Eric Newberry86d31872015-09-23 16:24:59 -0700835 // Initialize with Options that enables local fields
836 GenericLinkService::Options options;
837 options.allowLocalFields = true;
838 initialize(options);
839
Junxiao Shi9d727852019-05-14 13:44:22 -0600840 auto data = makeData("/12345678");
Eric Newberry86d31872015-09-23 16:24:59 -0700841 lp::Packet packet(data->wireEncode());
842 packet.set<lp::NextHopFaceIdField>(1000);
843
844 transport->receivePacket(packet.wireEncode());
845
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700846 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
Eric Newberry86d31872015-09-23 16:24:59 -0700847 BOOST_CHECK(receivedData.empty());
Eric Newberrya98bf932015-09-21 00:58:47 -0700848}
849
850BOOST_AUTO_TEST_CASE(ReceiveNextHopFaceIdDropNack)
851{
Eric Newberry86d31872015-09-23 16:24:59 -0700852 // Initialize with Options that enables local fields
853 GenericLinkService::Options options;
854 options.allowLocalFields = true;
855 initialize(options);
856
Junxiao Shi9d727852019-05-14 13:44:22 -0600857 lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, nullopt, 123),
858 lp::NackReason::NO_ROUTE);
Eric Newberry86d31872015-09-23 16:24:59 -0700859 lp::Packet packet;
860 packet.set<lp::FragmentField>(std::make_pair(
861 nack.getInterest().wireEncode().begin(), nack.getInterest().wireEncode().end()));
862 packet.set<lp::NackField>(nack.getHeader());
863 packet.set<lp::NextHopFaceIdField>(1000);
864
865 transport->receivePacket(packet.wireEncode());
866
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700867 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
Eric Newberry86d31872015-09-23 16:24:59 -0700868 BOOST_CHECK(receivedNacks.empty());
Eric Newberrya98bf932015-09-21 00:58:47 -0700869}
870
Junxiao Shi6eb02712017-05-27 22:48:02 +0000871BOOST_AUTO_TEST_CASE(ReceiveCachePolicy)
Eric Newberrya98bf932015-09-21 00:58:47 -0700872{
Junxiao Shi6eb02712017-05-27 22:48:02 +0000873 // Initialize with Options that disables local fields
Eric Newberry86d31872015-09-23 16:24:59 -0700874 GenericLinkService::Options options;
Junxiao Shi6eb02712017-05-27 22:48:02 +0000875 options.allowLocalFields = false;
Eric Newberry86d31872015-09-23 16:24:59 -0700876 initialize(options);
Junxiao Shi6eb02712017-05-27 22:48:02 +0000877 // CachePolicy is unprivileged and does not require allowLocalFields option.
Eric Newberry86d31872015-09-23 16:24:59 -0700878
Junxiao Shi9d727852019-05-14 13:44:22 -0600879 auto data = makeData("/12345678");
Eric Newberry86d31872015-09-23 16:24:59 -0700880 lp::Packet packet(data->wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000881 packet.set<lp::CachePolicyField>(lp::CachePolicy().setPolicy(lp::CachePolicyType::NO_CACHE));
Eric Newberry86d31872015-09-23 16:24:59 -0700882
883 transport->receivePacket(packet.wireEncode());
884
885 BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400886 auto tag = receivedData.back().getTag<lp::CachePolicyTag>();
Junxiao Shi0de23a22015-12-03 20:07:02 +0000887 BOOST_REQUIRE(tag != nullptr);
888 BOOST_CHECK_EQUAL(tag->get().getPolicy(), lp::CachePolicyType::NO_CACHE);
Eric Newberrya98bf932015-09-21 00:58:47 -0700889}
890
Junxiao Shi6eb02712017-05-27 22:48:02 +0000891BOOST_AUTO_TEST_CASE(ReceiveCachePolicyDropInterest)
Eric Newberrya98bf932015-09-21 00:58:47 -0700892{
Eric Newberry86d31872015-09-23 16:24:59 -0700893 // Initialize with Options that enables local fields
894 GenericLinkService::Options options;
895 options.allowLocalFields = true;
896 initialize(options);
897
Junxiao Shi9d727852019-05-14 13:44:22 -0600898 auto interest = makeInterest("/12345678");
Eric Newberry86d31872015-09-23 16:24:59 -0700899 lp::Packet packet(interest->wireEncode());
900 lp::CachePolicy policy;
901 policy.setPolicy(lp::CachePolicyType::NO_CACHE);
902 packet.set<lp::CachePolicyField>(policy);
903
904 transport->receivePacket(packet.wireEncode());
905
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700906 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
Eric Newberry86d31872015-09-23 16:24:59 -0700907 BOOST_CHECK(receivedInterests.empty());
Eric Newberrya98bf932015-09-21 00:58:47 -0700908}
909
Junxiao Shi6eb02712017-05-27 22:48:02 +0000910BOOST_AUTO_TEST_CASE(ReceiveCachePolicyDropNack)
Eric Newberrya98bf932015-09-21 00:58:47 -0700911{
Eric Newberry86d31872015-09-23 16:24:59 -0700912 // Initialize with Options that enables local fields
913 GenericLinkService::Options options;
914 options.allowLocalFields = true;
915 initialize(options);
916
Junxiao Shi9d727852019-05-14 13:44:22 -0600917 lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, nullopt, 123),
918 lp::NackReason::NO_ROUTE);
Eric Newberry86d31872015-09-23 16:24:59 -0700919 lp::Packet packet(nack.getInterest().wireEncode());
920 packet.set<lp::NackField>(nack.getHeader());
921 lp::CachePolicy policy;
922 policy.setPolicy(lp::CachePolicyType::NO_CACHE);
923 packet.set<lp::CachePolicyField>(policy);
924
925 transport->receivePacket(packet.wireEncode());
926
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700927 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
Eric Newberry86d31872015-09-23 16:24:59 -0700928 BOOST_CHECK(receivedNacks.empty());
929}
930
931BOOST_AUTO_TEST_CASE(SendIncomingFaceId)
932{
933 // Initialize with Options that enables local fields
934 GenericLinkService::Options options;
935 options.allowLocalFields = true;
936 initialize(options);
937
Junxiao Shi9d727852019-05-14 13:44:22 -0600938 auto interest = makeInterest("/12345678");
Junxiao Shi0de23a22015-12-03 20:07:02 +0000939 interest->setTag(make_shared<lp::IncomingFaceIdTag>(1000));
Eric Newberry86d31872015-09-23 16:24:59 -0700940
ashiqopu075bb7d2019-03-10 01:38:21 +0000941 face->sendInterest(*interest, 0);
Eric Newberry86d31872015-09-23 16:24:59 -0700942
943 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
944 lp::Packet sent(transport->sentPackets.back().packet);
945 BOOST_REQUIRE(sent.has<lp::IncomingFaceIdField>());
946 BOOST_CHECK_EQUAL(sent.get<lp::IncomingFaceIdField>(), 1000);
947}
948
949BOOST_AUTO_TEST_CASE(SendIncomingFaceIdDisabled)
950{
951 // Initialize with Options that disables local fields
952 GenericLinkService::Options options;
953 options.allowLocalFields = false;
954 initialize(options);
955
Junxiao Shi9d727852019-05-14 13:44:22 -0600956 auto interest = makeInterest("/12345678");
Junxiao Shi0de23a22015-12-03 20:07:02 +0000957 interest->setTag(make_shared<lp::IncomingFaceIdTag>(1000));
Eric Newberry86d31872015-09-23 16:24:59 -0700958
ashiqopu075bb7d2019-03-10 01:38:21 +0000959 face->sendInterest(*interest, 0);
Eric Newberry86d31872015-09-23 16:24:59 -0700960
961 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
962 lp::Packet sent(transport->sentPackets.back().packet);
963 BOOST_CHECK(!sent.has<lp::IncomingFaceIdField>());
964}
965
966BOOST_AUTO_TEST_CASE(ReceiveIncomingFaceIdIgnoreInterest)
967{
968 // Initialize with Options that enables local fields
969 GenericLinkService::Options options;
970 options.allowLocalFields = true;
971 initialize(options);
972
Junxiao Shi9d727852019-05-14 13:44:22 -0600973 auto interest = makeInterest("/12345678");
Eric Newberry86d31872015-09-23 16:24:59 -0700974 lp::Packet packet(interest->wireEncode());
975 packet.set<lp::IncomingFaceIdField>(1000);
976
977 transport->receivePacket(packet.wireEncode());
978
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700979 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
Eric Newberry86d31872015-09-23 16:24:59 -0700980 BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
Junxiao Shi0de23a22015-12-03 20:07:02 +0000981 BOOST_CHECK(receivedInterests.back().getTag<lp::IncomingFaceIdTag>() == nullptr);
Eric Newberry86d31872015-09-23 16:24:59 -0700982}
983
984BOOST_AUTO_TEST_CASE(ReceiveIncomingFaceIdIgnoreData)
985{
986 // Initialize with Options that enables local fields
987 GenericLinkService::Options options;
988 options.allowLocalFields = true;
989 initialize(options);
990
Junxiao Shi9d727852019-05-14 13:44:22 -0600991 auto data = makeData("/z1megUh9Bj");
Eric Newberry86d31872015-09-23 16:24:59 -0700992 lp::Packet packet(data->wireEncode());
993 packet.set<lp::IncomingFaceIdField>(1000);
994
995 transport->receivePacket(packet.wireEncode());
996
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700997 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
Eric Newberry86d31872015-09-23 16:24:59 -0700998 BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
Junxiao Shi0de23a22015-12-03 20:07:02 +0000999 BOOST_CHECK(receivedData.back().getTag<lp::IncomingFaceIdTag>() == nullptr);
Eric Newberry86d31872015-09-23 16:24:59 -07001000}
1001
1002BOOST_AUTO_TEST_CASE(ReceiveIncomingFaceIdIgnoreNack)
1003{
1004 // Initialize with Options that enables local fields
1005 GenericLinkService::Options options;
1006 options.allowLocalFields = true;
1007 initialize(options);
1008
Junxiao Shi9d727852019-05-14 13:44:22 -06001009 lp::Nack nack = makeNack(*makeInterest("/TPAhdiHz", false, nullopt, 278),
1010 lp::NackReason::CONGESTION);
Eric Newberry86d31872015-09-23 16:24:59 -07001011 lp::Packet packet(nack.getInterest().wireEncode());
1012 packet.set<lp::NackField>(nack.getHeader());
1013 packet.set<lp::IncomingFaceIdField>(1000);
1014
1015 transport->receivePacket(packet.wireEncode());
1016
Eric Newberry4c3e6b82015-11-10 16:48:42 -07001017 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
Eric Newberry86d31872015-09-23 16:24:59 -07001018 BOOST_REQUIRE_EQUAL(receivedNacks.size(), 1);
Junxiao Shi0de23a22015-12-03 20:07:02 +00001019 BOOST_CHECK(receivedNacks.back().getTag<lp::IncomingFaceIdTag>() == nullptr);
Eric Newberrya98bf932015-09-21 00:58:47 -07001020}
1021
Eric Newberryee400b52016-11-24 14:12:48 +00001022BOOST_AUTO_TEST_CASE(SendCongestionMarkInterest)
1023{
Junxiao Shi9d727852019-05-14 13:44:22 -06001024 auto interest = makeInterest("/12345678");
Eric Newberryee400b52016-11-24 14:12:48 +00001025 interest->setTag(make_shared<lp::CongestionMarkTag>(1));
1026
ashiqopu075bb7d2019-03-10 01:38:21 +00001027 face->sendInterest(*interest, 0);
Eric Newberryee400b52016-11-24 14:12:48 +00001028
1029 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
1030 lp::Packet sent(transport->sentPackets.back().packet);
1031 BOOST_REQUIRE(sent.has<lp::CongestionMarkField>());
1032 BOOST_CHECK_EQUAL(sent.get<lp::CongestionMarkField>(), 1);
1033}
1034
1035BOOST_AUTO_TEST_CASE(SendCongestionMarkData)
1036{
Junxiao Shi9d727852019-05-14 13:44:22 -06001037 auto data = makeData("/12345678");
Eric Newberryee400b52016-11-24 14:12:48 +00001038 data->setTag(make_shared<lp::CongestionMarkTag>(0));
1039
ashiqopu075bb7d2019-03-10 01:38:21 +00001040 face->sendData(*data, 0);
Eric Newberryee400b52016-11-24 14:12:48 +00001041
1042 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
1043 lp::Packet sent(transport->sentPackets.back().packet);
1044 BOOST_REQUIRE(sent.has<lp::CongestionMarkField>());
1045 BOOST_CHECK_EQUAL(sent.get<lp::CongestionMarkField>(), 0);
1046}
1047
1048BOOST_AUTO_TEST_CASE(SendCongestionMarkNack)
1049{
Junxiao Shi9d727852019-05-14 13:44:22 -06001050 lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, nullopt, 123),
1051 lp::NackReason::NO_ROUTE);
Eric Newberryee400b52016-11-24 14:12:48 +00001052 nack.setTag(make_shared<lp::CongestionMarkTag>(std::numeric_limits<uint64_t>::max()));
1053
ashiqopu075bb7d2019-03-10 01:38:21 +00001054 face->sendNack(nack, 0);
Eric Newberryee400b52016-11-24 14:12:48 +00001055
1056 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
1057 lp::Packet sent(transport->sentPackets.back().packet);
1058 BOOST_REQUIRE(sent.has<lp::CongestionMarkField>());
1059 BOOST_CHECK_EQUAL(sent.get<lp::CongestionMarkField>(), std::numeric_limits<uint64_t>::max());
1060}
1061
1062BOOST_AUTO_TEST_CASE(ReceiveCongestionMarkInterest)
1063{
Junxiao Shi9d727852019-05-14 13:44:22 -06001064 auto interest = makeInterest("/12345678");
Eric Newberryee400b52016-11-24 14:12:48 +00001065 lp::Packet packet(interest->wireEncode());
1066 packet.set<lp::CongestionMarkField>(1);
1067
1068 transport->receivePacket(packet.wireEncode());
1069
1070 BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -04001071 auto tag = receivedInterests.back().getTag<lp::CongestionMarkTag>();
Eric Newberryee400b52016-11-24 14:12:48 +00001072 BOOST_REQUIRE(tag != nullptr);
1073 BOOST_CHECK_EQUAL(*tag, 1);
1074}
1075
1076BOOST_AUTO_TEST_CASE(ReceiveCongestionMarkData)
1077{
Junxiao Shi9d727852019-05-14 13:44:22 -06001078 auto data = makeData("/12345678");
Eric Newberryee400b52016-11-24 14:12:48 +00001079 lp::Packet packet(data->wireEncode());
1080 packet.set<lp::CongestionMarkField>(1);
1081
1082 transport->receivePacket(packet.wireEncode());
1083
1084 BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -04001085 auto tag = receivedData.back().getTag<lp::CongestionMarkTag>();
Eric Newberryee400b52016-11-24 14:12:48 +00001086 BOOST_REQUIRE(tag != nullptr);
1087 BOOST_CHECK_EQUAL(*tag, 1);
1088}
1089
1090BOOST_AUTO_TEST_CASE(ReceiveCongestionMarkNack)
1091{
Junxiao Shi9d727852019-05-14 13:44:22 -06001092 lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, nullopt, 123),
1093 lp::NackReason::NO_ROUTE);
Eric Newberryee400b52016-11-24 14:12:48 +00001094 lp::Packet packet;
1095 packet.set<lp::FragmentField>(std::make_pair(
1096 nack.getInterest().wireEncode().begin(), nack.getInterest().wireEncode().end()));
1097 packet.set<lp::NackField>(nack.getHeader());
1098 packet.set<lp::CongestionMarkField>(1);
1099
1100 transport->receivePacket(packet.wireEncode());
1101
1102 BOOST_REQUIRE_EQUAL(receivedNacks.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -04001103 auto tag = receivedNacks.back().getTag<lp::CongestionMarkTag>();
Eric Newberryee400b52016-11-24 14:12:48 +00001104 BOOST_REQUIRE(tag != nullptr);
1105 BOOST_CHECK_EQUAL(*tag, 1);
1106}
1107
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001108BOOST_AUTO_TEST_CASE(SendNonDiscovery)
1109{
1110 GenericLinkService::Options options;
1111 options.allowSelfLearning = true;
1112 initialize(options);
1113
Junxiao Shi9d727852019-05-14 13:44:22 -06001114 auto interest = makeInterest("/12345678");
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001115 interest->setTag(make_shared<lp::NonDiscoveryTag>(lp::EmptyValue{}));
1116
ashiqopu075bb7d2019-03-10 01:38:21 +00001117 face->sendInterest(*interest, 0);
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001118
1119 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
1120 lp::Packet sent(transport->sentPackets.back().packet);
1121 BOOST_CHECK(sent.has<lp::NonDiscoveryField>());
1122}
1123
1124BOOST_AUTO_TEST_CASE(SendNonDiscoveryDisabled)
1125{
1126 GenericLinkService::Options options;
1127 options.allowSelfLearning = false;
1128 initialize(options);
1129
Junxiao Shi9d727852019-05-14 13:44:22 -06001130 auto interest = makeInterest("/12345678");
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001131 interest->setTag(make_shared<lp::NonDiscoveryTag>(lp::EmptyValue{}));
1132
ashiqopu075bb7d2019-03-10 01:38:21 +00001133 face->sendInterest(*interest, 0);
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001134
1135 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
1136 lp::Packet sent(transport->sentPackets.back().packet);
1137 BOOST_CHECK(!sent.has<lp::NonDiscoveryField>());
1138}
1139
1140BOOST_AUTO_TEST_CASE(ReceiveNonDiscovery)
1141{
1142 GenericLinkService::Options options;
1143 options.allowSelfLearning = true;
1144 initialize(options);
1145
Junxiao Shi9d727852019-05-14 13:44:22 -06001146 auto interest = makeInterest("/12345678");
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001147 lp::Packet packet(interest->wireEncode());
1148 packet.set<lp::NonDiscoveryField>(lp::EmptyValue{});
1149
1150 transport->receivePacket(packet.wireEncode());
1151
1152 BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -04001153 auto tag = receivedInterests.back().getTag<lp::NonDiscoveryTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001154 BOOST_CHECK(tag != nullptr);
1155}
1156
1157BOOST_AUTO_TEST_CASE(ReceiveNonDiscoveryDisabled)
1158{
1159 GenericLinkService::Options options;
1160 options.allowSelfLearning = false;
1161 initialize(options);
1162
Junxiao Shi9d727852019-05-14 13:44:22 -06001163 auto interest = makeInterest("/12345678");
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001164 lp::Packet packet(interest->wireEncode());
1165 packet.set<lp::NonDiscoveryField>(lp::EmptyValue{});
1166
1167 transport->receivePacket(packet.wireEncode());
1168
1169 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
1170 BOOST_CHECK_EQUAL(receivedInterests.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -04001171 auto tag = receivedInterests.back().getTag<lp::NonDiscoveryTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001172 BOOST_CHECK(tag == nullptr);
1173}
1174
1175BOOST_AUTO_TEST_CASE(ReceiveNonDiscoveryDropData)
1176{
1177 GenericLinkService::Options options;
1178 options.allowSelfLearning = true;
1179 initialize(options);
1180
Junxiao Shi9d727852019-05-14 13:44:22 -06001181 auto data = makeData("/12345678");
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001182 lp::Packet packet(data->wireEncode());
1183 packet.set<lp::NonDiscoveryField>(lp::EmptyValue{});
1184
1185 transport->receivePacket(packet.wireEncode());
1186
1187 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
1188 BOOST_CHECK(receivedData.empty());
1189}
1190
1191BOOST_AUTO_TEST_CASE(ReceiveNonDiscoveryDropNack)
1192{
1193 GenericLinkService::Options options;
1194 options.allowSelfLearning = true;
1195 initialize(options);
1196
Junxiao Shi9d727852019-05-14 13:44:22 -06001197 lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, nullopt, 123),
1198 lp::NackReason::NO_ROUTE);
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001199 lp::Packet packet;
1200 packet.set<lp::FragmentField>(std::make_pair(
1201 nack.getInterest().wireEncode().begin(), nack.getInterest().wireEncode().end()));
1202 packet.set<lp::NackField>(nack.getHeader());
1203 packet.set<lp::NonDiscoveryField>(lp::EmptyValue{});
1204
1205 transport->receivePacket(packet.wireEncode());
1206
1207 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
1208 BOOST_CHECK(receivedNacks.empty());
1209}
1210
1211BOOST_AUTO_TEST_CASE(SendPrefixAnnouncement)
1212{
1213 GenericLinkService::Options options;
1214 options.allowSelfLearning = true;
1215 initialize(options);
1216
Junxiao Shi9d727852019-05-14 13:44:22 -06001217 auto data = makeData("/12345678");
Teng Liangbce3cb52018-09-05 20:08:27 -07001218 auto pah = makePrefixAnnHeader("/local/ndn/prefix");
1219 data->setTag(make_shared<lp::PrefixAnnouncementTag>(pah));
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001220
ashiqopu075bb7d2019-03-10 01:38:21 +00001221 face->sendData(*data, 0);
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001222
1223 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
1224 lp::Packet sent(transport->sentPackets.back().packet);
1225 BOOST_CHECK(sent.has<lp::PrefixAnnouncementField>());
1226}
1227
1228BOOST_AUTO_TEST_CASE(SendPrefixAnnouncementDisabled)
1229{
1230 GenericLinkService::Options options;
1231 options.allowSelfLearning = false;
1232 initialize(options);
1233
Junxiao Shi9d727852019-05-14 13:44:22 -06001234 auto data = makeData("/12345678");
Teng Liangbce3cb52018-09-05 20:08:27 -07001235 auto pah = makePrefixAnnHeader("/local/ndn/prefix");
1236 data->setTag(make_shared<lp::PrefixAnnouncementTag>(pah));
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001237
ashiqopu075bb7d2019-03-10 01:38:21 +00001238 face->sendData(*data, 0);
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001239
1240 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
1241 lp::Packet sent(transport->sentPackets.back().packet);
1242 BOOST_CHECK(!sent.has<lp::PrefixAnnouncementField>());
1243}
1244
1245BOOST_AUTO_TEST_CASE(ReceivePrefixAnnouncement)
1246{
1247 GenericLinkService::Options options;
1248 options.allowSelfLearning = true;
1249 initialize(options);
1250
Junxiao Shi9d727852019-05-14 13:44:22 -06001251 auto data = makeData("/12345678");
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001252 lp::Packet packet(data->wireEncode());
Teng Liangbce3cb52018-09-05 20:08:27 -07001253 auto pah = makePrefixAnnHeader("/local/ndn/prefix");
1254 packet.set<lp::PrefixAnnouncementField>(pah);
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001255
1256 transport->receivePacket(packet.wireEncode());
1257
1258 BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -04001259 auto tag = receivedData.back().getTag<lp::PrefixAnnouncementTag>();
Teng Liangbce3cb52018-09-05 20:08:27 -07001260 BOOST_CHECK_EQUAL(tag->get().getPrefixAnn()->getAnnouncedName(), "/local/ndn/prefix");
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001261}
1262
1263BOOST_AUTO_TEST_CASE(ReceivePrefixAnnouncementDisabled)
1264{
1265 GenericLinkService::Options options;
1266 options.allowSelfLearning = false;
1267 initialize(options);
1268
Junxiao Shi9d727852019-05-14 13:44:22 -06001269 auto data = makeData("/12345678");
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001270 lp::Packet packet(data->wireEncode());
Teng Liangbce3cb52018-09-05 20:08:27 -07001271 auto pah = makePrefixAnnHeader("/local/ndn/prefix");
1272 packet.set<lp::PrefixAnnouncementField>(pah);
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001273
1274 transport->receivePacket(packet.wireEncode());
1275
1276 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
1277 BOOST_CHECK_EQUAL(receivedData.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -04001278 auto tag = receivedData.back().getTag<lp::PrefixAnnouncementTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001279 BOOST_CHECK(tag == nullptr);
1280}
1281
1282BOOST_AUTO_TEST_CASE(ReceivePrefixAnnouncementDropInterest)
1283{
1284 GenericLinkService::Options options;
1285 options.allowSelfLearning = true;
1286 initialize(options);
1287
Junxiao Shi9d727852019-05-14 13:44:22 -06001288 auto interest = makeInterest("/12345678");
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001289 lp::Packet packet(interest->wireEncode());
Teng Liangbce3cb52018-09-05 20:08:27 -07001290 auto pah = makePrefixAnnHeader("/local/ndn/prefix");
1291 packet.set<lp::PrefixAnnouncementField>(pah);
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001292
1293 transport->receivePacket(packet.wireEncode());
1294
1295 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
1296 BOOST_CHECK(receivedInterests.empty());
1297}
1298
1299BOOST_AUTO_TEST_CASE(ReceivePrefixAnnouncementDropNack)
1300{
1301 GenericLinkService::Options options;
1302 options.allowSelfLearning = true;
1303 initialize(options);
1304
Junxiao Shi9d727852019-05-14 13:44:22 -06001305 lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, nullopt, 123),
1306 lp::NackReason::NO_ROUTE);
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001307 lp::Packet packet;
1308 packet.set<lp::FragmentField>(std::make_pair(
1309 nack.getInterest().wireEncode().begin(), nack.getInterest().wireEncode().end()));
1310 packet.set<lp::NackField>(nack.getHeader());
Teng Liangbce3cb52018-09-05 20:08:27 -07001311 auto pah = makePrefixAnnHeader("/local/ndn/prefix");
1312 packet.set<lp::PrefixAnnouncementField>(pah);
Teng Liangfdcbb4d2018-01-27 16:01:35 -07001313
1314 transport->receivePacket(packet.wireEncode());
1315
1316 BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
1317 BOOST_CHECK(receivedNacks.empty());
1318}
1319
Eric Newberryee400b52016-11-24 14:12:48 +00001320BOOST_AUTO_TEST_SUITE_END() // LpFields
Eric Newberrya98bf932015-09-21 00:58:47 -07001321
Eric Newberrya1939ba2015-10-09 12:35:03 -07001322BOOST_AUTO_TEST_SUITE(Malformed) // receive malformed packets
1323
1324BOOST_AUTO_TEST_CASE(WrongTlvType)
1325{
1326 // Initialize with Options that disables all services
1327 GenericLinkService::Options options;
1328 options.allowLocalFields = false;
1329 initialize(options);
1330
Davide Pesaventob3a23ca2019-05-04 20:40:21 -04001331 auto packet = ndn::encoding::makeEmptyBlock(tlv::Name);
1332 transport->receivePacket(packet);
Eric Newberrya1939ba2015-10-09 12:35:03 -07001333
Eric Newberry4c3e6b82015-11-10 16:48:42 -07001334 BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 1);
Eric Newberrya1939ba2015-10-09 12:35:03 -07001335 BOOST_CHECK_EQUAL(receivedInterests.size(), 0);
1336 BOOST_CHECK_EQUAL(receivedData.size(), 0);
1337 BOOST_CHECK_EQUAL(receivedNacks.size(), 0);
1338}
1339
1340BOOST_AUTO_TEST_CASE(Unparsable)
1341{
1342 // Initialize with Options that disables all services
1343 GenericLinkService::Options options;
1344 options.allowLocalFields = false;
1345 initialize(options);
1346
Davide Pesaventob3a23ca2019-05-04 20:40:21 -04001347 auto packet = ndn::encoding::makeStringBlock(lp::tlv::LpPacket, "x");
Eric Newberrya1939ba2015-10-09 12:35:03 -07001348 BOOST_CHECK_THROW(packet.parse(), tlv::Error);
Davide Pesaventob3a23ca2019-05-04 20:40:21 -04001349 transport->receivePacket(packet);
Eric Newberrya1939ba2015-10-09 12:35:03 -07001350
Eric Newberry4c3e6b82015-11-10 16:48:42 -07001351 BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 1);
Eric Newberrya1939ba2015-10-09 12:35:03 -07001352 BOOST_CHECK_EQUAL(receivedInterests.size(), 0);
1353 BOOST_CHECK_EQUAL(receivedData.size(), 0);
1354 BOOST_CHECK_EQUAL(receivedNacks.size(), 0);
1355}
1356
1357BOOST_AUTO_TEST_SUITE_END() // Malformed
1358
Eric Newberry86d31872015-09-23 16:24:59 -07001359BOOST_AUTO_TEST_SUITE_END() // TestGenericLinkService
1360BOOST_AUTO_TEST_SUITE_END() // Face
Eric Newberrya98bf932015-09-21 00:58:47 -07001361
1362} // namespace tests
1363} // namespace face
1364} // namespace nfd