blob: de073b47107d57a1761d6e11e68db8ac47ea3ca1 [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 Pesavento91c15c82024-01-15 17:14:23 -05003 * Copyright (c) 2014-2024, 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
Davide Pesavento9a63bf22023-11-11 17:12:51 -050028#include <ndn-cxx/lp/fields.hpp>
Junxiao Shi606d5dd2019-09-23 12:47:44 -060029#include <ndn-cxx/lp/pit-token.hpp>
Junxiao Shicbc8e942016-09-06 03:17:45 +000030#include <ndn-cxx/lp/tags.hpp>
Eric Newberrya98bf932015-09-21 00:58:47 -070031
Eric Newberryb49313d2017-12-24 20:22:27 -070032#include <cmath>
33
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040034namespace nfd::face {
Eric Newberrya98bf932015-09-21 00:58:47 -070035
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 Newberry86d31872015-09-23 16:24:59 -070042GenericLinkService::GenericLinkService(const GenericLinkService::Options& options)
Eric Newberry73bcad32017-04-25 17:57:35 -070043 : m_options(options)
Eric Newberry4c3e6b82015-11-10 16:48:42 -070044 , m_fragmenter(m_options.fragmenterOptions, this)
45 , m_reassembler(m_options.reassemblerOptions, this)
Eric Newberry185ab292017-03-28 06:45:39 +000046 , m_reliability(m_options.reliabilityOptions, this)
Eric Newberry86d31872015-09-23 16:24:59 -070047{
Davide Pesavento412c9822021-07-02 00:21:05 -040048 m_reassembler.beforeTimeout.connect([this] (auto&&...) { ++nReassemblyTimeouts; });
49 m_reliability.onDroppedInterest.connect([this] (const auto& i) { notifyDroppedInterest(i); });
Eric Newberry73bcad32017-04-25 17:57:35 -070050 nReassembling.observe(&m_reassembler);
Eric Newberry86d31872015-09-23 16:24:59 -070051}
52
Eric Newberrya98bf932015-09-21 00:58:47 -070053void
Eric Newberry185ab292017-03-28 06:45:39 +000054GenericLinkService::setOptions(const GenericLinkService::Options& options)
55{
56 m_options = options;
57 m_fragmenter.setOptions(m_options.fragmenterOptions);
58 m_reassembler.setOptions(m_options.reassemblerOptions);
59 m_reliability.setOptions(m_options.reliabilityOptions);
60}
61
Eric Newberrycb6551e2020-03-02 14:12:16 -080062ssize_t
63GenericLinkService::getEffectiveMtu() const
64{
65 // Since MTU_UNLIMITED is negative, it will implicitly override any finite override MTU
66 return std::min(m_options.overrideMtu, getTransport()->getMtu());
67}
68
69bool
70GenericLinkService::canOverrideMtuTo(ssize_t mtu) const
71{
72 // Not allowed to override unlimited transport MTU
73 if (getTransport()->getMtu() == MTU_UNLIMITED) {
74 return false;
75 }
76
77 // Override MTU must be at least MIN_MTU (also implicitly forbids MTU_UNLIMITED and MTU_INVALID)
78 return mtu >= MIN_MTU;
79}
80
Eric Newberry185ab292017-03-28 06:45:39 +000081void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070082GenericLinkService::requestIdlePacket()
Eric Newberry185ab292017-03-28 06:45:39 +000083{
84 // No need to request Acks to attach to this packet from LpReliability, as they are already
85 // attached in sendLpPacket
Eric Newberry5ab4cf82020-02-03 15:40:16 -080086 NFD_LOG_FACE_TRACE("IDLE packet requested");
Teng Liangf3bc3ae2020-06-08 10:19:25 -070087 this->sendLpPacket({});
Eric Newberry185ab292017-03-28 06:45:39 +000088}
89
90void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070091GenericLinkService::sendLpPacket(lp::Packet&& pkt)
Eric Newberry185ab292017-03-28 06:45:39 +000092{
Eric Newberrycb6551e2020-03-02 14:12:16 -080093 const ssize_t mtu = getEffectiveMtu();
Eric Newberryb49313d2017-12-24 20:22:27 -070094
Eric Newberry185ab292017-03-28 06:45:39 +000095 if (m_options.reliabilityOptions.isEnabled) {
96 m_reliability.piggyback(pkt, mtu);
97 }
98
Eric Newberryb49313d2017-12-24 20:22:27 -070099 if (m_options.allowCongestionMarking) {
100 checkCongestionLevel(pkt);
101 }
102
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400103 auto block = pkt.wireEncode();
104 if (mtu != MTU_UNLIMITED && block.size() > static_cast<size_t>(mtu)) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400105 ++nOutOverMtu;
Eric Newberry185ab292017-03-28 06:45:39 +0000106 NFD_LOG_FACE_WARN("attempted to send packet over MTU limit");
107 return;
108 }
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700109 this->sendPacket(block);
Eric Newberry185ab292017-03-28 06:45:39 +0000110}
111
112void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700113GenericLinkService::doSendInterest(const Interest& interest)
Eric Newberrya98bf932015-09-21 00:58:47 -0700114{
115 lp::Packet lpPacket(interest.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000116
Eric Newberryee400b52016-11-24 14:12:48 +0000117 encodeLpFields(interest, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700118
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700119 this->sendNetPacket(std::move(lpPacket), true);
Eric Newberrya98bf932015-09-21 00:58:47 -0700120}
121
122void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700123GenericLinkService::doSendData(const Data& data)
Eric Newberrya98bf932015-09-21 00:58:47 -0700124{
125 lp::Packet lpPacket(data.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000126
Eric Newberryee400b52016-11-24 14:12:48 +0000127 encodeLpFields(data, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700128
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700129 this->sendNetPacket(std::move(lpPacket), false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700130}
131
132void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700133GenericLinkService::doSendNack(const lp::Nack& nack)
Eric Newberrya98bf932015-09-21 00:58:47 -0700134{
135 lp::Packet lpPacket(nack.getInterest().wireEncode());
136 lpPacket.add<lp::NackField>(nack.getHeader());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000137
Eric Newberryee400b52016-11-24 14:12:48 +0000138 encodeLpFields(nack, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700139
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700140 this->sendNetPacket(std::move(lpPacket), false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700141}
142
Junxiao Shi0de23a22015-12-03 20:07:02 +0000143void
Eric Newberry32f7eac2020-02-07 14:40:17 -0800144GenericLinkService::assignSequences(std::vector<lp::Packet>& pkts)
145{
146 std::for_each(pkts.begin(), pkts.end(), [this] (lp::Packet& pkt) {
147 pkt.set<lp::SequenceField>(++m_lastSeqNo);
148 });
149}
150
151void
Eric Newberry41aba102017-11-01 16:42:13 -0700152GenericLinkService::encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket)
Eric Newberry86d31872015-09-23 16:24:59 -0700153{
Eric Newberryee400b52016-11-24 14:12:48 +0000154 if (m_options.allowLocalFields) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600155 auto incomingFaceIdTag = netPkt.getTag<lp::IncomingFaceIdTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000156 if (incomingFaceIdTag != nullptr) {
157 lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
158 }
159 }
160
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600161 auto congestionMarkTag = netPkt.getTag<lp::CongestionMarkTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000162 if (congestionMarkTag != nullptr) {
163 lpPacket.add<lp::CongestionMarkField>(*congestionMarkTag);
Eric Newberry86d31872015-09-23 16:24:59 -0700164 }
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700165
166 if (m_options.allowSelfLearning) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600167 auto nonDiscoveryTag = netPkt.getTag<lp::NonDiscoveryTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700168 if (nonDiscoveryTag != nullptr) {
169 lpPacket.add<lp::NonDiscoveryField>(*nonDiscoveryTag);
170 }
171
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600172 auto prefixAnnouncementTag = netPkt.getTag<lp::PrefixAnnouncementTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700173 if (prefixAnnouncementTag != nullptr) {
174 lpPacket.add<lp::PrefixAnnouncementField>(*prefixAnnouncementTag);
175 }
176 }
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600177
178 auto pitToken = netPkt.getTag<lp::PitToken>();
179 if (pitToken != nullptr) {
180 lpPacket.add<lp::PitTokenField>(*pitToken);
181 }
Eric Newberry86d31872015-09-23 16:24:59 -0700182}
183
Eric Newberrya98bf932015-09-21 00:58:47 -0700184void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700185GenericLinkService::sendNetPacket(lp::Packet&& pkt, bool isInterest)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700186{
187 std::vector<lp::Packet> frags;
Eric Newberrycb6551e2020-03-02 14:12:16 -0800188 ssize_t mtu = getEffectiveMtu();
Eric Newberry7b0071e2017-07-03 17:33:31 +0000189
190 // Make space for feature fields in fragments
191 if (m_options.reliabilityOptions.isEnabled && mtu != MTU_UNLIMITED) {
192 mtu -= LpReliability::RESERVED_HEADER_SPACE;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000193 }
194
Eric Newberryb49313d2017-12-24 20:22:27 -0700195 if (m_options.allowCongestionMarking && mtu != MTU_UNLIMITED) {
196 mtu -= CONGESTION_MARK_SIZE;
197 }
198
Eric Newberryf3ee8082020-01-28 13:44:18 -0800199 // An MTU of 0 is allowed but will cause all packets to be dropped before transmission
200 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu >= 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700201
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700202 if (m_options.allowFragmentation && mtu != MTU_UNLIMITED) {
203 bool isOk = false;
204 std::tie(isOk, frags) = m_fragmenter.fragmentPacket(pkt, mtu);
205 if (!isOk) {
206 // fragmentation failed (warning is logged by LpFragmenter)
Davide Pesavento412c9822021-07-02 00:21:05 -0400207 ++nFragmentationErrors;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700208 return;
209 }
210 }
211 else {
Eric Newberry41aba102017-11-01 16:42:13 -0700212 if (m_options.reliabilityOptions.isEnabled) {
213 frags.push_back(pkt);
214 }
215 else {
216 frags.push_back(std::move(pkt));
217 }
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700218 }
219
Eric Newberry185ab292017-03-28 06:45:39 +0000220 if (frags.size() == 1) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700221 // even if indexed fragmentation is enabled, the fragmenter should not
222 // fragment the packet if it can fit in MTU
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700223 BOOST_ASSERT(!frags.front().has<lp::FragIndexField>());
224 BOOST_ASSERT(!frags.front().has<lp::FragCountField>());
225 }
226
Eric Newberry32f7eac2020-02-07 14:40:17 -0800227 // Only assign sequences to fragments if reliability enabled or if packet contains >1 fragment
228 if (m_options.reliabilityOptions.isEnabled || frags.size() > 1) {
Eric Newberry185ab292017-03-28 06:45:39 +0000229 // Assign sequences to all fragments
230 this->assignSequences(frags);
231 }
232
233 if (m_options.reliabilityOptions.isEnabled && frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -0700234 m_reliability.handleOutgoing(frags, std::move(pkt), isInterest);
Eric Newberry185ab292017-03-28 06:45:39 +0000235 }
236
237 for (lp::Packet& frag : frags) {
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700238 this->sendLpPacket(std::move(frag));
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700239 }
240}
241
242void
Eric Newberryb49313d2017-12-24 20:22:27 -0700243GenericLinkService::checkCongestionLevel(lp::Packet& pkt)
244{
245 ssize_t sendQueueLength = getTransport()->getSendQueueLength();
Klaus Schneider380668b2019-10-02 01:21:13 -0700246 // The transport must support retrieving the current send queue length
Eric Newberryb49313d2017-12-24 20:22:27 -0700247 if (sendQueueLength < 0) {
248 return;
249 }
250
Eric Newberryb49313d2017-12-24 20:22:27 -0700251 if (sendQueueLength > 0) {
Klaus Schneider380668b2019-10-02 01:21:13 -0700252 NFD_LOG_FACE_TRACE("txqlen=" << sendQueueLength << " threshold=" <<
253 m_options.defaultCongestionThreshold << " capacity=" <<
254 getTransport()->getSendQueueCapacity());
Eric Newberryb49313d2017-12-24 20:22:27 -0700255 }
256
Klaus Schneider380668b2019-10-02 01:21:13 -0700257 // sendQueue is above target
258 if (static_cast<size_t>(sendQueueLength) > m_options.defaultCongestionThreshold) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700259 const auto now = time::steady_clock::now();
Eric Newberryb49313d2017-12-24 20:22:27 -0700260
Davide Pesavento412c9822021-07-02 00:21:05 -0400261 if (m_nextMarkTime == time::steady_clock::time_point::max()) {
Klaus Schneider380668b2019-10-02 01:21:13 -0700262 m_nextMarkTime = now + m_options.baseCongestionMarkingInterval;
263 }
264 // Mark packet if sendQueue stays above target for one interval
265 else if (now >= m_nextMarkTime) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700266 pkt.set<lp::CongestionMarkField>(1);
267 ++nCongestionMarked;
268 NFD_LOG_FACE_DEBUG("LpPacket was marked as congested");
269
270 ++m_nMarkedSinceInMarkingState;
271 // Decrease the marking interval by the inverse of the square root of the number of packets
272 // marked in this incident of congestion
Klaus Schneider380668b2019-10-02 01:21:13 -0700273 time::nanoseconds interval(static_cast<time::nanoseconds::rep>(
274 m_options.baseCongestionMarkingInterval.count() /
275 std::sqrt(m_nMarkedSinceInMarkingState + 1)));
276 m_nextMarkTime += interval;
Eric Newberryb49313d2017-12-24 20:22:27 -0700277 }
278 }
Davide Pesavento412c9822021-07-02 00:21:05 -0400279 else if (m_nextMarkTime != time::steady_clock::time_point::max()) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700280 // Congestion incident has ended, so reset
281 NFD_LOG_FACE_DEBUG("Send queue length dropped below congestion threshold");
Davide Pesavento412c9822021-07-02 00:21:05 -0400282 m_nextMarkTime = time::steady_clock::time_point::max();
Eric Newberryb49313d2017-12-24 20:22:27 -0700283 m_nMarkedSinceInMarkingState = 0;
284 }
285}
286
287void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400288GenericLinkService::doReceivePacket(const Block& packet, const EndpointId& endpoint)
Eric Newberrya98bf932015-09-21 00:58:47 -0700289{
Eric Newberry86d31872015-09-23 16:24:59 -0700290 try {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400291 lp::Packet pkt(packet);
Eric Newberrya1939ba2015-10-09 12:35:03 -0700292
Eric Newberry185ab292017-03-28 06:45:39 +0000293 if (m_options.reliabilityOptions.isEnabled) {
Eric Newberry32f7eac2020-02-07 14:40:17 -0800294 if (!m_reliability.processIncomingPacket(pkt)) {
295 NFD_LOG_FACE_TRACE("received duplicate fragment: DROP");
Davide Pesavento412c9822021-07-02 00:21:05 -0400296 ++nDuplicateSequence;
Eric Newberry32f7eac2020-02-07 14:40:17 -0800297 return;
298 }
Eric Newberry185ab292017-03-28 06:45:39 +0000299 }
300
Eric Newberrya1939ba2015-10-09 12:35:03 -0700301 if (!pkt.has<lp::FragmentField>()) {
302 NFD_LOG_FACE_TRACE("received IDLE packet: DROP");
303 return;
304 }
305
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700306 if ((pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) &&
307 !m_options.allowReassembly) {
308 NFD_LOG_FACE_WARN("received fragment, but reassembly disabled: DROP");
Eric Newberrya1939ba2015-10-09 12:35:03 -0700309 return;
310 }
311
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400312 auto [isReassembled, netPkt, firstPkt] = m_reassembler.receiveFragment(endpoint, pkt);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700313 if (isReassembled) {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400314 this->decodeNetPacket(netPkt, firstPkt, endpoint);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700315 }
316 }
317 catch (const tlv::Error& e) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400318 ++nInLpInvalid;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700319 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
320 }
321}
Eric Newberry86d31872015-09-23 16:24:59 -0700322
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700323void
ashiqopu075bb7d2019-03-10 01:38:21 +0000324GenericLinkService::decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt,
325 const EndpointId& endpointId)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700326{
327 try {
Eric Newberry86d31872015-09-23 16:24:59 -0700328 switch (netPkt.type()) {
329 case tlv::Interest:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700330 if (firstPkt.has<lp::NackField>()) {
ashiqopu075bb7d2019-03-10 01:38:21 +0000331 this->decodeNack(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700332 }
333 else {
ashiqopu075bb7d2019-03-10 01:38:21 +0000334 this->decodeInterest(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700335 }
336 break;
337 case tlv::Data:
ashiqopu075bb7d2019-03-10 01:38:21 +0000338 this->decodeData(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700339 break;
340 default:
Davide Pesavento412c9822021-07-02 00:21:05 -0400341 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700342 NFD_LOG_FACE_WARN("unrecognized network-layer packet TLV-TYPE " << netPkt.type() << ": DROP");
343 return;
Eric Newberrya98bf932015-09-21 00:58:47 -0700344 }
345 }
Eric Newberry86d31872015-09-23 16:24:59 -0700346 catch (const tlv::Error& e) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400347 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700348 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
349 }
350}
351
Eric Newberry86d31872015-09-23 16:24:59 -0700352void
ashiqopu075bb7d2019-03-10 01:38:21 +0000353GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt,
354 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700355{
356 BOOST_ASSERT(netPkt.type() == tlv::Interest);
357 BOOST_ASSERT(!firstPkt.has<lp::NackField>());
358
359 // forwarding expects Interest to be created with make_shared
360 auto interest = make_shared<Interest>(netPkt);
361
362 if (firstPkt.has<lp::NextHopFaceIdField>()) {
363 if (m_options.allowLocalFields) {
Junxiao Shi0de23a22015-12-03 20:07:02 +0000364 interest->setTag(make_shared<lp::NextHopFaceIdTag>(firstPkt.get<lp::NextHopFaceIdField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700365 }
366 else {
367 NFD_LOG_FACE_WARN("received NextHopFaceId, but local fields disabled: DROP");
368 return;
369 }
370 }
371
372 if (firstPkt.has<lp::CachePolicyField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400373 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700374 NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
375 return;
376 }
377
378 if (firstPkt.has<lp::IncomingFaceIdField>()) {
379 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
380 }
381
Eric Newberryee400b52016-11-24 14:12:48 +0000382 if (firstPkt.has<lp::CongestionMarkField>()) {
383 interest->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
384 }
385
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700386 if (firstPkt.has<lp::NonDiscoveryField>()) {
387 if (m_options.allowSelfLearning) {
388 interest->setTag(make_shared<lp::NonDiscoveryTag>(firstPkt.get<lp::NonDiscoveryField>()));
389 }
390 else {
391 NFD_LOG_FACE_WARN("received NonDiscovery, but self-learning disabled: IGNORE");
392 }
393 }
394
395 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400396 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700397 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Interest: DROP");
398 return;
399 }
400
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600401 if (firstPkt.has<lp::PitTokenField>()) {
402 interest->setTag(make_shared<lp::PitToken>(firstPkt.get<lp::PitTokenField>()));
403 }
404
ashiqopu075bb7d2019-03-10 01:38:21 +0000405 this->receiveInterest(*interest, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700406}
407
408void
ashiqopu075bb7d2019-03-10 01:38:21 +0000409GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt,
410 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700411{
412 BOOST_ASSERT(netPkt.type() == tlv::Data);
413
414 // forwarding expects Data to be created with make_shared
415 auto data = make_shared<Data>(netPkt);
416
417 if (firstPkt.has<lp::NackField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400418 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700419 NFD_LOG_FACE_WARN("received Nack with Data: DROP");
420 return;
421 }
422
423 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400424 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700425 NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
426 return;
427 }
428
429 if (firstPkt.has<lp::CachePolicyField>()) {
Junxiao Shi6eb02712017-05-27 22:48:02 +0000430 // CachePolicy is unprivileged and does not require allowLocalFields option.
431 // In case of an invalid CachePolicyType, get<lp::CachePolicyField> will throw,
432 // so it's unnecessary to check here.
433 data->setTag(make_shared<lp::CachePolicyTag>(firstPkt.get<lp::CachePolicyField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700434 }
435
436 if (firstPkt.has<lp::IncomingFaceIdField>()) {
437 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
438 }
439
Eric Newberryee400b52016-11-24 14:12:48 +0000440 if (firstPkt.has<lp::CongestionMarkField>()) {
441 data->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
442 }
443
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700444 if (firstPkt.has<lp::NonDiscoveryField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400445 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700446 NFD_LOG_FACE_WARN("received NonDiscovery with Data: DROP");
447 return;
448 }
449
450 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
451 if (m_options.allowSelfLearning) {
452 data->setTag(make_shared<lp::PrefixAnnouncementTag>(firstPkt.get<lp::PrefixAnnouncementField>()));
453 }
454 else {
455 NFD_LOG_FACE_WARN("received PrefixAnnouncement, but self-learning disabled: IGNORE");
456 }
457 }
458
ashiqopu075bb7d2019-03-10 01:38:21 +0000459 this->receiveData(*data, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700460}
461
462void
ashiqopu075bb7d2019-03-10 01:38:21 +0000463GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt,
464 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700465{
466 BOOST_ASSERT(netPkt.type() == tlv::Interest);
467 BOOST_ASSERT(firstPkt.has<lp::NackField>());
468
469 lp::Nack nack((Interest(netPkt)));
470 nack.setHeader(firstPkt.get<lp::NackField>());
471
472 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400473 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700474 NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
475 return;
476 }
477
478 if (firstPkt.has<lp::CachePolicyField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400479 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700480 NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
481 return;
482 }
483
484 if (firstPkt.has<lp::IncomingFaceIdField>()) {
485 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
486 }
487
Eric Newberryee400b52016-11-24 14:12:48 +0000488 if (firstPkt.has<lp::CongestionMarkField>()) {
489 nack.setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
490 }
491
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700492 if (firstPkt.has<lp::NonDiscoveryField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400493 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700494 NFD_LOG_FACE_WARN("received NonDiscovery with Nack: DROP");
495 return;
496 }
497
498 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400499 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700500 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Nack: DROP");
501 return;
502 }
503
ashiqopu075bb7d2019-03-10 01:38:21 +0000504 this->receiveNack(nack, endpointId);
Eric Newberrya98bf932015-09-21 00:58:47 -0700505}
506
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400507} // namespace nfd::face