blob: be216a7795e9a3a036b2ba0bea3ad92423b9762d [file] [log] [blame]
Eric Newberrya98bf932015-09-21 00:58:47 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberry41aba102017-11-01 16:42:13 -07002/*
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#ifndef NFD_DAEMON_FACE_GENERIC_LINK_SERVICE_HPP
27#define NFD_DAEMON_FACE_GENERIC_LINK_SERVICE_HPP
28
Eric Newberrya98bf932015-09-21 00:58:47 -070029#include "link-service.hpp"
Eric Newberry4c3e6b82015-11-10 16:48:42 -070030#include "lp-fragmenter.hpp"
31#include "lp-reassembler.hpp"
Eric Newberry185ab292017-03-28 06:45:39 +000032#include "lp-reliability.hpp"
Eric Newberrya98bf932015-09-21 00:58:47 -070033
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040034namespace nfd::face {
Eric Newberrya98bf932015-09-21 00:58:47 -070035
Eric Newberry4c3e6b82015-11-10 16:48:42 -070036/** \brief counters provided by GenericLinkService
37 * \note The type name 'GenericLinkServiceCounters' is implementation detail.
38 * Use 'GenericLinkService::Counters' in public API.
39 */
40class GenericLinkServiceCounters : public virtual LinkService::Counters
41{
42public:
Eric Newberry4c3e6b82015-11-10 16:48:42 -070043 /** \brief count of failed fragmentations
44 */
45 PacketCounter nFragmentationErrors;
46
47 /** \brief count of outgoing LpPackets dropped due to exceeding MTU limit
48 *
49 * If this counter is non-zero, the operator should enable fragmentation.
50 */
51 PacketCounter nOutOverMtu;
52
53 /** \brief count of invalid LpPackets dropped before reassembly
54 */
55 PacketCounter nInLpInvalid;
56
57 /** \brief count of network-layer packets currently being reassembled
58 */
59 SizeCounter<LpReassembler> nReassembling;
60
61 /** \brief count of dropped partial network-layer packets due to reassembly timeout
62 */
63 PacketCounter nReassemblyTimeouts;
64
65 /** \brief count of invalid reassembled network-layer packets dropped
66 */
67 PacketCounter nInNetInvalid;
Eric Newberry185ab292017-03-28 06:45:39 +000068
69 /** \brief count of network-layer packets that did not require retransmission of a fragment
70 */
71 PacketCounter nAcknowledged;
72
73 /** \brief count of network-layer packets that had at least one fragment retransmitted, but were
74 * eventually received in full
75 */
76 PacketCounter nRetransmitted;
77
78 /** \brief count of network-layer packets dropped because a fragment reached the maximum number
79 * of retransmissions
80 */
81 PacketCounter nRetxExhausted;
Eric Newberryb49313d2017-12-24 20:22:27 -070082
Eric Newberry32f7eac2020-02-07 14:40:17 -080083 /** \brief count of LpPackets dropped due to duplicate Sequence numbers
84 */
85 PacketCounter nDuplicateSequence;
86
Eric Newberryb49313d2017-12-24 20:22:27 -070087 /** \brief count of outgoing LpPackets that were marked with congestion marks
88 */
89 PacketCounter nCongestionMarked;
Eric Newberry4c3e6b82015-11-10 16:48:42 -070090};
91
Eric Newberry86d31872015-09-23 16:24:59 -070092/** \brief GenericLinkService is a LinkService that implements the NDNLPv2 protocol
Eric Newberry185ab292017-03-28 06:45:39 +000093 * \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
Eric Newberrya98bf932015-09-21 00:58:47 -070094 */
Davide Pesavento264af772021-02-09 21:48:24 -050095class GenericLinkService NFD_FINAL_UNLESS_WITH_TESTS : public LinkService
96 , protected virtual GenericLinkServiceCounters
Eric Newberrya98bf932015-09-21 00:58:47 -070097{
Eric Newberry86d31872015-09-23 16:24:59 -070098public:
99 /** \brief Options that control the behavior of GenericLinkService
100 */
101 class Options
102 {
103 public:
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400104 Options() noexcept
105 {
106 }
Eric Newberry86d31872015-09-23 16:24:59 -0700107
108 public:
Eric Newberry86d31872015-09-23 16:24:59 -0700109 /** \brief enables encoding of IncomingFaceId, and decoding of NextHopFaceId and CachePolicy
110 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400111 bool allowLocalFields = false;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700112
113 /** \brief enables fragmentation
114 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400115 bool allowFragmentation = false;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700116
117 /** \brief options for fragmentation
118 */
119 LpFragmenter::Options fragmenterOptions;
120
121 /** \brief enables reassembly
122 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400123 bool allowReassembly = false;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700124
125 /** \brief options for reassembly
126 */
127 LpReassembler::Options reassemblerOptions;
Eric Newberry185ab292017-03-28 06:45:39 +0000128
129 /** \brief options for reliability
130 */
131 LpReliability::Options reliabilityOptions;
Eric Newberryb49313d2017-12-24 20:22:27 -0700132
133 /** \brief enables send queue congestion detection and marking
134 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400135 bool allowCongestionMarking = false;
Eric Newberryb49313d2017-12-24 20:22:27 -0700136
137 /** \brief starting value for congestion marking interval
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400138 *
Klaus Schneider380668b2019-10-02 01:21:13 -0700139 * Packets are marked if the queue size stays above THRESHOLD for at least one INTERVAL.
140 *
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400141 * The default value (100 ms) is taken from RFC 8289 (CoDel).
Eric Newberryb49313d2017-12-24 20:22:27 -0700142 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400143 time::nanoseconds baseCongestionMarkingInterval = 100_ms;
Eric Newberryb49313d2017-12-24 20:22:27 -0700144
145 /** \brief default congestion threshold in bytes
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400146 *
Klaus Schneider380668b2019-10-02 01:21:13 -0700147 * Packets are marked if the queue size stays above THRESHOLD for at least one INTERVAL.
148 *
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400149 * The default value (64 KiB) works well for a queue capacity of 200 KiB.
Eric Newberryb49313d2017-12-24 20:22:27 -0700150 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400151 size_t defaultCongestionThreshold = 65536;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700152
153 /** \brief enables self-learning forwarding support
154 */
Teng Liang39465c22018-11-12 19:43:04 -0700155 bool allowSelfLearning = true;
Eric Newberrycb6551e2020-03-02 14:12:16 -0800156
157 /** \brief overrides MTU provided by Transport
158 *
159 * This MTU value will be used instead of the MTU provided by the transport if it is less than
160 * the transport MTU. However, it will not be utilized when the transport MTU is unlimited.
161 *
162 * Acceptable values for the override MTU are values >= MIN_MTU, which can be validated before
163 * being set with canOverrideMtuTo().
164 */
165 ssize_t overrideMtu = std::numeric_limits<ssize_t>::max();
Eric Newberry86d31872015-09-23 16:24:59 -0700166 };
167
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700168 /** \brief counters provided by GenericLinkService
169 */
Junxiao Shifab9e0d2017-02-02 06:04:59 +0000170 using Counters = GenericLinkServiceCounters;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700171
Eric Newberry86d31872015-09-23 16:24:59 -0700172 explicit
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400173 GenericLinkService(const Options& options = {});
Eric Newberry86d31872015-09-23 16:24:59 -0700174
175 /** \brief get Options used by GenericLinkService
176 */
177 const Options&
178 getOptions() const;
179
180 /** \brief sets Options used by GenericLinkService
181 */
182 void
183 setOptions(const Options& options);
184
Junxiao Shifab9e0d2017-02-02 06:04:59 +0000185 const Counters&
Davide Pesavento264af772021-02-09 21:48:24 -0500186 getCounters() const NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700187
Eric Newberrycb6551e2020-03-02 14:12:16 -0800188 ssize_t
Davide Pesavento264af772021-02-09 21:48:24 -0500189 getEffectiveMtu() const NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL;
Eric Newberrycb6551e2020-03-02 14:12:16 -0800190
191 /** \brief Whether MTU can be overridden to the specified value
192 *
193 * If the transport MTU is unlimited, then this will always return false.
194 */
195 bool
196 canOverrideMtuTo(ssize_t mtu) const;
197
Davide Pesavento264af772021-02-09 21:48:24 -0500198NFD_PROTECTED_WITH_TESTS_ELSE_PRIVATE: // send path
Eric Newberry185ab292017-03-28 06:45:39 +0000199 /** \brief request an IDLE packet to transmit pending service fields
200 */
201 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700202 requestIdlePacket();
Eric Newberry185ab292017-03-28 06:45:39 +0000203
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700204 /** \brief send an LpPacket
Eric Newberry185ab292017-03-28 06:45:39 +0000205 */
206 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700207 sendLpPacket(lp::Packet&& pkt);
Eric Newberry185ab292017-03-28 06:45:39 +0000208
Eric Newberrya98bf932015-09-21 00:58:47 -0700209 void
Davide Pesavento264af772021-02-09 21:48:24 -0500210 doSendInterest(const Interest& interest) NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL;
Eric Newberrya98bf932015-09-21 00:58:47 -0700211
Eric Newberrya98bf932015-09-21 00:58:47 -0700212 void
Davide Pesavento264af772021-02-09 21:48:24 -0500213 doSendData(const Data& data) NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL;
Eric Newberrya98bf932015-09-21 00:58:47 -0700214
Eric Newberrya98bf932015-09-21 00:58:47 -0700215 void
Davide Pesavento264af772021-02-09 21:48:24 -0500216 doSendNack(const ndn::lp::Nack& nack) NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL;
Eric Newberrya98bf932015-09-21 00:58:47 -0700217
Eric Newberry32f7eac2020-02-07 14:40:17 -0800218 /** \brief assign consecutive sequence numbers to LpPackets
219 */
220 void
221 assignSequences(std::vector<lp::Packet>& pkts);
222
Eric Newberry185ab292017-03-28 06:45:39 +0000223private: // send path
Eric Newberryee400b52016-11-24 14:12:48 +0000224 /** \brief encode link protocol fields from tags onto an outgoing LpPacket
225 * \param netPkt network-layer packet to extract tags from
226 * \param lpPacket LpPacket to add link protocol fields to
Eric Newberry86d31872015-09-23 16:24:59 -0700227 */
Eric Newberryee400b52016-11-24 14:12:48 +0000228 void
Eric Newberry41aba102017-11-01 16:42:13 -0700229 encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket);
Eric Newberry86d31872015-09-23 16:24:59 -0700230
Junxiao Shi0de23a22015-12-03 20:07:02 +0000231 /** \brief send a complete network layer packet
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700232 * \param pkt LpPacket containing a complete network layer packet
Eric Newberry41aba102017-11-01 16:42:13 -0700233 * \param isInterest whether the network layer packet is an Interest
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700234 */
235 void
Teng Liangf3bc3ae2020-06-08 10:19:25 -0700236 sendNetPacket(lp::Packet&& pkt, bool isInterest);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700237
Eric Newberryb49313d2017-12-24 20:22:27 -0700238 /** \brief if the send queue is found to be congested, add a congestion mark to the packet
239 * according to CoDel
240 * \sa https://tools.ietf.org/html/rfc8289
241 */
242 void
243 checkCongestionLevel(lp::Packet& pkt);
244
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700245private: // receive path
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700246 void
Davide Pesavento264af772021-02-09 21:48:24 -0500247 doReceivePacket(const Block& packet, const EndpointId& endpoint) NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700248
249 /** \brief decode incoming network-layer packet
250 * \param netPkt reassembled network-layer packet
251 * \param firstPkt LpPacket of first fragment
ashiqopu075bb7d2019-03-10 01:38:21 +0000252 * \param endpointId endpoint of peer who sent the packet
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700253 *
254 * If decoding is successful, a receive signal is emitted;
255 * otherwise, a warning is logged.
256 */
257 void
ashiqopu075bb7d2019-03-10 01:38:21 +0000258 decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700259
Eric Newberry86d31872015-09-23 16:24:59 -0700260 /** \brief decode incoming Interest
261 * \param netPkt reassembled network-layer packet; TLV-TYPE must be Interest
262 * \param firstPkt LpPacket of first fragment; must not have Nack field
ashiqopu075bb7d2019-03-10 01:38:21 +0000263 * \param endpointId endpoint of peer who sent the Interest
Eric Newberry86d31872015-09-23 16:24:59 -0700264 *
265 * If decoding is successful, receiveInterest signal is emitted;
266 * otherwise, a warning is logged.
267 *
268 * \throw tlv::Error parse error in an LpHeader field
269 */
270 void
ashiqopu075bb7d2019-03-10 01:38:21 +0000271 decodeInterest(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700272
273 /** \brief decode incoming Interest
274 * \param netPkt reassembled network-layer packet; TLV-TYPE must be Data
275 * \param firstPkt LpPacket of first fragment
ashiqopu075bb7d2019-03-10 01:38:21 +0000276 * \param endpointId endpoint of peer who sent the Data
Eric Newberry86d31872015-09-23 16:24:59 -0700277 *
278 * If decoding is successful, receiveData signal is emitted;
279 * otherwise, a warning is logged.
280 *
281 * \throw tlv::Error parse error in an LpHeader field
282 */
283 void
ashiqopu075bb7d2019-03-10 01:38:21 +0000284 decodeData(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700285
286 /** \brief decode incoming Interest
287 * \param netPkt reassembled network-layer packet; TLV-TYPE must be Interest
288 * \param firstPkt LpPacket of first fragment; must have Nack field
ashiqopu075bb7d2019-03-10 01:38:21 +0000289 * \param endpointId endpoint of peer who sent the Nack
Eric Newberry86d31872015-09-23 16:24:59 -0700290 *
291 * If decoding is successful, receiveNack signal is emitted;
292 * otherwise, a warning is logged.
293 *
294 * \throw tlv::Error parse error in an LpHeader field
295 */
296 void
ashiqopu075bb7d2019-03-10 01:38:21 +0000297 decodeNack(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
Eric Newberry86d31872015-09-23 16:24:59 -0700298
Davide Pesavento264af772021-02-09 21:48:24 -0500299NFD_PROTECTED_WITH_TESTS_ELSE_PRIVATE:
Eric Newberry86d31872015-09-23 16:24:59 -0700300 Options m_options;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700301 LpFragmenter m_fragmenter;
302 LpReassembler m_reassembler;
Eric Newberry185ab292017-03-28 06:45:39 +0000303 LpReliability m_reliability;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700304 lp::Sequence m_lastSeqNo;
Eric Newberry185ab292017-03-28 06:45:39 +0000305
Davide Pesavento264af772021-02-09 21:48:24 -0500306NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Eric Newberryb49313d2017-12-24 20:22:27 -0700307 /// Time to mark next packet due to send queue congestion
308 time::steady_clock::TimePoint m_nextMarkTime;
Eric Newberryb49313d2017-12-24 20:22:27 -0700309 /// number of marked packets in the current incident of congestion
310 size_t m_nMarkedSinceInMarkingState;
311
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400312 friend LpReliability;
Eric Newberrya98bf932015-09-21 00:58:47 -0700313};
314
Eric Newberry86d31872015-09-23 16:24:59 -0700315inline const GenericLinkService::Options&
316GenericLinkService::getOptions() const
317{
318 return m_options;
319}
320
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700321inline const GenericLinkService::Counters&
322GenericLinkService::getCounters() const
323{
324 return *this;
325}
326
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400327} // namespace nfd::face
Eric Newberrya98bf932015-09-21 00:58:47 -0700328
Eric Newberry86d31872015-09-23 16:24:59 -0700329#endif // NFD_DAEMON_FACE_GENERIC_LINK_SERVICE_HPP