blob: 239de43bd296712ef29c6c6fdf8e750d09033e53 [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 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)
Eric Newberryb49313d2017-12-24 20:22:27 -070048 , m_nextMarkTime(time::steady_clock::TimePoint::max())
Eric Newberryb49313d2017-12-24 20:22:27 -070049 , m_nMarkedSinceInMarkingState(0)
Eric Newberry86d31872015-09-23 16:24:59 -070050{
Davide Pesaventoe4b22382018-06-10 14:37:24 -040051 m_reassembler.beforeTimeout.connect([this] (auto...) { ++this->nReassemblyTimeouts; });
52 m_reliability.onDroppedInterest.connect([this] (const auto& i) { this->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
65void
ashiqopu075bb7d2019-03-10 01:38:21 +000066GenericLinkService::requestIdlePacket(const EndpointId& endpointId)
Eric Newberry185ab292017-03-28 06:45:39 +000067{
68 // No need to request Acks to attach to this packet from LpReliability, as they are already
69 // attached in sendLpPacket
ashiqopu075bb7d2019-03-10 01:38:21 +000070 this->sendLpPacket({}, endpointId);
Eric Newberry185ab292017-03-28 06:45:39 +000071}
72
73void
ashiqopu075bb7d2019-03-10 01:38:21 +000074GenericLinkService::sendLpPacket(lp::Packet&& pkt, const EndpointId& endpointId)
Eric Newberry185ab292017-03-28 06:45:39 +000075{
76 const ssize_t mtu = this->getTransport()->getMtu();
Eric Newberryb49313d2017-12-24 20:22:27 -070077
Eric Newberry185ab292017-03-28 06:45:39 +000078 if (m_options.reliabilityOptions.isEnabled) {
79 m_reliability.piggyback(pkt, mtu);
80 }
81
Eric Newberryb49313d2017-12-24 20:22:27 -070082 if (m_options.allowCongestionMarking) {
83 checkCongestionLevel(pkt);
84 }
85
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040086 auto block = pkt.wireEncode();
87 if (mtu != MTU_UNLIMITED && block.size() > static_cast<size_t>(mtu)) {
Eric Newberry185ab292017-03-28 06:45:39 +000088 ++this->nOutOverMtu;
89 NFD_LOG_FACE_WARN("attempted to send packet over MTU limit");
90 return;
91 }
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040092 this->sendPacket(block, endpointId);
Eric Newberry185ab292017-03-28 06:45:39 +000093}
94
95void
ashiqopu075bb7d2019-03-10 01:38:21 +000096GenericLinkService::doSendInterest(const Interest& interest, const EndpointId& endpointId)
Eric Newberrya98bf932015-09-21 00:58:47 -070097{
98 lp::Packet lpPacket(interest.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +000099
Eric Newberryee400b52016-11-24 14:12:48 +0000100 encodeLpFields(interest, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700101
ashiqopu075bb7d2019-03-10 01:38:21 +0000102 this->sendNetPacket(std::move(lpPacket), endpointId, true);
Eric Newberrya98bf932015-09-21 00:58:47 -0700103}
104
105void
ashiqopu075bb7d2019-03-10 01:38:21 +0000106GenericLinkService::doSendData(const Data& data, const EndpointId& endpointId)
Eric Newberrya98bf932015-09-21 00:58:47 -0700107{
108 lp::Packet lpPacket(data.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000109
Eric Newberryee400b52016-11-24 14:12:48 +0000110 encodeLpFields(data, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700111
ashiqopu075bb7d2019-03-10 01:38:21 +0000112 this->sendNetPacket(std::move(lpPacket), endpointId, false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700113}
114
115void
ashiqopu075bb7d2019-03-10 01:38:21 +0000116GenericLinkService::doSendNack(const lp::Nack& nack, const EndpointId& endpointId)
Eric Newberrya98bf932015-09-21 00:58:47 -0700117{
118 lp::Packet lpPacket(nack.getInterest().wireEncode());
119 lpPacket.add<lp::NackField>(nack.getHeader());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000120
Eric Newberryee400b52016-11-24 14:12:48 +0000121 encodeLpFields(nack, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700122
ashiqopu075bb7d2019-03-10 01:38:21 +0000123 this->sendNetPacket(std::move(lpPacket), endpointId, false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700124}
125
Junxiao Shi0de23a22015-12-03 20:07:02 +0000126void
Eric Newberry41aba102017-11-01 16:42:13 -0700127GenericLinkService::encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket)
Eric Newberry86d31872015-09-23 16:24:59 -0700128{
Eric Newberryee400b52016-11-24 14:12:48 +0000129 if (m_options.allowLocalFields) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600130 auto incomingFaceIdTag = netPkt.getTag<lp::IncomingFaceIdTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000131 if (incomingFaceIdTag != nullptr) {
132 lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
133 }
134 }
135
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600136 auto congestionMarkTag = netPkt.getTag<lp::CongestionMarkTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000137 if (congestionMarkTag != nullptr) {
138 lpPacket.add<lp::CongestionMarkField>(*congestionMarkTag);
Eric Newberry86d31872015-09-23 16:24:59 -0700139 }
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700140
141 if (m_options.allowSelfLearning) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600142 auto nonDiscoveryTag = netPkt.getTag<lp::NonDiscoveryTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700143 if (nonDiscoveryTag != nullptr) {
144 lpPacket.add<lp::NonDiscoveryField>(*nonDiscoveryTag);
145 }
146
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600147 auto prefixAnnouncementTag = netPkt.getTag<lp::PrefixAnnouncementTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700148 if (prefixAnnouncementTag != nullptr) {
149 lpPacket.add<lp::PrefixAnnouncementField>(*prefixAnnouncementTag);
150 }
151 }
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600152
153 auto pitToken = netPkt.getTag<lp::PitToken>();
154 if (pitToken != nullptr) {
155 lpPacket.add<lp::PitTokenField>(*pitToken);
156 }
Spyridon Mastorakisfc5711a2016-12-06 15:20:19 -0800157
158 shared_ptr<lp::HopCountTag> hopCountTag = netPkt.getTag<lp::HopCountTag>();
159 if (hopCountTag != nullptr) {
160 lpPacket.add<lp::HopCountTagField>(*hopCountTag);
161 }
162 else {
163 lpPacket.add<lp::HopCountTagField>(0);
164 }
Alexander Afanasyev53b29172019-07-29 11:10:16 -0400165
166 if (m_options.enableGeoTags) {
167 auto geoTag = m_options.enableGeoTags();
168 if (geoTag != nullptr) {
169 lpPacket.add<lp::GeoTagField>(*geoTag);
170 }
171 }
Eric Newberry86d31872015-09-23 16:24:59 -0700172}
173
Eric Newberrya98bf932015-09-21 00:58:47 -0700174void
ashiqopu075bb7d2019-03-10 01:38:21 +0000175GenericLinkService::sendNetPacket(lp::Packet&& pkt, const EndpointId& endpointId, bool isInterest)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700176{
177 std::vector<lp::Packet> frags;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000178 ssize_t mtu = this->getTransport()->getMtu();
179
180 // Make space for feature fields in fragments
181 if (m_options.reliabilityOptions.isEnabled && mtu != MTU_UNLIMITED) {
182 mtu -= LpReliability::RESERVED_HEADER_SPACE;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000183 }
184
Eric Newberryb49313d2017-12-24 20:22:27 -0700185 if (m_options.allowCongestionMarking && mtu != MTU_UNLIMITED) {
186 mtu -= CONGESTION_MARK_SIZE;
187 }
188
189 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
190
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700191 if (m_options.allowFragmentation && mtu != MTU_UNLIMITED) {
192 bool isOk = false;
193 std::tie(isOk, frags) = m_fragmenter.fragmentPacket(pkt, mtu);
194 if (!isOk) {
195 // fragmentation failed (warning is logged by LpFragmenter)
Junxiao Shi0de23a22015-12-03 20:07:02 +0000196 ++this->nFragmentationErrors;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700197 return;
198 }
199 }
200 else {
Eric Newberry41aba102017-11-01 16:42:13 -0700201 if (m_options.reliabilityOptions.isEnabled) {
202 frags.push_back(pkt);
203 }
204 else {
205 frags.push_back(std::move(pkt));
206 }
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700207 }
208
Eric Newberry185ab292017-03-28 06:45:39 +0000209 if (frags.size() == 1) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700210 // even if indexed fragmentation is enabled, the fragmenter should not
211 // fragment the packet if it can fit in MTU
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700212 BOOST_ASSERT(!frags.front().has<lp::FragIndexField>());
213 BOOST_ASSERT(!frags.front().has<lp::FragCountField>());
214 }
215
Eric Newberry7b0071e2017-07-03 17:33:31 +0000216 // Only assign sequences to fragments if packet contains more than 1 fragment
217 if (frags.size() > 1) {
Eric Newberry185ab292017-03-28 06:45:39 +0000218 // Assign sequences to all fragments
219 this->assignSequences(frags);
220 }
221
222 if (m_options.reliabilityOptions.isEnabled && frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -0700223 m_reliability.handleOutgoing(frags, std::move(pkt), isInterest);
Eric Newberry185ab292017-03-28 06:45:39 +0000224 }
225
226 for (lp::Packet& frag : frags) {
ashiqopu075bb7d2019-03-10 01:38:21 +0000227 this->sendLpPacket(std::move(frag), endpointId);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700228 }
229}
230
231void
232GenericLinkService::assignSequence(lp::Packet& pkt)
233{
234 pkt.set<lp::SequenceField>(++m_lastSeqNo);
235}
236
237void
238GenericLinkService::assignSequences(std::vector<lp::Packet>& pkts)
239{
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400240 std::for_each(pkts.begin(), pkts.end(), [this] (auto& pkt) { this->assignSequence(pkt); });
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700241}
242
243void
Eric Newberryb49313d2017-12-24 20:22:27 -0700244GenericLinkService::checkCongestionLevel(lp::Packet& pkt)
245{
246 ssize_t sendQueueLength = getTransport()->getSendQueueLength();
Klaus Schneider380668b2019-10-02 01:21:13 -0700247 // The transport must support retrieving the current send queue length
Eric Newberryb49313d2017-12-24 20:22:27 -0700248 if (sendQueueLength < 0) {
249 return;
250 }
251
Eric Newberryb49313d2017-12-24 20:22:27 -0700252 if (sendQueueLength > 0) {
Klaus Schneider380668b2019-10-02 01:21:13 -0700253 NFD_LOG_FACE_TRACE("txqlen=" << sendQueueLength << " threshold=" <<
254 m_options.defaultCongestionThreshold << " capacity=" <<
255 getTransport()->getSendQueueCapacity());
Eric Newberryb49313d2017-12-24 20:22:27 -0700256 }
257
Klaus Schneider380668b2019-10-02 01:21:13 -0700258 // sendQueue is above target
259 if (static_cast<size_t>(sendQueueLength) > m_options.defaultCongestionThreshold) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700260 const auto now = time::steady_clock::now();
Eric Newberryb49313d2017-12-24 20:22:27 -0700261
Klaus Schneider380668b2019-10-02 01:21:13 -0700262 if (m_nextMarkTime == time::steady_clock::TimePoint::max()) {
263 m_nextMarkTime = now + m_options.baseCongestionMarkingInterval;
264 }
265 // Mark packet if sendQueue stays above target for one interval
266 else if (now >= m_nextMarkTime) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700267 pkt.set<lp::CongestionMarkField>(1);
268 ++nCongestionMarked;
269 NFD_LOG_FACE_DEBUG("LpPacket was marked as congested");
270
271 ++m_nMarkedSinceInMarkingState;
272 // Decrease the marking interval by the inverse of the square root of the number of packets
273 // marked in this incident of congestion
Klaus Schneider380668b2019-10-02 01:21:13 -0700274 time::nanoseconds interval(static_cast<time::nanoseconds::rep>(
275 m_options.baseCongestionMarkingInterval.count() /
276 std::sqrt(m_nMarkedSinceInMarkingState + 1)));
277 m_nextMarkTime += interval;
Eric Newberryb49313d2017-12-24 20:22:27 -0700278 }
279 }
280 else if (m_nextMarkTime != time::steady_clock::TimePoint::max()) {
281 // Congestion incident has ended, so reset
282 NFD_LOG_FACE_DEBUG("Send queue length dropped below congestion threshold");
283 m_nextMarkTime = time::steady_clock::TimePoint::max();
284 m_nMarkedSinceInMarkingState = 0;
285 }
286}
287
288void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400289GenericLinkService::doReceivePacket(const Block& packet, const EndpointId& endpoint)
Eric Newberrya98bf932015-09-21 00:58:47 -0700290{
Eric Newberry86d31872015-09-23 16:24:59 -0700291 try {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400292 lp::Packet pkt(packet);
Eric Newberrya1939ba2015-10-09 12:35:03 -0700293
Eric Newberry185ab292017-03-28 06:45:39 +0000294 if (m_options.reliabilityOptions.isEnabled) {
295 m_reliability.processIncomingPacket(pkt);
296 }
297
Eric Newberrya1939ba2015-10-09 12:35:03 -0700298 if (!pkt.has<lp::FragmentField>()) {
299 NFD_LOG_FACE_TRACE("received IDLE packet: DROP");
300 return;
301 }
302
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700303 if ((pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) &&
304 !m_options.allowReassembly) {
305 NFD_LOG_FACE_WARN("received fragment, but reassembly disabled: DROP");
Eric Newberrya1939ba2015-10-09 12:35:03 -0700306 return;
307 }
308
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700309 bool isReassembled = false;
310 Block netPkt;
311 lp::Packet firstPkt;
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400312 std::tie(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) {
318 ++this->nInLpInvalid;
319 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:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700341 ++this->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) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700347 ++this->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
Spyridon Mastorakisfc5711a2016-12-06 15:20:19 -0800362 // Increment HopCount
363 if (firstPkt.has<lp::HopCountTagField>()) {
364 interest->setTag(make_shared<lp::HopCountTag>(firstPkt.get<lp::HopCountTagField>() + 1));
365 }
366
Alexander Afanasyev53b29172019-07-29 11:10:16 -0400367 if (m_options.enableGeoTags && firstPkt.has<lp::GeoTagField>()) {
368 interest->setTag(make_shared<lp::GeoTag>(firstPkt.get<lp::GeoTagField>()));
369 }
370
Eric Newberry86d31872015-09-23 16:24:59 -0700371 if (firstPkt.has<lp::NextHopFaceIdField>()) {
372 if (m_options.allowLocalFields) {
Junxiao Shi0de23a22015-12-03 20:07:02 +0000373 interest->setTag(make_shared<lp::NextHopFaceIdTag>(firstPkt.get<lp::NextHopFaceIdField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700374 }
375 else {
376 NFD_LOG_FACE_WARN("received NextHopFaceId, but local fields disabled: DROP");
377 return;
378 }
379 }
380
381 if (firstPkt.has<lp::CachePolicyField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700382 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700383 NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
384 return;
385 }
386
387 if (firstPkt.has<lp::IncomingFaceIdField>()) {
388 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
389 }
390
Eric Newberryee400b52016-11-24 14:12:48 +0000391 if (firstPkt.has<lp::CongestionMarkField>()) {
392 interest->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
393 }
394
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700395 if (firstPkt.has<lp::NonDiscoveryField>()) {
396 if (m_options.allowSelfLearning) {
397 interest->setTag(make_shared<lp::NonDiscoveryTag>(firstPkt.get<lp::NonDiscoveryField>()));
398 }
399 else {
400 NFD_LOG_FACE_WARN("received NonDiscovery, but self-learning disabled: IGNORE");
401 }
402 }
403
404 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
405 ++this->nInNetInvalid;
406 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Interest: DROP");
407 return;
408 }
409
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600410 if (firstPkt.has<lp::PitTokenField>()) {
411 interest->setTag(make_shared<lp::PitToken>(firstPkt.get<lp::PitTokenField>()));
412 }
413
ashiqopu075bb7d2019-03-10 01:38:21 +0000414 this->receiveInterest(*interest, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700415}
416
417void
ashiqopu075bb7d2019-03-10 01:38:21 +0000418GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt,
419 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700420{
421 BOOST_ASSERT(netPkt.type() == tlv::Data);
422
423 // forwarding expects Data to be created with make_shared
424 auto data = make_shared<Data>(netPkt);
425
Spyridon Mastorakisfc5711a2016-12-06 15:20:19 -0800426 if (firstPkt.has<lp::HopCountTagField>()) {
427 data->setTag(make_shared<lp::HopCountTag>(firstPkt.get<lp::HopCountTagField>() + 1));
428 }
429
Alexander Afanasyev53b29172019-07-29 11:10:16 -0400430 if (m_options.enableGeoTags && firstPkt.has<lp::GeoTagField>()) {
431 data->setTag(make_shared<lp::GeoTag>(firstPkt.get<lp::GeoTagField>()));
432 }
433
Eric Newberry86d31872015-09-23 16:24:59 -0700434 if (firstPkt.has<lp::NackField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700435 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700436 NFD_LOG_FACE_WARN("received Nack with Data: DROP");
437 return;
438 }
439
440 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700441 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700442 NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
443 return;
444 }
445
446 if (firstPkt.has<lp::CachePolicyField>()) {
Junxiao Shi6eb02712017-05-27 22:48:02 +0000447 // CachePolicy is unprivileged and does not require allowLocalFields option.
448 // In case of an invalid CachePolicyType, get<lp::CachePolicyField> will throw,
449 // so it's unnecessary to check here.
450 data->setTag(make_shared<lp::CachePolicyTag>(firstPkt.get<lp::CachePolicyField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700451 }
452
453 if (firstPkt.has<lp::IncomingFaceIdField>()) {
454 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
455 }
456
Eric Newberryee400b52016-11-24 14:12:48 +0000457 if (firstPkt.has<lp::CongestionMarkField>()) {
458 data->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
459 }
460
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700461 if (firstPkt.has<lp::NonDiscoveryField>()) {
462 ++this->nInNetInvalid;
463 NFD_LOG_FACE_WARN("received NonDiscovery with Data: DROP");
464 return;
465 }
466
467 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
468 if (m_options.allowSelfLearning) {
469 data->setTag(make_shared<lp::PrefixAnnouncementTag>(firstPkt.get<lp::PrefixAnnouncementField>()));
470 }
471 else {
472 NFD_LOG_FACE_WARN("received PrefixAnnouncement, but self-learning disabled: IGNORE");
473 }
474 }
475
ashiqopu075bb7d2019-03-10 01:38:21 +0000476 this->receiveData(*data, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700477}
478
479void
ashiqopu075bb7d2019-03-10 01:38:21 +0000480GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt,
481 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700482{
483 BOOST_ASSERT(netPkt.type() == tlv::Interest);
484 BOOST_ASSERT(firstPkt.has<lp::NackField>());
485
486 lp::Nack nack((Interest(netPkt)));
487 nack.setHeader(firstPkt.get<lp::NackField>());
488
489 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700490 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700491 NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
492 return;
493 }
494
495 if (firstPkt.has<lp::CachePolicyField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700496 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700497 NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
498 return;
499 }
500
501 if (firstPkt.has<lp::IncomingFaceIdField>()) {
502 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
503 }
504
Eric Newberryee400b52016-11-24 14:12:48 +0000505 if (firstPkt.has<lp::CongestionMarkField>()) {
506 nack.setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
507 }
508
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700509 if (firstPkt.has<lp::NonDiscoveryField>()) {
510 ++this->nInNetInvalid;
511 NFD_LOG_FACE_WARN("received NonDiscovery with Nack: DROP");
512 return;
513 }
514
515 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
516 ++this->nInNetInvalid;
517 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Nack: DROP");
518 return;
519 }
520
ashiqopu075bb7d2019-03-10 01:38:21 +0000521 this->receiveNack(nack, endpointId);
Eric Newberrya98bf932015-09-21 00:58:47 -0700522}
523
524} // namespace face
525} // namespace nfd