blob: 1ab78fe7431908212347aca5156a5a2e59c24d93 [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 Pesavento412c9822021-07-02 00:21:05 -04003 * Copyright (c) 2014-2021, 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 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 Newberry4c3e6b82015-11-10 16:48:42 -070047 , m_lastSeqNo(-2)
Davide Pesavento412c9822021-07-02 00:21:05 -040048 , m_nextMarkTime(time::steady_clock::time_point::max())
Eric Newberryb49313d2017-12-24 20:22:27 -070049 , m_nMarkedSinceInMarkingState(0)
Eric Newberry86d31872015-09-23 16:24:59 -070050{
Davide Pesavento412c9822021-07-02 00:21:05 -040051 m_reassembler.beforeTimeout.connect([this] (auto&&...) { ++nReassemblyTimeouts; });
52 m_reliability.onDroppedInterest.connect([this] (const auto& i) { notifyDroppedInterest(i); });
Eric Newberry73bcad32017-04-25 17:57:35 -070053 nReassembling.observe(&m_reassembler);
Eric Newberry86d31872015-09-23 16:24:59 -070054}
55
Eric Newberrya98bf932015-09-21 00:58:47 -070056void
Eric Newberry185ab292017-03-28 06:45:39 +000057GenericLinkService::setOptions(const GenericLinkService::Options& options)
58{
59 m_options = options;
60 m_fragmenter.setOptions(m_options.fragmenterOptions);
61 m_reassembler.setOptions(m_options.reassemblerOptions);
62 m_reliability.setOptions(m_options.reliabilityOptions);
63}
64
Eric Newberrycb6551e2020-03-02 14:12:16 -080065ssize_t
66GenericLinkService::getEffectiveMtu() const
67{
68 // Since MTU_UNLIMITED is negative, it will implicitly override any finite override MTU
69 return std::min(m_options.overrideMtu, getTransport()->getMtu());
70}
71
72bool
73GenericLinkService::canOverrideMtuTo(ssize_t mtu) const
74{
75 // Not allowed to override unlimited transport MTU
76 if (getTransport()->getMtu() == MTU_UNLIMITED) {
77 return false;
78 }
79
80 // Override MTU must be at least MIN_MTU (also implicitly forbids MTU_UNLIMITED and MTU_INVALID)
81 return mtu >= MIN_MTU;
82}
83
Eric Newberry185ab292017-03-28 06:45:39 +000084void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070085GenericLinkService::requestIdlePacket()
Eric Newberry185ab292017-03-28 06:45:39 +000086{
87 // No need to request Acks to attach to this packet from LpReliability, as they are already
88 // attached in sendLpPacket
Eric Newberry5ab4cf82020-02-03 15:40:16 -080089 NFD_LOG_FACE_TRACE("IDLE packet requested");
Teng Liangf3bc3ae2020-06-08 10:19:25 -070090 this->sendLpPacket({});
Eric Newberry185ab292017-03-28 06:45:39 +000091}
92
93void
Teng Liangf3bc3ae2020-06-08 10:19:25 -070094GenericLinkService::sendLpPacket(lp::Packet&& pkt)
Eric Newberry185ab292017-03-28 06:45:39 +000095{
Eric Newberrycb6551e2020-03-02 14:12:16 -080096 const ssize_t mtu = getEffectiveMtu();
Eric Newberryb49313d2017-12-24 20:22:27 -070097
Eric Newberry185ab292017-03-28 06:45:39 +000098 if (m_options.reliabilityOptions.isEnabled) {
99 m_reliability.piggyback(pkt, mtu);
100 }
101
Eric Newberryb49313d2017-12-24 20:22:27 -0700102 if (m_options.allowCongestionMarking) {
103 checkCongestionLevel(pkt);
104 }
105
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400106 auto block = pkt.wireEncode();
107 if (mtu != MTU_UNLIMITED && block.size() > static_cast<size_t>(mtu)) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400108 ++nOutOverMtu;
Eric Newberry185ab292017-03-28 06:45:39 +0000109 NFD_LOG_FACE_WARN("attempted to send packet over MTU limit");
110 return;
111 }
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700112 this->sendPacket(block);
Eric Newberry185ab292017-03-28 06:45:39 +0000113}
114
115void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700116GenericLinkService::doSendInterest(const Interest& interest)
Eric Newberrya98bf932015-09-21 00:58:47 -0700117{
118 lp::Packet lpPacket(interest.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000119
Eric Newberryee400b52016-11-24 14:12:48 +0000120 encodeLpFields(interest, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700121
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700122 this->sendNetPacket(std::move(lpPacket), true);
Eric Newberrya98bf932015-09-21 00:58:47 -0700123}
124
125void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700126GenericLinkService::doSendData(const Data& data)
Eric Newberrya98bf932015-09-21 00:58:47 -0700127{
128 lp::Packet lpPacket(data.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000129
Eric Newberryee400b52016-11-24 14:12:48 +0000130 encodeLpFields(data, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700131
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700132 this->sendNetPacket(std::move(lpPacket), false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700133}
134
135void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700136GenericLinkService::doSendNack(const lp::Nack& nack)
Eric Newberrya98bf932015-09-21 00:58:47 -0700137{
138 lp::Packet lpPacket(nack.getInterest().wireEncode());
139 lpPacket.add<lp::NackField>(nack.getHeader());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000140
Eric Newberryee400b52016-11-24 14:12:48 +0000141 encodeLpFields(nack, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700142
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700143 this->sendNetPacket(std::move(lpPacket), false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700144}
145
Junxiao Shi0de23a22015-12-03 20:07:02 +0000146void
Eric Newberry32f7eac2020-02-07 14:40:17 -0800147GenericLinkService::assignSequences(std::vector<lp::Packet>& pkts)
148{
149 std::for_each(pkts.begin(), pkts.end(), [this] (lp::Packet& pkt) {
150 pkt.set<lp::SequenceField>(++m_lastSeqNo);
151 });
152}
153
154void
Eric Newberry41aba102017-11-01 16:42:13 -0700155GenericLinkService::encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket)
Eric Newberry86d31872015-09-23 16:24:59 -0700156{
Eric Newberryee400b52016-11-24 14:12:48 +0000157 if (m_options.allowLocalFields) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600158 auto incomingFaceIdTag = netPkt.getTag<lp::IncomingFaceIdTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000159 if (incomingFaceIdTag != nullptr) {
160 lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
161 }
162 }
163
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600164 auto congestionMarkTag = netPkt.getTag<lp::CongestionMarkTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000165 if (congestionMarkTag != nullptr) {
166 lpPacket.add<lp::CongestionMarkField>(*congestionMarkTag);
Eric Newberry86d31872015-09-23 16:24:59 -0700167 }
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700168
169 if (m_options.allowSelfLearning) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600170 auto nonDiscoveryTag = netPkt.getTag<lp::NonDiscoveryTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700171 if (nonDiscoveryTag != nullptr) {
172 lpPacket.add<lp::NonDiscoveryField>(*nonDiscoveryTag);
173 }
174
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600175 auto prefixAnnouncementTag = netPkt.getTag<lp::PrefixAnnouncementTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700176 if (prefixAnnouncementTag != nullptr) {
177 lpPacket.add<lp::PrefixAnnouncementField>(*prefixAnnouncementTag);
178 }
179 }
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600180
181 auto pitToken = netPkt.getTag<lp::PitToken>();
182 if (pitToken != nullptr) {
183 lpPacket.add<lp::PitTokenField>(*pitToken);
184 }
Spyridon Mastorakise6900392016-12-06 15:20:19 -0800185
186 shared_ptr<lp::HopCountTag> hopCountTag = netPkt.getTag<lp::HopCountTag>();
187 if (hopCountTag != nullptr) {
188 lpPacket.add<lp::HopCountTagField>(*hopCountTag);
189 }
190 else {
191 lpPacket.add<lp::HopCountTagField>(0);
192 }
Alexander Afanasyevbaee72a2019-07-29 11:10:16 -0400193
194 if (m_options.enableGeoTags) {
195 auto geoTag = m_options.enableGeoTags();
196 if (geoTag != nullptr) {
197 lpPacket.add<lp::GeoTagField>(*geoTag);
198 }
199 }
Eric Newberry86d31872015-09-23 16:24:59 -0700200}
201
Eric Newberrya98bf932015-09-21 00:58:47 -0700202void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700203GenericLinkService::sendNetPacket(lp::Packet&& pkt, bool isInterest)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700204{
205 std::vector<lp::Packet> frags;
Eric Newberrycb6551e2020-03-02 14:12:16 -0800206 ssize_t mtu = getEffectiveMtu();
Eric Newberry7b0071e2017-07-03 17:33:31 +0000207
208 // Make space for feature fields in fragments
209 if (m_options.reliabilityOptions.isEnabled && mtu != MTU_UNLIMITED) {
210 mtu -= LpReliability::RESERVED_HEADER_SPACE;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000211 }
212
Eric Newberryb49313d2017-12-24 20:22:27 -0700213 if (m_options.allowCongestionMarking && mtu != MTU_UNLIMITED) {
214 mtu -= CONGESTION_MARK_SIZE;
215 }
216
Eric Newberryf3ee8082020-01-28 13:44:18 -0800217 // An MTU of 0 is allowed but will cause all packets to be dropped before transmission
218 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu >= 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700219
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700220 if (m_options.allowFragmentation && mtu != MTU_UNLIMITED) {
221 bool isOk = false;
222 std::tie(isOk, frags) = m_fragmenter.fragmentPacket(pkt, mtu);
223 if (!isOk) {
224 // fragmentation failed (warning is logged by LpFragmenter)
Davide Pesavento412c9822021-07-02 00:21:05 -0400225 ++nFragmentationErrors;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700226 return;
227 }
228 }
229 else {
Eric Newberry41aba102017-11-01 16:42:13 -0700230 if (m_options.reliabilityOptions.isEnabled) {
231 frags.push_back(pkt);
232 }
233 else {
234 frags.push_back(std::move(pkt));
235 }
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700236 }
237
Eric Newberry185ab292017-03-28 06:45:39 +0000238 if (frags.size() == 1) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700239 // even if indexed fragmentation is enabled, the fragmenter should not
240 // fragment the packet if it can fit in MTU
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700241 BOOST_ASSERT(!frags.front().has<lp::FragIndexField>());
242 BOOST_ASSERT(!frags.front().has<lp::FragCountField>());
243 }
244
Eric Newberry32f7eac2020-02-07 14:40:17 -0800245 // Only assign sequences to fragments if reliability enabled or if packet contains >1 fragment
246 if (m_options.reliabilityOptions.isEnabled || frags.size() > 1) {
Eric Newberry185ab292017-03-28 06:45:39 +0000247 // Assign sequences to all fragments
248 this->assignSequences(frags);
249 }
250
251 if (m_options.reliabilityOptions.isEnabled && frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -0700252 m_reliability.handleOutgoing(frags, std::move(pkt), isInterest);
Eric Newberry185ab292017-03-28 06:45:39 +0000253 }
254
255 for (lp::Packet& frag : frags) {
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700256 this->sendLpPacket(std::move(frag));
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700257 }
258}
259
260void
Eric Newberryb49313d2017-12-24 20:22:27 -0700261GenericLinkService::checkCongestionLevel(lp::Packet& pkt)
262{
263 ssize_t sendQueueLength = getTransport()->getSendQueueLength();
Klaus Schneider380668b2019-10-02 01:21:13 -0700264 // The transport must support retrieving the current send queue length
Eric Newberryb49313d2017-12-24 20:22:27 -0700265 if (sendQueueLength < 0) {
266 return;
267 }
268
Eric Newberryb49313d2017-12-24 20:22:27 -0700269 if (sendQueueLength > 0) {
Klaus Schneider380668b2019-10-02 01:21:13 -0700270 NFD_LOG_FACE_TRACE("txqlen=" << sendQueueLength << " threshold=" <<
271 m_options.defaultCongestionThreshold << " capacity=" <<
272 getTransport()->getSendQueueCapacity());
Eric Newberryb49313d2017-12-24 20:22:27 -0700273 }
274
Klaus Schneider380668b2019-10-02 01:21:13 -0700275 // sendQueue is above target
276 if (static_cast<size_t>(sendQueueLength) > m_options.defaultCongestionThreshold) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700277 const auto now = time::steady_clock::now();
Eric Newberryb49313d2017-12-24 20:22:27 -0700278
Davide Pesavento412c9822021-07-02 00:21:05 -0400279 if (m_nextMarkTime == time::steady_clock::time_point::max()) {
Klaus Schneider380668b2019-10-02 01:21:13 -0700280 m_nextMarkTime = now + m_options.baseCongestionMarkingInterval;
281 }
282 // Mark packet if sendQueue stays above target for one interval
283 else if (now >= m_nextMarkTime) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700284 pkt.set<lp::CongestionMarkField>(1);
285 ++nCongestionMarked;
286 NFD_LOG_FACE_DEBUG("LpPacket was marked as congested");
287
288 ++m_nMarkedSinceInMarkingState;
289 // Decrease the marking interval by the inverse of the square root of the number of packets
290 // marked in this incident of congestion
Klaus Schneider380668b2019-10-02 01:21:13 -0700291 time::nanoseconds interval(static_cast<time::nanoseconds::rep>(
292 m_options.baseCongestionMarkingInterval.count() /
293 std::sqrt(m_nMarkedSinceInMarkingState + 1)));
294 m_nextMarkTime += interval;
Eric Newberryb49313d2017-12-24 20:22:27 -0700295 }
296 }
Davide Pesavento412c9822021-07-02 00:21:05 -0400297 else if (m_nextMarkTime != time::steady_clock::time_point::max()) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700298 // Congestion incident has ended, so reset
299 NFD_LOG_FACE_DEBUG("Send queue length dropped below congestion threshold");
Davide Pesavento412c9822021-07-02 00:21:05 -0400300 m_nextMarkTime = time::steady_clock::time_point::max();
Eric Newberryb49313d2017-12-24 20:22:27 -0700301 m_nMarkedSinceInMarkingState = 0;
302 }
303}
304
305void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400306GenericLinkService::doReceivePacket(const Block& packet, const EndpointId& endpoint)
Eric Newberrya98bf932015-09-21 00:58:47 -0700307{
Eric Newberry86d31872015-09-23 16:24:59 -0700308 try {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400309 lp::Packet pkt(packet);
Eric Newberrya1939ba2015-10-09 12:35:03 -0700310
Eric Newberry185ab292017-03-28 06:45:39 +0000311 if (m_options.reliabilityOptions.isEnabled) {
Eric Newberry32f7eac2020-02-07 14:40:17 -0800312 if (!m_reliability.processIncomingPacket(pkt)) {
313 NFD_LOG_FACE_TRACE("received duplicate fragment: DROP");
Davide Pesavento412c9822021-07-02 00:21:05 -0400314 ++nDuplicateSequence;
Eric Newberry32f7eac2020-02-07 14:40:17 -0800315 return;
316 }
Eric Newberry185ab292017-03-28 06:45:39 +0000317 }
318
Eric Newberrya1939ba2015-10-09 12:35:03 -0700319 if (!pkt.has<lp::FragmentField>()) {
320 NFD_LOG_FACE_TRACE("received IDLE packet: DROP");
321 return;
322 }
323
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700324 if ((pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) &&
325 !m_options.allowReassembly) {
326 NFD_LOG_FACE_WARN("received fragment, but reassembly disabled: DROP");
Eric Newberrya1939ba2015-10-09 12:35:03 -0700327 return;
328 }
329
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700330 bool isReassembled = false;
331 Block netPkt;
332 lp::Packet firstPkt;
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400333 std::tie(isReassembled, netPkt, firstPkt) = m_reassembler.receiveFragment(endpoint, pkt);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700334 if (isReassembled) {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400335 this->decodeNetPacket(netPkt, firstPkt, endpoint);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700336 }
337 }
338 catch (const tlv::Error& e) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400339 ++nInLpInvalid;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700340 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
341 }
342}
Eric Newberry86d31872015-09-23 16:24:59 -0700343
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700344void
ashiqopu075bb7d2019-03-10 01:38:21 +0000345GenericLinkService::decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt,
346 const EndpointId& endpointId)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700347{
348 try {
Eric Newberry86d31872015-09-23 16:24:59 -0700349 switch (netPkt.type()) {
350 case tlv::Interest:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700351 if (firstPkt.has<lp::NackField>()) {
ashiqopu075bb7d2019-03-10 01:38:21 +0000352 this->decodeNack(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700353 }
354 else {
ashiqopu075bb7d2019-03-10 01:38:21 +0000355 this->decodeInterest(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700356 }
357 break;
358 case tlv::Data:
ashiqopu075bb7d2019-03-10 01:38:21 +0000359 this->decodeData(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700360 break;
361 default:
Davide Pesavento412c9822021-07-02 00:21:05 -0400362 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700363 NFD_LOG_FACE_WARN("unrecognized network-layer packet TLV-TYPE " << netPkt.type() << ": DROP");
364 return;
Eric Newberrya98bf932015-09-21 00:58:47 -0700365 }
366 }
Eric Newberry86d31872015-09-23 16:24:59 -0700367 catch (const tlv::Error& e) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400368 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700369 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
370 }
371}
372
Eric Newberry86d31872015-09-23 16:24:59 -0700373void
ashiqopu075bb7d2019-03-10 01:38:21 +0000374GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt,
375 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700376{
377 BOOST_ASSERT(netPkt.type() == tlv::Interest);
378 BOOST_ASSERT(!firstPkt.has<lp::NackField>());
379
380 // forwarding expects Interest to be created with make_shared
381 auto interest = make_shared<Interest>(netPkt);
382
Spyridon Mastorakise6900392016-12-06 15:20:19 -0800383 // Increment HopCount
384 if (firstPkt.has<lp::HopCountTagField>()) {
385 interest->setTag(make_shared<lp::HopCountTag>(firstPkt.get<lp::HopCountTagField>() + 1));
386 }
387
Alexander Afanasyevbaee72a2019-07-29 11:10:16 -0400388 if (m_options.enableGeoTags && firstPkt.has<lp::GeoTagField>()) {
389 interest->setTag(make_shared<lp::GeoTag>(firstPkt.get<lp::GeoTagField>()));
390 }
391
Eric Newberry86d31872015-09-23 16:24:59 -0700392 if (firstPkt.has<lp::NextHopFaceIdField>()) {
393 if (m_options.allowLocalFields) {
Junxiao Shi0de23a22015-12-03 20:07:02 +0000394 interest->setTag(make_shared<lp::NextHopFaceIdTag>(firstPkt.get<lp::NextHopFaceIdField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700395 }
396 else {
397 NFD_LOG_FACE_WARN("received NextHopFaceId, but local fields disabled: DROP");
398 return;
399 }
400 }
401
402 if (firstPkt.has<lp::CachePolicyField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400403 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700404 NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
405 return;
406 }
407
408 if (firstPkt.has<lp::IncomingFaceIdField>()) {
409 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
410 }
411
Eric Newberryee400b52016-11-24 14:12:48 +0000412 if (firstPkt.has<lp::CongestionMarkField>()) {
413 interest->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
414 }
415
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700416 if (firstPkt.has<lp::NonDiscoveryField>()) {
417 if (m_options.allowSelfLearning) {
418 interest->setTag(make_shared<lp::NonDiscoveryTag>(firstPkt.get<lp::NonDiscoveryField>()));
419 }
420 else {
421 NFD_LOG_FACE_WARN("received NonDiscovery, but self-learning disabled: IGNORE");
422 }
423 }
424
425 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400426 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700427 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Interest: DROP");
428 return;
429 }
430
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600431 if (firstPkt.has<lp::PitTokenField>()) {
432 interest->setTag(make_shared<lp::PitToken>(firstPkt.get<lp::PitTokenField>()));
433 }
434
ashiqopu075bb7d2019-03-10 01:38:21 +0000435 this->receiveInterest(*interest, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700436}
437
438void
ashiqopu075bb7d2019-03-10 01:38:21 +0000439GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt,
440 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700441{
442 BOOST_ASSERT(netPkt.type() == tlv::Data);
443
444 // forwarding expects Data to be created with make_shared
445 auto data = make_shared<Data>(netPkt);
446
Spyridon Mastorakise6900392016-12-06 15:20:19 -0800447 if (firstPkt.has<lp::HopCountTagField>()) {
448 data->setTag(make_shared<lp::HopCountTag>(firstPkt.get<lp::HopCountTagField>() + 1));
449 }
450
Alexander Afanasyevbaee72a2019-07-29 11:10:16 -0400451 if (m_options.enableGeoTags && firstPkt.has<lp::GeoTagField>()) {
452 data->setTag(make_shared<lp::GeoTag>(firstPkt.get<lp::GeoTagField>()));
453 }
454
Eric Newberry86d31872015-09-23 16:24:59 -0700455 if (firstPkt.has<lp::NackField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400456 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700457 NFD_LOG_FACE_WARN("received Nack with Data: DROP");
458 return;
459 }
460
461 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400462 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700463 NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
464 return;
465 }
466
467 if (firstPkt.has<lp::CachePolicyField>()) {
Junxiao Shi6eb02712017-05-27 22:48:02 +0000468 // CachePolicy is unprivileged and does not require allowLocalFields option.
469 // In case of an invalid CachePolicyType, get<lp::CachePolicyField> will throw,
470 // so it's unnecessary to check here.
471 data->setTag(make_shared<lp::CachePolicyTag>(firstPkt.get<lp::CachePolicyField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700472 }
473
474 if (firstPkt.has<lp::IncomingFaceIdField>()) {
475 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
476 }
477
Eric Newberryee400b52016-11-24 14:12:48 +0000478 if (firstPkt.has<lp::CongestionMarkField>()) {
479 data->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
480 }
481
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700482 if (firstPkt.has<lp::NonDiscoveryField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400483 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700484 NFD_LOG_FACE_WARN("received NonDiscovery with Data: DROP");
485 return;
486 }
487
488 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
489 if (m_options.allowSelfLearning) {
490 data->setTag(make_shared<lp::PrefixAnnouncementTag>(firstPkt.get<lp::PrefixAnnouncementField>()));
491 }
492 else {
493 NFD_LOG_FACE_WARN("received PrefixAnnouncement, but self-learning disabled: IGNORE");
494 }
495 }
496
ashiqopu075bb7d2019-03-10 01:38:21 +0000497 this->receiveData(*data, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700498}
499
500void
ashiqopu075bb7d2019-03-10 01:38:21 +0000501GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt,
502 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700503{
504 BOOST_ASSERT(netPkt.type() == tlv::Interest);
505 BOOST_ASSERT(firstPkt.has<lp::NackField>());
506
507 lp::Nack nack((Interest(netPkt)));
508 nack.setHeader(firstPkt.get<lp::NackField>());
509
510 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400511 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700512 NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
513 return;
514 }
515
516 if (firstPkt.has<lp::CachePolicyField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400517 ++nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700518 NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
519 return;
520 }
521
522 if (firstPkt.has<lp::IncomingFaceIdField>()) {
523 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
524 }
525
Eric Newberryee400b52016-11-24 14:12:48 +0000526 if (firstPkt.has<lp::CongestionMarkField>()) {
527 nack.setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
528 }
529
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700530 if (firstPkt.has<lp::NonDiscoveryField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400531 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700532 NFD_LOG_FACE_WARN("received NonDiscovery with Nack: DROP");
533 return;
534 }
535
536 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
Davide Pesavento412c9822021-07-02 00:21:05 -0400537 ++nInNetInvalid;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700538 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Nack: DROP");
539 return;
540 }
541
ashiqopu075bb7d2019-03-10 01:38:21 +0000542 this->receiveNack(nack, endpointId);
Eric Newberrya98bf932015-09-21 00:58:47 -0700543}
544
545} // namespace face
546} // namespace nfd