blob: c8eea37ac85c2e5f267bc5a18fa6566f4a326495 [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/*
Eric Newberryb49313d2017-12-24 20:22:27 -07003 * Copyright (c) 2014-2018, 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
34namespace nfd {
35namespace face {
36
Eric Newberry4c3e6b82015-11-10 16:48:42 -070037/** \brief counters provided by GenericLinkService
38 * \note The type name 'GenericLinkServiceCounters' is implementation detail.
39 * Use 'GenericLinkService::Counters' in public API.
40 */
41class GenericLinkServiceCounters : public virtual LinkService::Counters
42{
43public:
Eric Newberry4c3e6b82015-11-10 16:48:42 -070044 /** \brief count of failed fragmentations
45 */
46 PacketCounter nFragmentationErrors;
47
48 /** \brief count of outgoing LpPackets dropped due to exceeding MTU limit
49 *
50 * If this counter is non-zero, the operator should enable fragmentation.
51 */
52 PacketCounter nOutOverMtu;
53
54 /** \brief count of invalid LpPackets dropped before reassembly
55 */
56 PacketCounter nInLpInvalid;
57
58 /** \brief count of network-layer packets currently being reassembled
59 */
60 SizeCounter<LpReassembler> nReassembling;
61
62 /** \brief count of dropped partial network-layer packets due to reassembly timeout
63 */
64 PacketCounter nReassemblyTimeouts;
65
66 /** \brief count of invalid reassembled network-layer packets dropped
67 */
68 PacketCounter nInNetInvalid;
Eric Newberry185ab292017-03-28 06:45:39 +000069
70 /** \brief count of network-layer packets that did not require retransmission of a fragment
71 */
72 PacketCounter nAcknowledged;
73
74 /** \brief count of network-layer packets that had at least one fragment retransmitted, but were
75 * eventually received in full
76 */
77 PacketCounter nRetransmitted;
78
79 /** \brief count of network-layer packets dropped because a fragment reached the maximum number
80 * of retransmissions
81 */
82 PacketCounter nRetxExhausted;
Eric Newberryb49313d2017-12-24 20:22:27 -070083
84 /** \brief count of outgoing LpPackets that were marked with congestion marks
85 */
86 PacketCounter nCongestionMarked;
Eric Newberry4c3e6b82015-11-10 16:48:42 -070087};
88
Eric Newberry86d31872015-09-23 16:24:59 -070089/** \brief GenericLinkService is a LinkService that implements the NDNLPv2 protocol
Eric Newberry185ab292017-03-28 06:45:39 +000090 * \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
Eric Newberrya98bf932015-09-21 00:58:47 -070091 */
92class GenericLinkService : public LinkService
Eric Newberry73bcad32017-04-25 17:57:35 -070093 , protected virtual GenericLinkServiceCounters
Eric Newberrya98bf932015-09-21 00:58:47 -070094{
Eric Newberry86d31872015-09-23 16:24:59 -070095public:
96 /** \brief Options that control the behavior of GenericLinkService
97 */
98 class Options
99 {
100 public:
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400101 constexpr
102 Options() noexcept
103 {
104 }
Eric Newberry86d31872015-09-23 16:24:59 -0700105
106 public:
Eric Newberry86d31872015-09-23 16:24:59 -0700107 /** \brief enables encoding of IncomingFaceId, and decoding of NextHopFaceId and CachePolicy
108 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400109 bool allowLocalFields = false;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700110
111 /** \brief enables fragmentation
112 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400113 bool allowFragmentation = false;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700114
115 /** \brief options for fragmentation
116 */
117 LpFragmenter::Options fragmenterOptions;
118
119 /** \brief enables reassembly
120 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400121 bool allowReassembly = false;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700122
123 /** \brief options for reassembly
124 */
125 LpReassembler::Options reassemblerOptions;
Eric Newberry185ab292017-03-28 06:45:39 +0000126
127 /** \brief options for reliability
128 */
129 LpReliability::Options reliabilityOptions;
Eric Newberryb49313d2017-12-24 20:22:27 -0700130
131 /** \brief enables send queue congestion detection and marking
132 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400133 bool allowCongestionMarking = false;
Eric Newberryb49313d2017-12-24 20:22:27 -0700134
135 /** \brief starting value for congestion marking interval
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400136 *
137 * The default value (100 ms) is taken from RFC 8289 (CoDel).
Eric Newberryb49313d2017-12-24 20:22:27 -0700138 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400139 time::nanoseconds baseCongestionMarkingInterval = 100_ms;
Eric Newberryb49313d2017-12-24 20:22:27 -0700140
141 /** \brief default congestion threshold in bytes
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400142 *
143 * The default value (64 KiB) works well for a queue capacity of 200 KiB.
Eric Newberryb49313d2017-12-24 20:22:27 -0700144 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400145 size_t defaultCongestionThreshold = 65536;
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700146
147 /** \brief enables self-learning forwarding support
148 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400149 bool allowSelfLearning = false;
Eric Newberry86d31872015-09-23 16:24:59 -0700150 };
151
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700152 /** \brief counters provided by GenericLinkService
153 */
Junxiao Shifab9e0d2017-02-02 06:04:59 +0000154 using Counters = GenericLinkServiceCounters;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700155
Eric Newberry86d31872015-09-23 16:24:59 -0700156 explicit
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400157 GenericLinkService(const Options& options = {});
Eric Newberry86d31872015-09-23 16:24:59 -0700158
159 /** \brief get Options used by GenericLinkService
160 */
161 const Options&
162 getOptions() const;
163
164 /** \brief sets Options used by GenericLinkService
165 */
166 void
167 setOptions(const Options& options);
168
Junxiao Shifab9e0d2017-02-02 06:04:59 +0000169 const Counters&
Davide Pesaventob84bd3a2016-04-22 02:21:45 +0200170 getCounters() const override;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700171
Junxiao Shifab9e0d2017-02-02 06:04:59 +0000172PROTECTED_WITH_TESTS_ELSE_PRIVATE: // send path
Eric Newberry185ab292017-03-28 06:45:39 +0000173 /** \brief request an IDLE packet to transmit pending service fields
174 */
175 void
176 requestIdlePacket();
177
178 /** \brief send an LpPacket fragment
179 * \param pkt LpPacket to send
180 */
181 void
182 sendLpPacket(lp::Packet&& pkt);
183
Junxiao Shi0de23a22015-12-03 20:07:02 +0000184 /** \brief send Interest
Eric Newberrya98bf932015-09-21 00:58:47 -0700185 */
186 void
Davide Pesaventob84bd3a2016-04-22 02:21:45 +0200187 doSendInterest(const Interest& interest) override;
Eric Newberrya98bf932015-09-21 00:58:47 -0700188
Junxiao Shi0de23a22015-12-03 20:07:02 +0000189 /** \brief send Data
Eric Newberrya98bf932015-09-21 00:58:47 -0700190 */
191 void
Davide Pesaventob84bd3a2016-04-22 02:21:45 +0200192 doSendData(const Data& data) override;
Eric Newberrya98bf932015-09-21 00:58:47 -0700193
Junxiao Shi0de23a22015-12-03 20:07:02 +0000194 /** \brief send Nack
Eric Newberrya98bf932015-09-21 00:58:47 -0700195 */
196 void
Davide Pesaventob84bd3a2016-04-22 02:21:45 +0200197 doSendNack(const ndn::lp::Nack& nack) override;
Eric Newberrya98bf932015-09-21 00:58:47 -0700198
Eric Newberry185ab292017-03-28 06:45:39 +0000199private: // send path
Eric Newberryee400b52016-11-24 14:12:48 +0000200 /** \brief encode link protocol fields from tags onto an outgoing LpPacket
201 * \param netPkt network-layer packet to extract tags from
202 * \param lpPacket LpPacket to add link protocol fields to
Eric Newberry86d31872015-09-23 16:24:59 -0700203 */
Eric Newberryee400b52016-11-24 14:12:48 +0000204 void
Eric Newberry41aba102017-11-01 16:42:13 -0700205 encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket);
Eric Newberry86d31872015-09-23 16:24:59 -0700206
Junxiao Shi0de23a22015-12-03 20:07:02 +0000207 /** \brief send a complete network layer packet
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700208 * \param pkt LpPacket containing a complete network layer packet
Eric Newberry41aba102017-11-01 16:42:13 -0700209 * \param isInterest whether the network layer packet is an Interest
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700210 */
211 void
Eric Newberry41aba102017-11-01 16:42:13 -0700212 sendNetPacket(lp::Packet&& pkt, bool isInterest);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700213
214 /** \brief assign a sequence number to an LpPacket
215 */
216 void
217 assignSequence(lp::Packet& pkt);
218
219 /** \brief assign consecutive sequence numbers to LpPackets
220 */
221 void
222 assignSequences(std::vector<lp::Packet>& pkts);
223
Eric Newberryb49313d2017-12-24 20:22:27 -0700224 /** \brief if the send queue is found to be congested, add a congestion mark to the packet
225 * according to CoDel
226 * \sa https://tools.ietf.org/html/rfc8289
227 */
228 void
229 checkCongestionLevel(lp::Packet& pkt);
230
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700231private: // receive path
232 /** \brief receive Packet from Transport
233 */
234 void
Davide Pesaventob84bd3a2016-04-22 02:21:45 +0200235 doReceivePacket(Transport::Packet&& packet) override;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700236
237 /** \brief decode incoming network-layer packet
238 * \param netPkt reassembled network-layer packet
239 * \param firstPkt LpPacket of first fragment
240 *
241 * If decoding is successful, a receive signal is emitted;
242 * otherwise, a warning is logged.
243 */
244 void
245 decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt);
246
Eric Newberry86d31872015-09-23 16:24:59 -0700247 /** \brief decode incoming Interest
248 * \param netPkt reassembled network-layer packet; TLV-TYPE must be Interest
249 * \param firstPkt LpPacket of first fragment; must not have Nack field
250 *
251 * If decoding is successful, receiveInterest signal is emitted;
252 * otherwise, a warning is logged.
253 *
254 * \throw tlv::Error parse error in an LpHeader field
255 */
256 void
257 decodeInterest(const Block& netPkt, const lp::Packet& firstPkt);
258
259 /** \brief decode incoming Interest
260 * \param netPkt reassembled network-layer packet; TLV-TYPE must be Data
261 * \param firstPkt LpPacket of first fragment
262 *
263 * If decoding is successful, receiveData signal is emitted;
264 * otherwise, a warning is logged.
265 *
266 * \throw tlv::Error parse error in an LpHeader field
267 */
268 void
269 decodeData(const Block& netPkt, const lp::Packet& firstPkt);
270
271 /** \brief decode incoming Interest
272 * \param netPkt reassembled network-layer packet; TLV-TYPE must be Interest
273 * \param firstPkt LpPacket of first fragment; must have Nack field
274 *
275 * If decoding is successful, receiveNack signal is emitted;
276 * otherwise, a warning is logged.
277 *
278 * \throw tlv::Error parse error in an LpHeader field
279 */
280 void
281 decodeNack(const Block& netPkt, const lp::Packet& firstPkt);
282
Eric Newberry185ab292017-03-28 06:45:39 +0000283PROTECTED_WITH_TESTS_ELSE_PRIVATE:
Eric Newberry86d31872015-09-23 16:24:59 -0700284 Options m_options;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700285 LpFragmenter m_fragmenter;
286 LpReassembler m_reassembler;
Eric Newberry185ab292017-03-28 06:45:39 +0000287 LpReliability m_reliability;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700288 lp::Sequence m_lastSeqNo;
Eric Newberry185ab292017-03-28 06:45:39 +0000289
Eric Newberryb49313d2017-12-24 20:22:27 -0700290PUBLIC_WITH_TESTS_ELSE_PRIVATE:
291 /// CongestionMark TLV-TYPE (3 octets) + CongestionMark TLV-LENGTH (1 octet) + sizeof(uint64_t)
292 static constexpr size_t CONGESTION_MARK_SIZE = 3 + 1 + sizeof(uint64_t);
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400293
Eric Newberryb49313d2017-12-24 20:22:27 -0700294 /// Time to mark next packet due to send queue congestion
295 time::steady_clock::TimePoint m_nextMarkTime;
296 /// Time last packet was marked
297 time::steady_clock::TimePoint m_lastMarkTime;
298 /// number of marked packets in the current incident of congestion
299 size_t m_nMarkedSinceInMarkingState;
300
Eric Newberry185ab292017-03-28 06:45:39 +0000301 friend class LpReliability;
Eric Newberrya98bf932015-09-21 00:58:47 -0700302};
303
Eric Newberry86d31872015-09-23 16:24:59 -0700304inline const GenericLinkService::Options&
305GenericLinkService::getOptions() const
306{
307 return m_options;
308}
309
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700310inline const GenericLinkService::Counters&
311GenericLinkService::getCounters() const
312{
313 return *this;
314}
315
Eric Newberrya98bf932015-09-21 00:58:47 -0700316} // namespace face
317} // namespace nfd
318
Eric Newberry86d31872015-09-23 16:24:59 -0700319#endif // NFD_DAEMON_FACE_GENERIC_LINK_SERVICE_HPP