blob: ed19eec1a1af701975ed4148fe2f2e578816dea7 [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 Pesaventoa3a7a4e2022-05-29 16:06:22 -04003 * Copyright (c) 2014-2022, 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
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040033namespace nfd::face {
Eric Newberrya98bf932015-09-21 00:58:47 -070034
Davide Pesaventoa3148082018-04-12 18:21:54 -040035NFD_LOG_INIT(GenericLinkService);
Eric Newberrya98bf932015-09-21 00:58:47 -070036
Davide Pesaventoa8098582019-03-31 15:48:02 -040037constexpr size_t CONGESTION_MARK_SIZE = tlv::sizeOfVarNumber(lp::tlv::CongestionMark) + // type
38 tlv::sizeOfVarNumber(sizeof(uint64_t)) + // length
39 tlv::sizeOfNonNegativeInteger(UINT64_MAX); // value
40
Eric Newberry86d31872015-09-23 16:24:59 -070041GenericLinkService::GenericLinkService(const GenericLinkService::Options& options)
Eric Newberry73bcad32017-04-25 17:57:35 -070042 : m_options(options)
Eric Newberry4c3e6b82015-11-10 16:48:42 -070043 , m_fragmenter(m_options.fragmenterOptions, this)
44 , m_reassembler(m_options.reassemblerOptions, this)
Eric Newberry185ab292017-03-28 06:45:39 +000045 , m_reliability(m_options.reliabilityOptions, this)
Eric Newberry4c3e6b82015-11-10 16:48:42 -070046 , m_lastSeqNo(-2)
Davide Pesavento412c9822021-07-02 00:21:05 -040047 , m_nextMarkTime(time::steady_clock::time_point::max())
Eric Newberryb49313d2017-12-24 20:22:27 -070048 , m_nMarkedSinceInMarkingState(0)
Eric Newberry86d31872015-09-23 16:24:59 -070049{
Davide Pesavento412c9822021-07-02 00:21:05 -040050 m_reassembler.beforeTimeout.connect([this] (auto&&...) { ++nReassemblyTimeouts; });
51 m_reliability.onDroppedInterest.connect([this] (const auto& i) { notifyDroppedInterest(i); });
Eric Newberry73bcad32017-04-25 17:57:35 -070052 nReassembling.observe(&m_reassembler);
Eric Newberry86d31872015-09-23 16:24:59 -070053}
54
Eric Newberrya98bf932015-09-21 00:58:47 -070055void
Eric Newberry185ab292017-03-28 06:45:39 +000056GenericLinkService::setOptions(const GenericLinkService::Options& options)
57{
58 m_options = options;
59 m_fragmenter.setOptions(m_options.fragmenterOptions);
60 m_reassembler.setOptions(m_options.reassemblerOptions);
61 m_reliability.setOptions(m_options.reliabilityOptions);
62}
63
Eric Newberrycb6551e2020-03-02 14:12:16 -080064ssize_t
65GenericLinkService::getEffectiveMtu() const
66{
67 // Since MTU_UNLIMITED is negative, it will implicitly override any finite override MTU
68 return std::min(m_options.overrideMtu, getTransport()->getMtu());
69}
70
71bool
72GenericLinkService::canOverrideMtuTo(ssize_t mtu) const
73{
74 // Not allowed to override unlimited transport MTU
75 if (getTransport()->getMtu() == MTU_UNLIMITED) {
76 return false;
77 }
78
79 // Override MTU must be at least MIN_MTU (also implicitly forbids MTU_UNLIMITED and MTU_INVALID)
80 return mtu >= MIN_MTU;
81}
82
Eric Newberry185ab292017-03-28 06:45:39 +000083void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070084GenericLinkService::requestIdlePacket()
Eric Newberry185ab292017-03-28 06:45:39 +000085{
86 // No need to request Acks to attach to this packet from LpReliability, as they are already
87 // attached in sendLpPacket
Eric Newberry5ab4cf82020-02-03 15:40:16 -080088 NFD_LOG_FACE_TRACE("IDLE packet requested");
Teng Liangf3bc3ae2020-06-08 10:19:25 -070089 this->sendLpPacket({});
Eric Newberry185ab292017-03-28 06:45:39 +000090}
91
92void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070093GenericLinkService::sendLpPacket(lp::Packet&& pkt)
Eric Newberry185ab292017-03-28 06:45:39 +000094{
Eric Newberrycb6551e2020-03-02 14:12:16 -080095 const ssize_t mtu = getEffectiveMtu();
Eric Newberryb49313d2017-12-24 20:22:27 -070096
Eric Newberry185ab292017-03-28 06:45:39 +000097 if (m_options.reliabilityOptions.isEnabled) {
98 m_reliability.piggyback(pkt, mtu);
99 }
100
Eric Newberryb49313d2017-12-24 20:22:27 -0700101 if (m_options.allowCongestionMarking) {
102 checkCongestionLevel(pkt);
103 }
104
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400105 auto block = pkt.wireEncode();
106 if (mtu != MTU_UNLIMITED && block.size() > static_cast<size_t>(mtu)) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400107 ++nOutOverMtu;
Eric Newberry185ab292017-03-28 06:45:39 +0000108 NFD_LOG_FACE_WARN("attempted to send packet over MTU limit");
109 return;
110 }
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700111 this->sendPacket(block);
Eric Newberry185ab292017-03-28 06:45:39 +0000112}
113
114void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700115GenericLinkService::doSendInterest(const Interest& interest)
Eric Newberrya98bf932015-09-21 00:58:47 -0700116{
117 lp::Packet lpPacket(interest.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000118
Eric Newberryee400b52016-11-24 14:12:48 +0000119 encodeLpFields(interest, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700120
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700121 this->sendNetPacket(std::move(lpPacket), true);
Eric Newberrya98bf932015-09-21 00:58:47 -0700122}
123
124void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700125GenericLinkService::doSendData(const Data& data)
Eric Newberrya98bf932015-09-21 00:58:47 -0700126{
127 lp::Packet lpPacket(data.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000128
Eric Newberryee400b52016-11-24 14:12:48 +0000129 encodeLpFields(data, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700130
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700131 this->sendNetPacket(std::move(lpPacket), false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700132}
133
134void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700135GenericLinkService::doSendNack(const lp::Nack& nack)
Eric Newberrya98bf932015-09-21 00:58:47 -0700136{
137 lp::Packet lpPacket(nack.getInterest().wireEncode());
138 lpPacket.add<lp::NackField>(nack.getHeader());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000139
Eric Newberryee400b52016-11-24 14:12:48 +0000140 encodeLpFields(nack, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700141
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700142 this->sendNetPacket(std::move(lpPacket), false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700143}
144
Junxiao Shi0de23a22015-12-03 20:07:02 +0000145void
Eric Newberry32f7eac2020-02-07 14:40:17 -0800146GenericLinkService::assignSequences(std::vector<lp::Packet>& pkts)
147{
148 std::for_each(pkts.begin(), pkts.end(), [this] (lp::Packet& pkt) {
149 pkt.set<lp::SequenceField>(++m_lastSeqNo);
150 });
151}
152
153void
Eric Newberry41aba102017-11-01 16:42:13 -0700154GenericLinkService::encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket)
Eric Newberry86d31872015-09-23 16:24:59 -0700155{
Eric Newberryee400b52016-11-24 14:12:48 +0000156 if (m_options.allowLocalFields) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600157 auto incomingFaceIdTag = netPkt.getTag<lp::IncomingFaceIdTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000158 if (incomingFaceIdTag != nullptr) {
159 lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
160 }
161 }
162
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600163 auto congestionMarkTag = netPkt.getTag<lp::CongestionMarkTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000164 if (congestionMarkTag != nullptr) {
165 lpPacket.add<lp::CongestionMarkField>(*congestionMarkTag);
Eric Newberry86d31872015-09-23 16:24:59 -0700166 }
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700167
168 if (m_options.allowSelfLearning) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600169 auto nonDiscoveryTag = netPkt.getTag<lp::NonDiscoveryTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700170 if (nonDiscoveryTag != nullptr) {
171 lpPacket.add<lp::NonDiscoveryField>(*nonDiscoveryTag);
172 }
173
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600174 auto prefixAnnouncementTag = netPkt.getTag<lp::PrefixAnnouncementTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700175 if (prefixAnnouncementTag != nullptr) {
176 lpPacket.add<lp::PrefixAnnouncementField>(*prefixAnnouncementTag);
177 }
178 }
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600179
180 auto pitToken = netPkt.getTag<lp::PitToken>();
181 if (pitToken != nullptr) {
182 lpPacket.add<lp::PitTokenField>(*pitToken);
183 }
Eric Newberry86d31872015-09-23 16:24:59 -0700184}
185
Eric Newberrya98bf932015-09-21 00:58:47 -0700186void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700187GenericLinkService::sendNetPacket(lp::Packet&& pkt, bool isInterest)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700188{
189 std::vector<lp::Packet> frags;
Eric Newberrycb6551e2020-03-02 14:12:16 -0800190 ssize_t mtu = getEffectiveMtu();
Eric Newberry7b0071e2017-07-03 17:33:31 +0000191
192 // Make space for feature fields in fragments
193 if (m_options.reliabilityOptions.isEnabled && mtu != MTU_UNLIMITED) {
194 mtu -= LpReliability::RESERVED_HEADER_SPACE;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000195 }
196
Eric Newberryb49313d2017-12-24 20:22:27 -0700197 if (m_options.allowCongestionMarking && mtu != MTU_UNLIMITED) {
198 mtu -= CONGESTION_MARK_SIZE;
199 }
200
Eric Newberryf3ee8082020-01-28 13:44:18 -0800201 // An MTU of 0 is allowed but will cause all packets to be dropped before transmission
202 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu >= 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700203
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700204 if (m_options.allowFragmentation && mtu != MTU_UNLIMITED) {
205 bool isOk = false;
206 std::tie(isOk, frags) = m_fragmenter.fragmentPacket(pkt, mtu);
207 if (!isOk) {
208 // fragmentation failed (warning is logged by LpFragmenter)
Davide Pesavento412c9822021-07-02 00:21:05 -0400209 ++nFragmentationErrors;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700210 return;
211 }
212 }
213 else {
Eric Newberry41aba102017-11-01 16:42:13 -0700214 if (m_options.reliabilityOptions.isEnabled) {
215 frags.push_back(pkt);
216 }
217 else {
218 frags.push_back(std::move(pkt));
219 }
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700220 }
221
Eric Newberry185ab292017-03-28 06:45:39 +0000222 if (frags.size() == 1) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700223 // even if indexed fragmentation is enabled, the fragmenter should not
224 // fragment the packet if it can fit in MTU
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700225 BOOST_ASSERT(!frags.front().has<lp::FragIndexField>());
226 BOOST_ASSERT(!frags.front().has<lp::FragCountField>());
227 }
228
Eric Newberry32f7eac2020-02-07 14:40:17 -0800229 // Only assign sequences to fragments if reliability enabled or if packet contains >1 fragment
230 if (m_options.reliabilityOptions.isEnabled || frags.size() > 1) {
Eric Newberry185ab292017-03-28 06:45:39 +0000231 // Assign sequences to all fragments
232 this->assignSequences(frags);
233 }
234
235 if (m_options.reliabilityOptions.isEnabled && frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -0700236 m_reliability.handleOutgoing(frags, std::move(pkt), isInterest);
Eric Newberry185ab292017-03-28 06:45:39 +0000237 }
238
239 for (lp::Packet& frag : frags) {
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700240 this->sendLpPacket(std::move(frag));
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700241 }
242}
243
244void
Eric Newberryb49313d2017-12-24 20:22:27 -0700245GenericLinkService::checkCongestionLevel(lp::Packet& pkt)
246{
247 ssize_t sendQueueLength = getTransport()->getSendQueueLength();
Klaus Schneider380668b2019-10-02 01:21:13 -0700248 // The transport must support retrieving the current send queue length
Eric Newberryb49313d2017-12-24 20:22:27 -0700249 if (sendQueueLength < 0) {
250 return;
251 }
252
Eric Newberryb49313d2017-12-24 20:22:27 -0700253 if (sendQueueLength > 0) {
Klaus Schneider380668b2019-10-02 01:21:13 -0700254 NFD_LOG_FACE_TRACE("txqlen=" << sendQueueLength << " threshold=" <<
255 m_options.defaultCongestionThreshold << " capacity=" <<
256 getTransport()->getSendQueueCapacity());
Eric Newberryb49313d2017-12-24 20:22:27 -0700257 }
258
Klaus Schneider380668b2019-10-02 01:21:13 -0700259 // sendQueue is above target
260 if (static_cast<size_t>(sendQueueLength) > m_options.defaultCongestionThreshold) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700261 const auto now = time::steady_clock::now();
Eric Newberryb49313d2017-12-24 20:22:27 -0700262
Davide Pesavento412c9822021-07-02 00:21:05 -0400263 if (m_nextMarkTime == time::steady_clock::time_point::max()) {
Klaus Schneider380668b2019-10-02 01:21:13 -0700264 m_nextMarkTime = now + m_options.baseCongestionMarkingInterval;
265 }
266 // Mark packet if sendQueue stays above target for one interval
267 else if (now >= m_nextMarkTime) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700268 pkt.set<lp::CongestionMarkField>(1);
269 ++nCongestionMarked;
270 NFD_LOG_FACE_DEBUG("LpPacket was marked as congested");
271
272 ++m_nMarkedSinceInMarkingState;
273 // Decrease the marking interval by the inverse of the square root of the number of packets
274 // marked in this incident of congestion
Klaus Schneider380668b2019-10-02 01:21:13 -0700275 time::nanoseconds interval(static_cast<time::nanoseconds::rep>(
276 m_options.baseCongestionMarkingInterval.count() /
277 std::sqrt(m_nMarkedSinceInMarkingState + 1)));
278 m_nextMarkTime += interval;
Eric Newberryb49313d2017-12-24 20:22:27 -0700279 }
280 }
Davide Pesavento412c9822021-07-02 00:21:05 -0400281 else if (m_nextMarkTime != time::steady_clock::time_point::max()) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700282 // Congestion incident has ended, so reset
283 NFD_LOG_FACE_DEBUG("Send queue length dropped below congestion threshold");
Davide Pesavento412c9822021-07-02 00:21:05 -0400284 m_nextMarkTime = time::steady_clock::time_point::max();
Eric Newberryb49313d2017-12-24 20:22:27 -0700285 m_nMarkedSinceInMarkingState = 0;
286 }
287}
288
289void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400290GenericLinkService::doReceivePacket(const Block& packet, const EndpointId& endpoint)
Eric Newberrya98bf932015-09-21 00:58:47 -0700291{
Eric Newberry86d31872015-09-23 16:24:59 -0700292 try {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400293 lp::Packet pkt(packet);
Eric Newberrya1939ba2015-10-09 12:35:03 -0700294
Eric Newberry185ab292017-03-28 06:45:39 +0000295 if (m_options.reliabilityOptions.isEnabled) {
Eric Newberry32f7eac2020-02-07 14:40:17 -0800296 if (!m_reliability.processIncomingPacket(pkt)) {
297 NFD_LOG_FACE_TRACE("received duplicate fragment: DROP");
Davide Pesavento412c9822021-07-02 00:21:05 -0400298 ++nDuplicateSequence;
Eric Newberry32f7eac2020-02-07 14:40:17 -0800299 return;
300 }
Eric Newberry185ab292017-03-28 06:45:39 +0000301 }
302
Eric Newberrya1939ba2015-10-09 12:35:03 -0700303 if (!pkt.has<lp::FragmentField>()) {
304 NFD_LOG_FACE_TRACE("received IDLE packet: DROP");
305 return;
306 }
307
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700308 if ((pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) &&
309 !m_options.allowReassembly) {
310 NFD_LOG_FACE_WARN("received fragment, but reassembly disabled: DROP");
Eric Newberrya1939ba2015-10-09 12:35:03 -0700311 return;
312 }
313
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400314 auto [isReassembled, netPkt, firstPkt] = m_reassembler.receiveFragment(endpoint, pkt);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700315 if (isReassembled) {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400316 this->decodeNetPacket(netPkt, firstPkt, endpoint);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700317 }
318 }
319 catch (const tlv::Error& e) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400320 ++nInLpInvalid;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700321 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
322 }
323}
Eric Newberry86d31872015-09-23 16:24:59 -0700324
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700325void
ashiqopu075bb7d2019-03-10 01:38:21 +0000326GenericLinkService::decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt,
327 const EndpointId& endpointId)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700328{
329 try {
Eric Newberry86d31872015-09-23 16:24:59 -0700330 switch (netPkt.type()) {
331 case tlv::Interest:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700332 if (firstPkt.has<lp::NackField>()) {
ashiqopu075bb7d2019-03-10 01:38:21 +0000333 this->decodeNack(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700334 }
335 else {
ashiqopu075bb7d2019-03-10 01:38:21 +0000336 this->decodeInterest(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700337 }
338 break;
339 case tlv::Data:
ashiqopu075bb7d2019-03-10 01:38:21 +0000340 this->decodeData(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700341 break;
342 default:
Davide Pesavento412c9822021-07-02 00:21:05 -0400343 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700344 NFD_LOG_FACE_WARN("unrecognized network-layer packet TLV-TYPE " << netPkt.type() << ": DROP");
345 return;
Eric Newberrya98bf932015-09-21 00:58:47 -0700346 }
347 }
Eric Newberry86d31872015-09-23 16:24:59 -0700348 catch (const tlv::Error& e) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400349 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700350 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
351 }
352}
353
Eric Newberry86d31872015-09-23 16:24:59 -0700354void
ashiqopu075bb7d2019-03-10 01:38:21 +0000355GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt,
356 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700357{
358 BOOST_ASSERT(netPkt.type() == tlv::Interest);
359 BOOST_ASSERT(!firstPkt.has<lp::NackField>());
360
361 // forwarding expects Interest to be created with make_shared
362 auto interest = make_shared<Interest>(netPkt);
363
364 if (firstPkt.has<lp::NextHopFaceIdField>()) {
365 if (m_options.allowLocalFields) {
Junxiao Shi0de23a22015-12-03 20:07:02 +0000366 interest->setTag(make_shared<lp::NextHopFaceIdTag>(firstPkt.get<lp::NextHopFaceIdField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700367 }
368 else {
369 NFD_LOG_FACE_WARN("received NextHopFaceId, but local fields disabled: DROP");
370 return;
371 }
372 }
373
374 if (firstPkt.has<lp::CachePolicyField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400375 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700376 NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
377 return;
378 }
379
380 if (firstPkt.has<lp::IncomingFaceIdField>()) {
381 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
382 }
383
Eric Newberryee400b52016-11-24 14:12:48 +0000384 if (firstPkt.has<lp::CongestionMarkField>()) {
385 interest->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
386 }
387
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700388 if (firstPkt.has<lp::NonDiscoveryField>()) {
389 if (m_options.allowSelfLearning) {
390 interest->setTag(make_shared<lp::NonDiscoveryTag>(firstPkt.get<lp::NonDiscoveryField>()));
391 }
392 else {
393 NFD_LOG_FACE_WARN("received NonDiscovery, but self-learning disabled: IGNORE");
394 }
395 }
396
397 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400398 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700399 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Interest: DROP");
400 return;
401 }
402
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600403 if (firstPkt.has<lp::PitTokenField>()) {
404 interest->setTag(make_shared<lp::PitToken>(firstPkt.get<lp::PitTokenField>()));
405 }
406
ashiqopu075bb7d2019-03-10 01:38:21 +0000407 this->receiveInterest(*interest, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700408}
409
410void
ashiqopu075bb7d2019-03-10 01:38:21 +0000411GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt,
412 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700413{
414 BOOST_ASSERT(netPkt.type() == tlv::Data);
415
416 // forwarding expects Data to be created with make_shared
417 auto data = make_shared<Data>(netPkt);
418
419 if (firstPkt.has<lp::NackField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400420 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700421 NFD_LOG_FACE_WARN("received Nack with Data: DROP");
422 return;
423 }
424
425 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400426 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700427 NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
428 return;
429 }
430
431 if (firstPkt.has<lp::CachePolicyField>()) {
Junxiao Shi6eb02712017-05-27 22:48:02 +0000432 // CachePolicy is unprivileged and does not require allowLocalFields option.
433 // In case of an invalid CachePolicyType, get<lp::CachePolicyField> will throw,
434 // so it's unnecessary to check here.
435 data->setTag(make_shared<lp::CachePolicyTag>(firstPkt.get<lp::CachePolicyField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700436 }
437
438 if (firstPkt.has<lp::IncomingFaceIdField>()) {
439 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
440 }
441
Eric Newberryee400b52016-11-24 14:12:48 +0000442 if (firstPkt.has<lp::CongestionMarkField>()) {
443 data->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
444 }
445
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700446 if (firstPkt.has<lp::NonDiscoveryField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400447 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700448 NFD_LOG_FACE_WARN("received NonDiscovery with Data: DROP");
449 return;
450 }
451
452 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
453 if (m_options.allowSelfLearning) {
454 data->setTag(make_shared<lp::PrefixAnnouncementTag>(firstPkt.get<lp::PrefixAnnouncementField>()));
455 }
456 else {
457 NFD_LOG_FACE_WARN("received PrefixAnnouncement, but self-learning disabled: IGNORE");
458 }
459 }
460
ashiqopu075bb7d2019-03-10 01:38:21 +0000461 this->receiveData(*data, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700462}
463
464void
ashiqopu075bb7d2019-03-10 01:38:21 +0000465GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt,
466 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700467{
468 BOOST_ASSERT(netPkt.type() == tlv::Interest);
469 BOOST_ASSERT(firstPkt.has<lp::NackField>());
470
471 lp::Nack nack((Interest(netPkt)));
472 nack.setHeader(firstPkt.get<lp::NackField>());
473
474 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400475 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700476 NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
477 return;
478 }
479
480 if (firstPkt.has<lp::CachePolicyField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400481 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700482 NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
483 return;
484 }
485
486 if (firstPkt.has<lp::IncomingFaceIdField>()) {
487 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
488 }
489
Eric Newberryee400b52016-11-24 14:12:48 +0000490 if (firstPkt.has<lp::CongestionMarkField>()) {
491 nack.setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
492 }
493
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700494 if (firstPkt.has<lp::NonDiscoveryField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400495 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700496 NFD_LOG_FACE_WARN("received NonDiscovery with Nack: DROP");
497 return;
498 }
499
500 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400501 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700502 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Nack: DROP");
503 return;
504 }
505
ashiqopu075bb7d2019-03-10 01:38:21 +0000506 this->receiveNack(nack, endpointId);
Eric Newberrya98bf932015-09-21 00:58:47 -0700507}
508
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400509} // namespace nfd::face