blob: 7e32fc70bcd669db3e09cde011858d3039c2c2b5 [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/*
Eric Newberryf3ee8082020-01-28 13:44:18 -08003 * Copyright (c) 2014-2020, 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
Eric Newberry5ab4cf82020-02-03 15:40:16 -080070 NFD_LOG_FACE_TRACE("IDLE packet requested");
ashiqopu075bb7d2019-03-10 01:38:21 +000071 this->sendLpPacket({}, endpointId);
Eric Newberry185ab292017-03-28 06:45:39 +000072}
73
74void
ashiqopu075bb7d2019-03-10 01:38:21 +000075GenericLinkService::sendLpPacket(lp::Packet&& pkt, const EndpointId& endpointId)
Eric Newberry185ab292017-03-28 06:45:39 +000076{
77 const ssize_t mtu = this->getTransport()->getMtu();
Eric Newberryb49313d2017-12-24 20:22:27 -070078
Eric Newberry185ab292017-03-28 06:45:39 +000079 if (m_options.reliabilityOptions.isEnabled) {
80 m_reliability.piggyback(pkt, mtu);
81 }
82
Eric Newberryb49313d2017-12-24 20:22:27 -070083 if (m_options.allowCongestionMarking) {
84 checkCongestionLevel(pkt);
85 }
86
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040087 auto block = pkt.wireEncode();
88 if (mtu != MTU_UNLIMITED && block.size() > static_cast<size_t>(mtu)) {
Eric Newberry185ab292017-03-28 06:45:39 +000089 ++this->nOutOverMtu;
90 NFD_LOG_FACE_WARN("attempted to send packet over MTU limit");
91 return;
92 }
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040093 this->sendPacket(block, endpointId);
Eric Newberry185ab292017-03-28 06:45:39 +000094}
95
96void
ashiqopu075bb7d2019-03-10 01:38:21 +000097GenericLinkService::doSendInterest(const Interest& interest, const EndpointId& endpointId)
Eric Newberrya98bf932015-09-21 00:58:47 -070098{
99 lp::Packet lpPacket(interest.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000100
Eric Newberryee400b52016-11-24 14:12:48 +0000101 encodeLpFields(interest, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700102
ashiqopu075bb7d2019-03-10 01:38:21 +0000103 this->sendNetPacket(std::move(lpPacket), endpointId, true);
Eric Newberrya98bf932015-09-21 00:58:47 -0700104}
105
106void
ashiqopu075bb7d2019-03-10 01:38:21 +0000107GenericLinkService::doSendData(const Data& data, const EndpointId& endpointId)
Eric Newberrya98bf932015-09-21 00:58:47 -0700108{
109 lp::Packet lpPacket(data.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000110
Eric Newberryee400b52016-11-24 14:12:48 +0000111 encodeLpFields(data, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700112
ashiqopu075bb7d2019-03-10 01:38:21 +0000113 this->sendNetPacket(std::move(lpPacket), endpointId, false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700114}
115
116void
ashiqopu075bb7d2019-03-10 01:38:21 +0000117GenericLinkService::doSendNack(const lp::Nack& nack, const EndpointId& endpointId)
Eric Newberrya98bf932015-09-21 00:58:47 -0700118{
119 lp::Packet lpPacket(nack.getInterest().wireEncode());
120 lpPacket.add<lp::NackField>(nack.getHeader());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000121
Eric Newberryee400b52016-11-24 14:12:48 +0000122 encodeLpFields(nack, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700123
ashiqopu075bb7d2019-03-10 01:38:21 +0000124 this->sendNetPacket(std::move(lpPacket), endpointId, false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700125}
126
Junxiao Shi0de23a22015-12-03 20:07:02 +0000127void
Eric Newberry32f7eac2020-02-07 14:40:17 -0800128GenericLinkService::assignSequences(std::vector<lp::Packet>& pkts)
129{
130 std::for_each(pkts.begin(), pkts.end(), [this] (lp::Packet& pkt) {
131 pkt.set<lp::SequenceField>(++m_lastSeqNo);
132 });
133}
134
135void
Eric Newberry41aba102017-11-01 16:42:13 -0700136GenericLinkService::encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket)
Eric Newberry86d31872015-09-23 16:24:59 -0700137{
Eric Newberryee400b52016-11-24 14:12:48 +0000138 if (m_options.allowLocalFields) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600139 auto incomingFaceIdTag = netPkt.getTag<lp::IncomingFaceIdTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000140 if (incomingFaceIdTag != nullptr) {
141 lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
142 }
143 }
144
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600145 auto congestionMarkTag = netPkt.getTag<lp::CongestionMarkTag>();
Eric Newberryee400b52016-11-24 14:12:48 +0000146 if (congestionMarkTag != nullptr) {
147 lpPacket.add<lp::CongestionMarkField>(*congestionMarkTag);
Eric Newberry86d31872015-09-23 16:24:59 -0700148 }
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700149
150 if (m_options.allowSelfLearning) {
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600151 auto nonDiscoveryTag = netPkt.getTag<lp::NonDiscoveryTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700152 if (nonDiscoveryTag != nullptr) {
153 lpPacket.add<lp::NonDiscoveryField>(*nonDiscoveryTag);
154 }
155
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600156 auto prefixAnnouncementTag = netPkt.getTag<lp::PrefixAnnouncementTag>();
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700157 if (prefixAnnouncementTag != nullptr) {
158 lpPacket.add<lp::PrefixAnnouncementField>(*prefixAnnouncementTag);
159 }
160 }
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600161
162 auto pitToken = netPkt.getTag<lp::PitToken>();
163 if (pitToken != nullptr) {
164 lpPacket.add<lp::PitTokenField>(*pitToken);
165 }
Eric Newberry86d31872015-09-23 16:24:59 -0700166}
167
Eric Newberrya98bf932015-09-21 00:58:47 -0700168void
ashiqopu075bb7d2019-03-10 01:38:21 +0000169GenericLinkService::sendNetPacket(lp::Packet&& pkt, const EndpointId& endpointId, bool isInterest)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700170{
171 std::vector<lp::Packet> frags;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000172 ssize_t mtu = this->getTransport()->getMtu();
173
174 // Make space for feature fields in fragments
175 if (m_options.reliabilityOptions.isEnabled && mtu != MTU_UNLIMITED) {
176 mtu -= LpReliability::RESERVED_HEADER_SPACE;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000177 }
178
Eric Newberryb49313d2017-12-24 20:22:27 -0700179 if (m_options.allowCongestionMarking && mtu != MTU_UNLIMITED) {
180 mtu -= CONGESTION_MARK_SIZE;
181 }
182
Eric Newberryf3ee8082020-01-28 13:44:18 -0800183 // An MTU of 0 is allowed but will cause all packets to be dropped before transmission
184 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu >= 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700185
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700186 if (m_options.allowFragmentation && mtu != MTU_UNLIMITED) {
187 bool isOk = false;
188 std::tie(isOk, frags) = m_fragmenter.fragmentPacket(pkt, mtu);
189 if (!isOk) {
190 // fragmentation failed (warning is logged by LpFragmenter)
Junxiao Shi0de23a22015-12-03 20:07:02 +0000191 ++this->nFragmentationErrors;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700192 return;
193 }
194 }
195 else {
Eric Newberry41aba102017-11-01 16:42:13 -0700196 if (m_options.reliabilityOptions.isEnabled) {
197 frags.push_back(pkt);
198 }
199 else {
200 frags.push_back(std::move(pkt));
201 }
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700202 }
203
Eric Newberry185ab292017-03-28 06:45:39 +0000204 if (frags.size() == 1) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700205 // even if indexed fragmentation is enabled, the fragmenter should not
206 // fragment the packet if it can fit in MTU
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700207 BOOST_ASSERT(!frags.front().has<lp::FragIndexField>());
208 BOOST_ASSERT(!frags.front().has<lp::FragCountField>());
209 }
210
Eric Newberry32f7eac2020-02-07 14:40:17 -0800211 // Only assign sequences to fragments if reliability enabled or if packet contains >1 fragment
212 if (m_options.reliabilityOptions.isEnabled || frags.size() > 1) {
Eric Newberry185ab292017-03-28 06:45:39 +0000213 // Assign sequences to all fragments
214 this->assignSequences(frags);
215 }
216
217 if (m_options.reliabilityOptions.isEnabled && frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -0700218 m_reliability.handleOutgoing(frags, std::move(pkt), isInterest);
Eric Newberry185ab292017-03-28 06:45:39 +0000219 }
220
221 for (lp::Packet& frag : frags) {
ashiqopu075bb7d2019-03-10 01:38:21 +0000222 this->sendLpPacket(std::move(frag), endpointId);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700223 }
224}
225
226void
Eric Newberryb49313d2017-12-24 20:22:27 -0700227GenericLinkService::checkCongestionLevel(lp::Packet& pkt)
228{
229 ssize_t sendQueueLength = getTransport()->getSendQueueLength();
Klaus Schneider380668b2019-10-02 01:21:13 -0700230 // The transport must support retrieving the current send queue length
Eric Newberryb49313d2017-12-24 20:22:27 -0700231 if (sendQueueLength < 0) {
232 return;
233 }
234
Eric Newberryb49313d2017-12-24 20:22:27 -0700235 if (sendQueueLength > 0) {
Klaus Schneider380668b2019-10-02 01:21:13 -0700236 NFD_LOG_FACE_TRACE("txqlen=" << sendQueueLength << " threshold=" <<
237 m_options.defaultCongestionThreshold << " capacity=" <<
238 getTransport()->getSendQueueCapacity());
Eric Newberryb49313d2017-12-24 20:22:27 -0700239 }
240
Klaus Schneider380668b2019-10-02 01:21:13 -0700241 // sendQueue is above target
242 if (static_cast<size_t>(sendQueueLength) > m_options.defaultCongestionThreshold) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700243 const auto now = time::steady_clock::now();
Eric Newberryb49313d2017-12-24 20:22:27 -0700244
Klaus Schneider380668b2019-10-02 01:21:13 -0700245 if (m_nextMarkTime == time::steady_clock::TimePoint::max()) {
246 m_nextMarkTime = now + m_options.baseCongestionMarkingInterval;
247 }
248 // Mark packet if sendQueue stays above target for one interval
249 else if (now >= m_nextMarkTime) {
Eric Newberryb49313d2017-12-24 20:22:27 -0700250 pkt.set<lp::CongestionMarkField>(1);
251 ++nCongestionMarked;
252 NFD_LOG_FACE_DEBUG("LpPacket was marked as congested");
253
254 ++m_nMarkedSinceInMarkingState;
255 // Decrease the marking interval by the inverse of the square root of the number of packets
256 // marked in this incident of congestion
Klaus Schneider380668b2019-10-02 01:21:13 -0700257 time::nanoseconds interval(static_cast<time::nanoseconds::rep>(
258 m_options.baseCongestionMarkingInterval.count() /
259 std::sqrt(m_nMarkedSinceInMarkingState + 1)));
260 m_nextMarkTime += interval;
Eric Newberryb49313d2017-12-24 20:22:27 -0700261 }
262 }
263 else if (m_nextMarkTime != time::steady_clock::TimePoint::max()) {
264 // Congestion incident has ended, so reset
265 NFD_LOG_FACE_DEBUG("Send queue length dropped below congestion threshold");
266 m_nextMarkTime = time::steady_clock::TimePoint::max();
267 m_nMarkedSinceInMarkingState = 0;
268 }
269}
270
271void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400272GenericLinkService::doReceivePacket(const Block& packet, const EndpointId& endpoint)
Eric Newberrya98bf932015-09-21 00:58:47 -0700273{
Eric Newberry86d31872015-09-23 16:24:59 -0700274 try {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400275 lp::Packet pkt(packet);
Eric Newberrya1939ba2015-10-09 12:35:03 -0700276
Eric Newberry185ab292017-03-28 06:45:39 +0000277 if (m_options.reliabilityOptions.isEnabled) {
Eric Newberry32f7eac2020-02-07 14:40:17 -0800278 if (!m_reliability.processIncomingPacket(pkt)) {
279 NFD_LOG_FACE_TRACE("received duplicate fragment: DROP");
280 ++this->nDuplicateSequence;
281 return;
282 }
Eric Newberry185ab292017-03-28 06:45:39 +0000283 }
284
Eric Newberrya1939ba2015-10-09 12:35:03 -0700285 if (!pkt.has<lp::FragmentField>()) {
286 NFD_LOG_FACE_TRACE("received IDLE packet: DROP");
287 return;
288 }
289
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700290 if ((pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) &&
291 !m_options.allowReassembly) {
292 NFD_LOG_FACE_WARN("received fragment, but reassembly disabled: DROP");
Eric Newberrya1939ba2015-10-09 12:35:03 -0700293 return;
294 }
295
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700296 bool isReassembled = false;
297 Block netPkt;
298 lp::Packet firstPkt;
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400299 std::tie(isReassembled, netPkt, firstPkt) = m_reassembler.receiveFragment(endpoint, pkt);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700300 if (isReassembled) {
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400301 this->decodeNetPacket(netPkt, firstPkt, endpoint);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700302 }
303 }
304 catch (const tlv::Error& e) {
305 ++this->nInLpInvalid;
306 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
307 }
308}
Eric Newberry86d31872015-09-23 16:24:59 -0700309
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700310void
ashiqopu075bb7d2019-03-10 01:38:21 +0000311GenericLinkService::decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt,
312 const EndpointId& endpointId)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700313{
314 try {
Eric Newberry86d31872015-09-23 16:24:59 -0700315 switch (netPkt.type()) {
316 case tlv::Interest:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700317 if (firstPkt.has<lp::NackField>()) {
ashiqopu075bb7d2019-03-10 01:38:21 +0000318 this->decodeNack(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700319 }
320 else {
ashiqopu075bb7d2019-03-10 01:38:21 +0000321 this->decodeInterest(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700322 }
323 break;
324 case tlv::Data:
ashiqopu075bb7d2019-03-10 01:38:21 +0000325 this->decodeData(netPkt, firstPkt, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700326 break;
327 default:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700328 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700329 NFD_LOG_FACE_WARN("unrecognized network-layer packet TLV-TYPE " << netPkt.type() << ": DROP");
330 return;
Eric Newberrya98bf932015-09-21 00:58:47 -0700331 }
332 }
Eric Newberry86d31872015-09-23 16:24:59 -0700333 catch (const tlv::Error& e) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700334 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700335 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
336 }
337}
338
Eric Newberry86d31872015-09-23 16:24:59 -0700339void
ashiqopu075bb7d2019-03-10 01:38:21 +0000340GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt,
341 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700342{
343 BOOST_ASSERT(netPkt.type() == tlv::Interest);
344 BOOST_ASSERT(!firstPkt.has<lp::NackField>());
345
346 // forwarding expects Interest to be created with make_shared
347 auto interest = make_shared<Interest>(netPkt);
348
349 if (firstPkt.has<lp::NextHopFaceIdField>()) {
350 if (m_options.allowLocalFields) {
Junxiao Shi0de23a22015-12-03 20:07:02 +0000351 interest->setTag(make_shared<lp::NextHopFaceIdTag>(firstPkt.get<lp::NextHopFaceIdField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700352 }
353 else {
354 NFD_LOG_FACE_WARN("received NextHopFaceId, but local fields disabled: DROP");
355 return;
356 }
357 }
358
359 if (firstPkt.has<lp::CachePolicyField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700360 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700361 NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
362 return;
363 }
364
365 if (firstPkt.has<lp::IncomingFaceIdField>()) {
366 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
367 }
368
Eric Newberryee400b52016-11-24 14:12:48 +0000369 if (firstPkt.has<lp::CongestionMarkField>()) {
370 interest->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
371 }
372
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700373 if (firstPkt.has<lp::NonDiscoveryField>()) {
374 if (m_options.allowSelfLearning) {
375 interest->setTag(make_shared<lp::NonDiscoveryTag>(firstPkt.get<lp::NonDiscoveryField>()));
376 }
377 else {
378 NFD_LOG_FACE_WARN("received NonDiscovery, but self-learning disabled: IGNORE");
379 }
380 }
381
382 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
383 ++this->nInNetInvalid;
384 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Interest: DROP");
385 return;
386 }
387
Junxiao Shi606d5dd2019-09-23 12:47:44 -0600388 if (firstPkt.has<lp::PitTokenField>()) {
389 interest->setTag(make_shared<lp::PitToken>(firstPkt.get<lp::PitTokenField>()));
390 }
391
ashiqopu075bb7d2019-03-10 01:38:21 +0000392 this->receiveInterest(*interest, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700393}
394
395void
ashiqopu075bb7d2019-03-10 01:38:21 +0000396GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt,
397 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700398{
399 BOOST_ASSERT(netPkt.type() == tlv::Data);
400
401 // forwarding expects Data to be created with make_shared
402 auto data = make_shared<Data>(netPkt);
403
404 if (firstPkt.has<lp::NackField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700405 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700406 NFD_LOG_FACE_WARN("received Nack with Data: DROP");
407 return;
408 }
409
410 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700411 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700412 NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
413 return;
414 }
415
416 if (firstPkt.has<lp::CachePolicyField>()) {
Junxiao Shi6eb02712017-05-27 22:48:02 +0000417 // CachePolicy is unprivileged and does not require allowLocalFields option.
418 // In case of an invalid CachePolicyType, get<lp::CachePolicyField> will throw,
419 // so it's unnecessary to check here.
420 data->setTag(make_shared<lp::CachePolicyTag>(firstPkt.get<lp::CachePolicyField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700421 }
422
423 if (firstPkt.has<lp::IncomingFaceIdField>()) {
424 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
425 }
426
Eric Newberryee400b52016-11-24 14:12:48 +0000427 if (firstPkt.has<lp::CongestionMarkField>()) {
428 data->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
429 }
430
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700431 if (firstPkt.has<lp::NonDiscoveryField>()) {
432 ++this->nInNetInvalid;
433 NFD_LOG_FACE_WARN("received NonDiscovery with Data: DROP");
434 return;
435 }
436
437 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
438 if (m_options.allowSelfLearning) {
439 data->setTag(make_shared<lp::PrefixAnnouncementTag>(firstPkt.get<lp::PrefixAnnouncementField>()));
440 }
441 else {
442 NFD_LOG_FACE_WARN("received PrefixAnnouncement, but self-learning disabled: IGNORE");
443 }
444 }
445
ashiqopu075bb7d2019-03-10 01:38:21 +0000446 this->receiveData(*data, endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700447}
448
449void
ashiqopu075bb7d2019-03-10 01:38:21 +0000450GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt,
451 const EndpointId& endpointId)
Eric Newberry86d31872015-09-23 16:24:59 -0700452{
453 BOOST_ASSERT(netPkt.type() == tlv::Interest);
454 BOOST_ASSERT(firstPkt.has<lp::NackField>());
455
456 lp::Nack nack((Interest(netPkt)));
457 nack.setHeader(firstPkt.get<lp::NackField>());
458
459 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700460 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700461 NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
462 return;
463 }
464
465 if (firstPkt.has<lp::CachePolicyField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700466 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700467 NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
468 return;
469 }
470
471 if (firstPkt.has<lp::IncomingFaceIdField>()) {
472 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
473 }
474
Eric Newberryee400b52016-11-24 14:12:48 +0000475 if (firstPkt.has<lp::CongestionMarkField>()) {
476 nack.setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
477 }
478
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700479 if (firstPkt.has<lp::NonDiscoveryField>()) {
480 ++this->nInNetInvalid;
481 NFD_LOG_FACE_WARN("received NonDiscovery with Nack: DROP");
482 return;
483 }
484
485 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
486 ++this->nInNetInvalid;
487 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Nack: DROP");
488 return;
489 }
490
ashiqopu075bb7d2019-03-10 01:38:21 +0000491 this->receiveNack(nack, endpointId);
Eric Newberrya98bf932015-09-21 00:58:47 -0700492}
493
494} // namespace face
495} // namespace nfd