blob: d00df79bdd3530d46955e334cb39df0cf97e39b0 [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/*
Eric Newberryb49313d2017-12-24 20:22:27 -07003 * Copyright (c) 2014-2018, 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 "generic-link-service.hpp"
Eric Newberryb49313d2017-12-24 20:22:27 -070027
Junxiao Shicbc8e942016-09-06 03:17:45 +000028#include <ndn-cxx/lp/tags.hpp>
Eric Newberrya98bf932015-09-21 00:58:47 -070029
Eric Newberryb49313d2017-12-24 20:22:27 -070030#include <cmath>
31
Eric Newberrya98bf932015-09-21 00:58:47 -070032namespace nfd {
33namespace face {
34
Davide Pesaventoa3148082018-04-12 18:21:54 -040035NFD_LOG_INIT(GenericLinkService);
Eric Newberrya98bf932015-09-21 00:58:47 -070036
Eric Newberryb49313d2017-12-24 20:22:27 -070037constexpr uint32_t DEFAULT_CONGESTION_THRESHOLD_DIVISOR = 2;
38
Eric Newberry86d31872015-09-23 16:24:59 -070039GenericLinkService::GenericLinkService(const GenericLinkService::Options& options)
Eric Newberry73bcad32017-04-25 17:57:35 -070040 : m_options(options)
Eric Newberry4c3e6b82015-11-10 16:48:42 -070041 , m_fragmenter(m_options.fragmenterOptions, this)
42 , m_reassembler(m_options.reassemblerOptions, this)
Eric Newberry185ab292017-03-28 06:45:39 +000043 , m_reliability(m_options.reliabilityOptions, this)
Eric Newberry4c3e6b82015-11-10 16:48:42 -070044 , m_lastSeqNo(-2)
Eric Newberryb49313d2017-12-24 20:22:27 -070045 , m_nextMarkTime(time::steady_clock::TimePoint::max())
46 , m_lastMarkTime(time::steady_clock::TimePoint::min())
47 , m_nMarkedSinceInMarkingState(0)
Eric Newberry86d31872015-09-23 16:24:59 -070048{
Davide Pesaventoe4b22382018-06-10 14:37:24 -040049 m_reassembler.beforeTimeout.connect([this] (auto...) { ++this->nReassemblyTimeouts; });
50 m_reliability.onDroppedInterest.connect([this] (const auto& i) { this->notifyDroppedInterest(i); });
Eric Newberry73bcad32017-04-25 17:57:35 -070051 nReassembling.observe(&m_reassembler);
Eric Newberry86d31872015-09-23 16:24:59 -070052}
53
Eric Newberrya98bf932015-09-21 00:58:47 -070054void
Eric Newberry185ab292017-03-28 06:45:39 +000055GenericLinkService::setOptions(const GenericLinkService::Options& options)
56{
57 m_options = options;
58 m_fragmenter.setOptions(m_options.fragmenterOptions);
59 m_reassembler.setOptions(m_options.reassemblerOptions);
60 m_reliability.setOptions(m_options.reliabilityOptions);
61}
62
63void
64GenericLinkService::requestIdlePacket()
65{
66 // No need to request Acks to attach to this packet from LpReliability, as they are already
67 // attached in sendLpPacket
68 this->sendLpPacket({});
69}
70
71void
72GenericLinkService::sendLpPacket(lp::Packet&& pkt)
73{
74 const ssize_t mtu = this->getTransport()->getMtu();
Eric Newberryb49313d2017-12-24 20:22:27 -070075
Eric Newberry185ab292017-03-28 06:45:39 +000076 if (m_options.reliabilityOptions.isEnabled) {
77 m_reliability.piggyback(pkt, mtu);
78 }
79
Eric Newberryb49313d2017-12-24 20:22:27 -070080 if (m_options.allowCongestionMarking) {
81 checkCongestionLevel(pkt);
82 }
83
Eric Newberry185ab292017-03-28 06:45:39 +000084 Transport::Packet tp(pkt.wireEncode());
85 if (mtu != MTU_UNLIMITED && tp.packet.size() > static_cast<size_t>(mtu)) {
86 ++this->nOutOverMtu;
87 NFD_LOG_FACE_WARN("attempted to send packet over MTU limit");
88 return;
89 }
90 this->sendPacket(std::move(tp));
91}
92
93void
Eric Newberrya98bf932015-09-21 00:58:47 -070094GenericLinkService::doSendInterest(const Interest& interest)
95{
96 lp::Packet lpPacket(interest.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +000097
Eric Newberryee400b52016-11-24 14:12:48 +000098 encodeLpFields(interest, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -070099
Eric Newberry41aba102017-11-01 16:42:13 -0700100 this->sendNetPacket(std::move(lpPacket), true);
Eric Newberrya98bf932015-09-21 00:58:47 -0700101}
102
103void
104GenericLinkService::doSendData(const Data& data)
105{
106 lp::Packet lpPacket(data.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000107
Eric Newberryee400b52016-11-24 14:12:48 +0000108 encodeLpFields(data, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700109
Eric Newberry41aba102017-11-01 16:42:13 -0700110 this->sendNetPacket(std::move(lpPacket), false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700111}
112
113void
114GenericLinkService::doSendNack(const lp::Nack& nack)
115{
116 lp::Packet lpPacket(nack.getInterest().wireEncode());
117 lpPacket.add<lp::NackField>(nack.getHeader());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000118
Eric Newberryee400b52016-11-24 14:12:48 +0000119 encodeLpFields(nack, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700120
Eric Newberry41aba102017-11-01 16:42:13 -0700121 this->sendNetPacket(std::move(lpPacket), false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700122}
123
Junxiao Shi0de23a22015-12-03 20:07:02 +0000124void
Eric Newberry41aba102017-11-01 16:42:13 -0700125GenericLinkService::encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket)
Eric Newberry86d31872015-09-23 16:24:59 -0700126{
Eric Newberryee400b52016-11-24 14:12:48 +0000127 if (m_options.allowLocalFields) {
128 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = netPkt.getTag<lp::IncomingFaceIdTag>();
129 if (incomingFaceIdTag != nullptr) {
130 lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
131 }
132 }
133
134 shared_ptr<lp::CongestionMarkTag> congestionMarkTag = netPkt.getTag<lp::CongestionMarkTag>();
135 if (congestionMarkTag != nullptr) {
136 lpPacket.add<lp::CongestionMarkField>(*congestionMarkTag);
Eric Newberry86d31872015-09-23 16:24:59 -0700137 }
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700138
139 if (m_options.allowSelfLearning) {
140 shared_ptr<lp::NonDiscoveryTag> nonDiscoveryTag = netPkt.getTag<lp::NonDiscoveryTag>();
141 if (nonDiscoveryTag != nullptr) {
142 lpPacket.add<lp::NonDiscoveryField>(*nonDiscoveryTag);
143 }
144
145 shared_ptr<lp::PrefixAnnouncementTag> prefixAnnouncementTag = netPkt.getTag<lp::PrefixAnnouncementTag>();
146 if (prefixAnnouncementTag != nullptr) {
147 lpPacket.add<lp::PrefixAnnouncementField>(*prefixAnnouncementTag);
148 }
149 }
Spyridon Mastorakis1429fc12016-12-06 15:20:19 -0800150
151 shared_ptr<lp::HopCountTag> hopCountTag = netPkt.getTag<lp::HopCountTag>();
152 if (hopCountTag != nullptr) {
153 lpPacket.add<lp::HopCountTagField>(*hopCountTag);
154 }
155 else {
156 lpPacket.add<lp::HopCountTagField>(0);
157 }
Eric Newberry86d31872015-09-23 16:24:59 -0700158}
159
Eric Newberrya98bf932015-09-21 00:58:47 -0700160void
Eric Newberry41aba102017-11-01 16:42:13 -0700161GenericLinkService::sendNetPacket(lp::Packet&& pkt, bool isInterest)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700162{
163 std::vector<lp::Packet> frags;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000164 ssize_t mtu = this->getTransport()->getMtu();
165
166 // Make space for feature fields in fragments
167 if (m_options.reliabilityOptions.isEnabled && mtu != MTU_UNLIMITED) {
168 mtu -= LpReliability::RESERVED_HEADER_SPACE;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000169 }
170
Eric Newberryb49313d2017-12-24 20:22:27 -0700171 if (m_options.allowCongestionMarking && mtu != MTU_UNLIMITED) {
172 mtu -= CONGESTION_MARK_SIZE;
173 }
174
175 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
176
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700177 if (m_options.allowFragmentation && mtu != MTU_UNLIMITED) {
178 bool isOk = false;
179 std::tie(isOk, frags) = m_fragmenter.fragmentPacket(pkt, mtu);
180 if (!isOk) {
181 // fragmentation failed (warning is logged by LpFragmenter)
Junxiao Shi0de23a22015-12-03 20:07:02 +0000182 ++this->nFragmentationErrors;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700183 return;
184 }
185 }
186 else {
Eric Newberry41aba102017-11-01 16:42:13 -0700187 if (m_options.reliabilityOptions.isEnabled) {
188 frags.push_back(pkt);
189 }
190 else {
191 frags.push_back(std::move(pkt));
192 }
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700193 }
194
Eric Newberry185ab292017-03-28 06:45:39 +0000195 if (frags.size() == 1) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700196 // even if indexed fragmentation is enabled, the fragmenter should not
197 // fragment the packet if it can fit in MTU
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700198 BOOST_ASSERT(!frags.front().has<lp::FragIndexField>());
199 BOOST_ASSERT(!frags.front().has<lp::FragCountField>());
200 }
201
Eric Newberry7b0071e2017-07-03 17:33:31 +0000202 // Only assign sequences to fragments if packet contains more than 1 fragment
203 if (frags.size() > 1) {
Eric Newberry185ab292017-03-28 06:45:39 +0000204 // Assign sequences to all fragments
205 this->assignSequences(frags);
206 }
207
208 if (m_options.reliabilityOptions.isEnabled && frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -0700209 m_reliability.handleOutgoing(frags, std::move(pkt), isInterest);
Eric Newberry185ab292017-03-28 06:45:39 +0000210 }
211
212 for (lp::Packet& frag : frags) {
213 this->sendLpPacket(std::move(frag));
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700214 }
215}
216
217void
218GenericLinkService::assignSequence(lp::Packet& pkt)
219{
220 pkt.set<lp::SequenceField>(++m_lastSeqNo);
221}
222
223void
224GenericLinkService::assignSequences(std::vector<lp::Packet>& pkts)
225{
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400226 std::for_each(pkts.begin(), pkts.end(), [this] (auto& pkt) { this->assignSequence(pkt); });
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700227}
228
229void
Eric Newberryb49313d2017-12-24 20:22:27 -0700230GenericLinkService::checkCongestionLevel(lp::Packet& pkt)
231{
232 ssize_t sendQueueLength = getTransport()->getSendQueueLength();
233 // This operation requires that the transport supports retrieving current send queue length
234 if (sendQueueLength < 0) {
235 return;
236 }
237
238 // To avoid overflowing the queue, set the congestion threshold to at least half of the send
239 // queue capacity.
240 size_t congestionThreshold = m_options.defaultCongestionThreshold;
241 if (getTransport()->getSendQueueCapacity() >= 0) {
242 congestionThreshold = std::min(congestionThreshold,
243 static_cast<size_t>(getTransport()->getSendQueueCapacity()) /
244 DEFAULT_CONGESTION_THRESHOLD_DIVISOR);
245 }
246
247 if (sendQueueLength > 0) {
248 NFD_LOG_FACE_TRACE("txqlen=" << sendQueueLength << " threshold=" << congestionThreshold <<
249 " capacity=" << getTransport()->getSendQueueCapacity());
250 }
251
252 if (static_cast<size_t>(sendQueueLength) > congestionThreshold) { // Send queue is congested
253 const auto now = time::steady_clock::now();
254 if (now >= m_nextMarkTime || now >= m_lastMarkTime + m_options.baseCongestionMarkingInterval) {
255 // Mark at most one initial packet per baseCongestionMarkingInterval
256 if (m_nMarkedSinceInMarkingState == 0) {
257 m_nextMarkTime = now;
258 }
259
260 // Time to mark packet
261 pkt.set<lp::CongestionMarkField>(1);
262 ++nCongestionMarked;
263 NFD_LOG_FACE_DEBUG("LpPacket was marked as congested");
264
265 ++m_nMarkedSinceInMarkingState;
266 // Decrease the marking interval by the inverse of the square root of the number of packets
267 // marked in this incident of congestion
268 m_nextMarkTime += time::nanoseconds(static_cast<time::nanoseconds::rep>(
269 m_options.baseCongestionMarkingInterval.count() /
270 std::sqrt(m_nMarkedSinceInMarkingState)));
271 m_lastMarkTime = now;
272 }
273 }
274 else if (m_nextMarkTime != time::steady_clock::TimePoint::max()) {
275 // Congestion incident has ended, so reset
276 NFD_LOG_FACE_DEBUG("Send queue length dropped below congestion threshold");
277 m_nextMarkTime = time::steady_clock::TimePoint::max();
278 m_nMarkedSinceInMarkingState = 0;
279 }
280}
281
282void
Eric Newberrya98bf932015-09-21 00:58:47 -0700283GenericLinkService::doReceivePacket(Transport::Packet&& packet)
284{
Eric Newberry86d31872015-09-23 16:24:59 -0700285 try {
Eric Newberrya1939ba2015-10-09 12:35:03 -0700286 lp::Packet pkt(packet.packet);
287
Eric Newberry185ab292017-03-28 06:45:39 +0000288 if (m_options.reliabilityOptions.isEnabled) {
289 m_reliability.processIncomingPacket(pkt);
290 }
291
Eric Newberrya1939ba2015-10-09 12:35:03 -0700292 if (!pkt.has<lp::FragmentField>()) {
293 NFD_LOG_FACE_TRACE("received IDLE packet: DROP");
294 return;
295 }
296
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700297 if ((pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) &&
298 !m_options.allowReassembly) {
299 NFD_LOG_FACE_WARN("received fragment, but reassembly disabled: DROP");
Eric Newberrya1939ba2015-10-09 12:35:03 -0700300 return;
301 }
302
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700303 bool isReassembled = false;
304 Block netPkt;
305 lp::Packet firstPkt;
306 std::tie(isReassembled, netPkt, firstPkt) = m_reassembler.receiveFragment(packet.remoteEndpoint,
307 pkt);
308 if (isReassembled) {
309 this->decodeNetPacket(netPkt, firstPkt);
310 }
311 }
312 catch (const tlv::Error& e) {
313 ++this->nInLpInvalid;
314 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
315 }
316}
Eric Newberry86d31872015-09-23 16:24:59 -0700317
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700318void
319GenericLinkService::decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt)
320{
321 try {
Eric Newberry86d31872015-09-23 16:24:59 -0700322 switch (netPkt.type()) {
323 case tlv::Interest:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700324 if (firstPkt.has<lp::NackField>()) {
325 this->decodeNack(netPkt, firstPkt);
Eric Newberry86d31872015-09-23 16:24:59 -0700326 }
327 else {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700328 this->decodeInterest(netPkt, firstPkt);
Eric Newberry86d31872015-09-23 16:24:59 -0700329 }
330 break;
331 case tlv::Data:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700332 this->decodeData(netPkt, firstPkt);
Eric Newberry86d31872015-09-23 16:24:59 -0700333 break;
334 default:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700335 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700336 NFD_LOG_FACE_WARN("unrecognized network-layer packet TLV-TYPE " << netPkt.type() << ": DROP");
337 return;
Eric Newberrya98bf932015-09-21 00:58:47 -0700338 }
339 }
Eric Newberry86d31872015-09-23 16:24:59 -0700340 catch (const tlv::Error& e) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700341 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700342 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
343 }
344}
345
Eric Newberry86d31872015-09-23 16:24:59 -0700346void
347GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt)
348{
349 BOOST_ASSERT(netPkt.type() == tlv::Interest);
350 BOOST_ASSERT(!firstPkt.has<lp::NackField>());
351
352 // forwarding expects Interest to be created with make_shared
353 auto interest = make_shared<Interest>(netPkt);
354
Spyridon Mastorakis1429fc12016-12-06 15:20:19 -0800355 // Increment HopCount
356 if (firstPkt.has<lp::HopCountTagField>()) {
357 interest->setTag(make_shared<lp::HopCountTag>(firstPkt.get<lp::HopCountTagField>() + 1));
358 }
359
Eric Newberry86d31872015-09-23 16:24:59 -0700360 if (firstPkt.has<lp::NextHopFaceIdField>()) {
361 if (m_options.allowLocalFields) {
Junxiao Shi0de23a22015-12-03 20:07:02 +0000362 interest->setTag(make_shared<lp::NextHopFaceIdTag>(firstPkt.get<lp::NextHopFaceIdField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700363 }
364 else {
365 NFD_LOG_FACE_WARN("received NextHopFaceId, but local fields disabled: DROP");
366 return;
367 }
368 }
369
370 if (firstPkt.has<lp::CachePolicyField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700371 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700372 NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
373 return;
374 }
375
376 if (firstPkt.has<lp::IncomingFaceIdField>()) {
377 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
378 }
379
Eric Newberryee400b52016-11-24 14:12:48 +0000380 if (firstPkt.has<lp::CongestionMarkField>()) {
381 interest->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
382 }
383
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700384 if (firstPkt.has<lp::NonDiscoveryField>()) {
385 if (m_options.allowSelfLearning) {
386 interest->setTag(make_shared<lp::NonDiscoveryTag>(firstPkt.get<lp::NonDiscoveryField>()));
387 }
388 else {
389 NFD_LOG_FACE_WARN("received NonDiscovery, but self-learning disabled: IGNORE");
390 }
391 }
392
393 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
394 ++this->nInNetInvalid;
395 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Interest: DROP");
396 return;
397 }
398
Eric Newberry86d31872015-09-23 16:24:59 -0700399 this->receiveInterest(*interest);
400}
401
402void
403GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt)
404{
405 BOOST_ASSERT(netPkt.type() == tlv::Data);
406
407 // forwarding expects Data to be created with make_shared
408 auto data = make_shared<Data>(netPkt);
409
Spyridon Mastorakis1429fc12016-12-06 15:20:19 -0800410 if (firstPkt.has<lp::HopCountTagField>()) {
411 data->setTag(make_shared<lp::HopCountTag>(firstPkt.get<lp::HopCountTagField>() + 1));
412 }
413
Eric Newberry86d31872015-09-23 16:24:59 -0700414 if (firstPkt.has<lp::NackField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700415 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700416 NFD_LOG_FACE_WARN("received Nack with Data: DROP");
417 return;
418 }
419
420 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700421 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700422 NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
423 return;
424 }
425
426 if (firstPkt.has<lp::CachePolicyField>()) {
Junxiao Shi6eb02712017-05-27 22:48:02 +0000427 // CachePolicy is unprivileged and does not require allowLocalFields option.
428 // In case of an invalid CachePolicyType, get<lp::CachePolicyField> will throw,
429 // so it's unnecessary to check here.
430 data->setTag(make_shared<lp::CachePolicyTag>(firstPkt.get<lp::CachePolicyField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700431 }
432
433 if (firstPkt.has<lp::IncomingFaceIdField>()) {
434 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
435 }
436
Eric Newberryee400b52016-11-24 14:12:48 +0000437 if (firstPkt.has<lp::CongestionMarkField>()) {
438 data->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
439 }
440
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700441 if (firstPkt.has<lp::NonDiscoveryField>()) {
442 ++this->nInNetInvalid;
443 NFD_LOG_FACE_WARN("received NonDiscovery with Data: DROP");
444 return;
445 }
446
447 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
448 if (m_options.allowSelfLearning) {
449 data->setTag(make_shared<lp::PrefixAnnouncementTag>(firstPkt.get<lp::PrefixAnnouncementField>()));
450 }
451 else {
452 NFD_LOG_FACE_WARN("received PrefixAnnouncement, but self-learning disabled: IGNORE");
453 }
454 }
455
Eric Newberry86d31872015-09-23 16:24:59 -0700456 this->receiveData(*data);
457}
458
459void
460GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt)
461{
462 BOOST_ASSERT(netPkt.type() == tlv::Interest);
463 BOOST_ASSERT(firstPkt.has<lp::NackField>());
464
465 lp::Nack nack((Interest(netPkt)));
466 nack.setHeader(firstPkt.get<lp::NackField>());
467
468 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700469 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700470 NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
471 return;
472 }
473
474 if (firstPkt.has<lp::CachePolicyField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700475 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700476 NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
477 return;
478 }
479
480 if (firstPkt.has<lp::IncomingFaceIdField>()) {
481 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
482 }
483
Eric Newberryee400b52016-11-24 14:12:48 +0000484 if (firstPkt.has<lp::CongestionMarkField>()) {
485 nack.setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
486 }
487
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700488 if (firstPkt.has<lp::NonDiscoveryField>()) {
489 ++this->nInNetInvalid;
490 NFD_LOG_FACE_WARN("received NonDiscovery with Nack: DROP");
491 return;
492 }
493
494 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
495 ++this->nInNetInvalid;
496 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Nack: DROP");
497 return;
498 }
499
Eric Newberry86d31872015-09-23 16:24:59 -0700500 this->receiveNack(nack);
Eric Newberrya98bf932015-09-21 00:58:47 -0700501}
502
503} // namespace face
504} // namespace nfd