blob: 2ab9f7ef5cfef66aa3d14dfea836345b2224c3bc [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 Pesaventoa8098582019-03-31 15:48:02 -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 "generic-link-service.hpp"
Eric Newberryb49313d2017-12-24 20:22:27 -070027
Junxiao Shi606d5dd2019-09-23 12:47:44 -060028#include <ndn-cxx/lp/pit-token.hpp>
Junxiao Shicbc8e942016-09-06 03:17:45 +000029#include <ndn-cxx/lp/tags.hpp>
Eric Newberrya98bf932015-09-21 00:58:47 -070030
Eric Newberryb49313d2017-12-24 20:22:27 -070031#include <cmath>
32
Eric Newberrya98bf932015-09-21 00:58:47 -070033namespace nfd {
34namespace face {
35
Davide Pesaventoa3148082018-04-12 18:21:54 -040036NFD_LOG_INIT(GenericLinkService);
Eric Newberrya98bf932015-09-21 00:58:47 -070037
Davide Pesaventoa8098582019-03-31 15:48:02 -040038constexpr size_t CONGESTION_MARK_SIZE = tlv::sizeOfVarNumber(lp::tlv::CongestionMark) + // type
39 tlv::sizeOfVarNumber(sizeof(uint64_t)) + // length
40 tlv::sizeOfNonNegativeInteger(UINT64_MAX); // value
41
Eric Newberryb49313d2017-12-24 20:22:27 -070042constexpr uint32_t DEFAULT_CONGESTION_THRESHOLD_DIVISOR = 2;
43
Eric Newberry86d31872015-09-23 16:24:59 -070044GenericLinkService::GenericLinkService(const GenericLinkService::Options& options)
Eric Newberry73bcad32017-04-25 17:57:35 -070045 : m_options(options)
Eric Newberry4c3e6b82015-11-10 16:48:42 -070046 , m_fragmenter(m_options.fragmenterOptions, this)
47 , m_reassembler(m_options.reassemblerOptions, this)
Eric Newberry185ab292017-03-28 06:45:39 +000048 , m_reliability(m_options.reliabilityOptions, this)
Eric Newberry4c3e6b82015-11-10 16:48:42 -070049 , m_lastSeqNo(-2)
Eric Newberryb49313d2017-12-24 20:22:27 -070050 , m_nextMarkTime(time::steady_clock::TimePoint::max())
51 , m_lastMarkTime(time::steady_clock::TimePoint::min())
52 , m_nMarkedSinceInMarkingState(0)
Eric Newberry86d31872015-09-23 16:24:59 -070053{
Davide Pesaventoe4b22382018-06-10 14:37:24 -040054 m_reassembler.beforeTimeout.connect([this] (auto...) { ++this->nReassemblyTimeouts; });
55 m_reliability.onDroppedInterest.connect([this] (const auto& i) { this->notifyDroppedInterest(i); });
Eric Newberry73bcad32017-04-25 17:57:35 -070056 nReassembling.observe(&m_reassembler);
Eric Newberry86d31872015-09-23 16:24:59 -070057}
58
Eric Newberrya98bf932015-09-21 00:58:47 -070059void
Eric Newberry185ab292017-03-28 06:45:39 +000060GenericLinkService::setOptions(const GenericLinkService::Options& options)
61{
62 m_options = options;
63 m_fragmenter.setOptions(m_options.fragmenterOptions);
64 m_reassembler.setOptions(m_options.reassemblerOptions);
65 m_reliability.setOptions(m_options.reliabilityOptions);
66}
67
68void
ashiqopu075bb7d2019-03-10 01:38:21 +000069GenericLinkService::requestIdlePacket(const EndpointId& endpointId)
Eric Newberry185ab292017-03-28 06:45:39 +000070{
71 // No need to request Acks to attach to this packet from LpReliability, as they are already
72 // attached in sendLpPacket
ashiqopu075bb7d2019-03-10 01:38:21 +000073 this->sendLpPacket({}, endpointId);
Eric Newberry185ab292017-03-28 06:45:39 +000074}
75
76void
ashiqopu075bb7d2019-03-10 01:38:21 +000077GenericLinkService::sendLpPacket(lp::Packet&& pkt, const EndpointId& endpointId)
Eric Newberry185ab292017-03-28 06:45:39 +000078{
79 const ssize_t mtu = this->getTransport()->getMtu();
Eric Newberryb49313d2017-12-24 20:22:27 -070080
Eric Newberry185ab292017-03-28 06:45:39 +000081 if (m_options.reliabilityOptions.isEnabled) {
82 m_reliability.piggyback(pkt, mtu);
83 }
84
Eric Newberryb49313d2017-12-24 20:22:27 -070085 if (m_options.allowCongestionMarking) {
86 checkCongestionLevel(pkt);
87 }
88
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040089 auto block = pkt.wireEncode();
90 if (mtu != MTU_UNLIMITED && block.size() > static_cast<size_t>(mtu)) {
Eric Newberry185ab292017-03-28 06:45:39 +000091 ++this->nOutOverMtu;
92 NFD_LOG_FACE_WARN("attempted to send packet over MTU limit");
93 return;
94 }
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040095 this->sendPacket(block, endpointId);
Eric Newberry185ab292017-03-28 06:45:39 +000096}
97
98void
ashiqopu075bb7d2019-03-10 01:38:21 +000099GenericLinkService::doSendInterest(const Interest& interest, const EndpointId& endpointId)
Eric Newberrya98bf932015-09-21 00:58:47 -0700100{
101 lp::Packet lpPacket(interest.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000102
Eric Newberryee400b52016-11-24 14:12:48 +0000103 encodeLpFields(interest, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700104
ashiqopu075bb7d2019-03-10 01:38:21 +0000105 this->sendNetPacket(std::move(lpPacket), endpointId, true);
Eric Newberrya98bf932015-09-21 00:58:47 -0700106}
107
108void
ashiqopu075bb7d2019-03-10 01:38:21 +0000109GenericLinkService::doSendData(const Data& data, const EndpointId& endpointId)
Eric Newberrya98bf932015-09-21 00:58:47 -0700110{
111 lp::Packet lpPacket(data.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000112
Eric Newberryee400b52016-11-24 14:12:48 +0000113 encodeLpFields(data, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700114
ashiqopu075bb7d2019-03-10 01:38:21 +0000115 this->sendNetPacket(std::move(lpPacket), endpointId, false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700116}
117
118void
ashiqopu075bb7d2019-03-10 01:38:21 +0000119GenericLinkService::doSendNack(const lp::Nack& nack, const EndpointId& endpointId)
Eric Newberrya98bf932015-09-21 00:58:47 -0700120{
121 lp::Packet lpPacket(nack.getInterest().wireEncode());
122 lpPacket.add<lp::NackField>(nack.getHeader());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000123
Eric Newberryee400b52016-11-24 14:12:48 +0000124 encodeLpFields(nack, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700125
ashiqopu075bb7d2019-03-10 01:38:21 +0000126 this->sendNetPacket(std::move(lpPacket), endpointId, false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700127}
128
Junxiao Shi0de23a22015-12-03 20:07:02 +0000129void
Eric Newberry41aba102017-11-01 16:42:13 -0700130GenericLinkService::encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket)
Eric Newberry86d31872015-09-23 16:24:59 -0700131{
Eric Newberryee400b52016-11-24 14:12:48 +0000132 if (m_options.allowLocalFields) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600133 auto incomingFaceIdTag = netPkt.getTag<lp::IncomingFaceIdTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000134 if (incomingFaceIdTag != nullptr) {
135 lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
136 }
137 }
138
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600139 auto congestionMarkTag = netPkt.getTag<lp::CongestionMarkTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000140 if (congestionMarkTag != nullptr) {
141 lpPacket.add<lp::CongestionMarkField>(*congestionMarkTag);
Eric Newberry86d31872015-09-23 16:24:59 -0700142 }
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700143
144 if (m_options.allowSelfLearning) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600145 auto nonDiscoveryTag = netPkt.getTag<lp::NonDiscoveryTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700146 if (nonDiscoveryTag != nullptr) {
147 lpPacket.add<lp::NonDiscoveryField>(*nonDiscoveryTag);
148 }
149
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600150 auto prefixAnnouncementTag = netPkt.getTag<lp::PrefixAnnouncementTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700151 if (prefixAnnouncementTag != nullptr) {
152 lpPacket.add<lp::PrefixAnnouncementField>(*prefixAnnouncementTag);
153 }
154 }
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600155
156 auto pitToken = netPkt.getTag<lp::PitToken>();
157 if (pitToken != nullptr) {
158 lpPacket.add<lp::PitTokenField>(*pitToken);
159 }
Eric Newberry86d31872015-09-23 16:24:59 -0700160}
161
Eric Newberrya98bf932015-09-21 00:58:47 -0700162void
ashiqopu075bb7d2019-03-10 01:38:21 +0000163GenericLinkService::sendNetPacket(lp::Packet&& pkt, const EndpointId& endpointId, bool isInterest)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700164{
165 std::vector<lp::Packet> frags;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000166 ssize_t mtu = this->getTransport()->getMtu();
167
168 // Make space for feature fields in fragments
169 if (m_options.reliabilityOptions.isEnabled && mtu != MTU_UNLIMITED) {
170 mtu -= LpReliability::RESERVED_HEADER_SPACE;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000171 }
172
Eric Newberryb49313d2017-12-24 20:22:27 -0700173 if (m_options.allowCongestionMarking && mtu != MTU_UNLIMITED) {
174 mtu -= CONGESTION_MARK_SIZE;
175 }
176
177 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
178
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700179 if (m_options.allowFragmentation && mtu != MTU_UNLIMITED) {
180 bool isOk = false;
181 std::tie(isOk, frags) = m_fragmenter.fragmentPacket(pkt, mtu);
182 if (!isOk) {
183 // fragmentation failed (warning is logged by LpFragmenter)
Junxiao Shi0de23a22015-12-03 20:07:02 +0000184 ++this->nFragmentationErrors;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700185 return;
186 }
187 }
188 else {
Eric Newberry41aba102017-11-01 16:42:13 -0700189 if (m_options.reliabilityOptions.isEnabled) {
190 frags.push_back(pkt);
191 }
192 else {
193 frags.push_back(std::move(pkt));
194 }
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700195 }
196
Eric Newberry185ab292017-03-28 06:45:39 +0000197 if (frags.size() == 1) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700198 // even if indexed fragmentation is enabled, the fragmenter should not
199 // fragment the packet if it can fit in MTU
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700200 BOOST_ASSERT(!frags.front().has<lp::FragIndexField>());
201 BOOST_ASSERT(!frags.front().has<lp::FragCountField>());
202 }
203
Eric Newberry7b0071e2017-07-03 17:33:31 +0000204 // Only assign sequences to fragments if packet contains more than 1 fragment
205 if (frags.size() > 1) {
Eric Newberry185ab292017-03-28 06:45:39 +0000206 // Assign sequences to all fragments
207 this->assignSequences(frags);
208 }
209
210 if (m_options.reliabilityOptions.isEnabled && frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -0700211 m_reliability.handleOutgoing(frags, std::move(pkt), isInterest);
Eric Newberry185ab292017-03-28 06:45:39 +0000212 }
213
214 for (lp::Packet& frag : frags) {
ashiqopu075bb7d2019-03-10 01:38:21 +0000215 this->sendLpPacket(std::move(frag), endpointId);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700216 }
217}
218
219void
220GenericLinkService::assignSequence(lp::Packet& pkt)
221{
222 pkt.set<lp::SequenceField>(++m_lastSeqNo);
223}
224
225void
226GenericLinkService::assignSequences(std::vector<lp::Packet>& pkts)
227{
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400228 std::for_each(pkts.begin(), pkts.end(), [this] (auto& pkt) { this->assignSequence(pkt); });
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700229}
230
231void
Eric Newberryb49313d2017-12-24 20:22:27 -0700232GenericLinkService::checkCongestionLevel(lp::Packet& pkt)
233{
234 ssize_t sendQueueLength = getTransport()->getSendQueueLength();
235 // This operation requires that the transport supports retrieving current send queue length
236 if (sendQueueLength < 0) {
237 return;
238 }
239
240 // To avoid overflowing the queue, set the congestion threshold to at least half of the send
241 // queue capacity.
242 size_t congestionThreshold = m_options.defaultCongestionThreshold;
243 if (getTransport()->getSendQueueCapacity() >= 0) {
244 congestionThreshold = std::min(congestionThreshold,
245 static_cast<size_t>(getTransport()->getSendQueueCapacity()) /
246 DEFAULT_CONGESTION_THRESHOLD_DIVISOR);
247 }
248
249 if (sendQueueLength > 0) {
250 NFD_LOG_FACE_TRACE("txqlen=" << sendQueueLength << " threshold=" << congestionThreshold <<
251 " capacity=" << getTransport()->getSendQueueCapacity());
252 }
253
254 if (static_cast<size_t>(sendQueueLength) > congestionThreshold) { // Send queue is congested
255 const auto now = time::steady_clock::now();
256 if (now >= m_nextMarkTime || now >= m_lastMarkTime + m_options.baseCongestionMarkingInterval) {
257 // Mark at most one initial packet per baseCongestionMarkingInterval
258 if (m_nMarkedSinceInMarkingState == 0) {
259 m_nextMarkTime = now;
260 }
261
262 // Time to mark packet
263 pkt.set<lp::CongestionMarkField>(1);
264 ++nCongestionMarked;
265 NFD_LOG_FACE_DEBUG("LpPacket was marked as congested");
266
267 ++m_nMarkedSinceInMarkingState;
268 // Decrease the marking interval by the inverse of the square root of the number of packets
269 // marked in this incident of congestion
270 m_nextMarkTime += time::nanoseconds(static_cast<time::nanoseconds::rep>(
271 m_options.baseCongestionMarkingInterval.count() /
272 std::sqrt(m_nMarkedSinceInMarkingState)));
273 m_lastMarkTime = now;
274 }
275 }
276 else if (m_nextMarkTime != time::steady_clock::TimePoint::max()) {
277 // Congestion incident has ended, so reset
278 NFD_LOG_FACE_DEBUG("Send queue length dropped below congestion threshold");
279 m_nextMarkTime = time::steady_clock::TimePoint::max();
280 m_nMarkedSinceInMarkingState = 0;
281 }
282}
283
284void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400285GenericLinkService::doReceivePacket(const Block& packet, const EndpointId& endpoint)
Eric Newberrya98bf932015-09-21 00:58:47 -0700286{
Eric Newberry86d31872015-09-23 16:24:59 -0700287 try {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400288 lp::Packet pkt(packet);
Eric Newberrya1939ba2015-10-09 12:35:03 -0700289
Eric Newberry185ab292017-03-28 06:45:39 +0000290 if (m_options.reliabilityOptions.isEnabled) {
291 m_reliability.processIncomingPacket(pkt);
292 }
293
Eric Newberrya1939ba2015-10-09 12:35:03 -0700294 if (!pkt.has<lp::FragmentField>()) {
295 NFD_LOG_FACE_TRACE("received IDLE packet: DROP");
296 return;
297 }
298
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700299 if ((pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) &&
300 !m_options.allowReassembly) {
301 NFD_LOG_FACE_WARN("received fragment, but reassembly disabled: DROP");
Eric Newberrya1939ba2015-10-09 12:35:03 -0700302 return;
303 }
304
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700305 bool isReassembled = false;
306 Block netPkt;
307 lp::Packet firstPkt;
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400308 std::tie(isReassembled, netPkt, firstPkt) = m_reassembler.receiveFragment(endpoint, pkt);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700309 if (isReassembled) {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400310 this->decodeNetPacket(netPkt, firstPkt, endpoint);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700311 }
312 }
313 catch (const tlv::Error& e) {
314 ++this->nInLpInvalid;
315 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
316 }
317}
Eric Newberry86d31872015-09-23 16:24:59 -0700318
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700319void
ashiqopu075bb7d2019-03-10 01:38:21 +0000320GenericLinkService::decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt,
321 const EndpointId& endpointId)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700322{
323 try {
Eric Newberry86d31872015-09-23 16:24:59 -0700324 switch (netPkt.type()) {
325 case tlv::Interest:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700326 if (firstPkt.has<lp::NackField>()) {
ashiqopu075bb7d2019-03-10 01:38:21 +0000327 this->decodeNack(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700328 }
329 else {
ashiqopu075bb7d2019-03-10 01:38:21 +0000330 this->decodeInterest(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700331 }
332 break;
333 case tlv::Data:
ashiqopu075bb7d2019-03-10 01:38:21 +0000334 this->decodeData(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700335 break;
336 default:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700337 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700338 NFD_LOG_FACE_WARN("unrecognized network-layer packet TLV-TYPE " << netPkt.type() << ": DROP");
339 return;
Eric Newberrya98bf932015-09-21 00:58:47 -0700340 }
341 }
Eric Newberry86d31872015-09-23 16:24:59 -0700342 catch (const tlv::Error& e) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700343 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700344 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
345 }
346}
347
Eric Newberry86d31872015-09-23 16:24:59 -0700348void
ashiqopu075bb7d2019-03-10 01:38:21 +0000349GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt,
350 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700351{
352 BOOST_ASSERT(netPkt.type() == tlv::Interest);
353 BOOST_ASSERT(!firstPkt.has<lp::NackField>());
354
355 // forwarding expects Interest to be created with make_shared
356 auto interest = make_shared<Interest>(netPkt);
357
358 if (firstPkt.has<lp::NextHopFaceIdField>()) {
359 if (m_options.allowLocalFields) {
Junxiao Shi0de23a22015-12-03 20:07:02 +0000360 interest->setTag(make_shared<lp::NextHopFaceIdTag>(firstPkt.get<lp::NextHopFaceIdField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700361 }
362 else {
363 NFD_LOG_FACE_WARN("received NextHopFaceId, but local fields disabled: DROP");
364 return;
365 }
366 }
367
368 if (firstPkt.has<lp::CachePolicyField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700369 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700370 NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
371 return;
372 }
373
374 if (firstPkt.has<lp::IncomingFaceIdField>()) {
375 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
376 }
377
Eric Newberryee400b52016-11-24 14:12:48 +0000378 if (firstPkt.has<lp::CongestionMarkField>()) {
379 interest->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
380 }
381
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700382 if (firstPkt.has<lp::NonDiscoveryField>()) {
383 if (m_options.allowSelfLearning) {
384 interest->setTag(make_shared<lp::NonDiscoveryTag>(firstPkt.get<lp::NonDiscoveryField>()));
385 }
386 else {
387 NFD_LOG_FACE_WARN("received NonDiscovery, but self-learning disabled: IGNORE");
388 }
389 }
390
391 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
392 ++this->nInNetInvalid;
393 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Interest: DROP");
394 return;
395 }
396
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600397 if (firstPkt.has<lp::PitTokenField>()) {
398 interest->setTag(make_shared<lp::PitToken>(firstPkt.get<lp::PitTokenField>()));
399 }
400
ashiqopu075bb7d2019-03-10 01:38:21 +0000401 this->receiveInterest(*interest, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700402}
403
404void
ashiqopu075bb7d2019-03-10 01:38:21 +0000405GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt,
406 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700407{
408 BOOST_ASSERT(netPkt.type() == tlv::Data);
409
410 // forwarding expects Data to be created with make_shared
411 auto data = make_shared<Data>(netPkt);
412
413 if (firstPkt.has<lp::NackField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700414 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700415 NFD_LOG_FACE_WARN("received Nack with Data: DROP");
416 return;
417 }
418
419 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700420 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700421 NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
422 return;
423 }
424
425 if (firstPkt.has<lp::CachePolicyField>()) {
Junxiao Shi6eb02712017-05-27 22:48:02 +0000426 // CachePolicy is unprivileged and does not require allowLocalFields option.
427 // In case of an invalid CachePolicyType, get<lp::CachePolicyField> will throw,
428 // so it's unnecessary to check here.
429 data->setTag(make_shared<lp::CachePolicyTag>(firstPkt.get<lp::CachePolicyField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700430 }
431
432 if (firstPkt.has<lp::IncomingFaceIdField>()) {
433 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
434 }
435
Eric Newberryee400b52016-11-24 14:12:48 +0000436 if (firstPkt.has<lp::CongestionMarkField>()) {
437 data->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
438 }
439
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700440 if (firstPkt.has<lp::NonDiscoveryField>()) {
441 ++this->nInNetInvalid;
442 NFD_LOG_FACE_WARN("received NonDiscovery with Data: DROP");
443 return;
444 }
445
446 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
447 if (m_options.allowSelfLearning) {
448 data->setTag(make_shared<lp::PrefixAnnouncementTag>(firstPkt.get<lp::PrefixAnnouncementField>()));
449 }
450 else {
451 NFD_LOG_FACE_WARN("received PrefixAnnouncement, but self-learning disabled: IGNORE");
452 }
453 }
454
ashiqopu075bb7d2019-03-10 01:38:21 +0000455 this->receiveData(*data, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700456}
457
458void
ashiqopu075bb7d2019-03-10 01:38:21 +0000459GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt,
460 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700461{
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
ashiqopu075bb7d2019-03-10 01:38:21 +0000500 this->receiveNack(nack, endpointId);
Eric Newberrya98bf932015-09-21 00:58:47 -0700501}
502
503} // namespace face
504} // namespace nfd