blob: 8bbfe868f24af110209f5e6a5dcdec447d6ff6b9 [file] [log] [blame]
Eric Newberrya98bf932015-09-21 00:58:47 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberryb49313d2017-12-24 20:22:27 -07002/*
ashiqopu77d0bfd2019-02-20 20:37:31 +00003 * 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#ifndef NFD_DAEMON_FACE_TRANSPORT_HPP
27#define NFD_DAEMON_FACE_TRANSPORT_HPP
28
Junxiao Shida93f1f2015-11-11 06:13:16 -070029#include "core/counter.hpp"
Eric Newberrya98bf932015-09-21 00:58:47 -070030#include "face-log.hpp"
Eric Newberryb49313d2017-12-24 20:22:27 -070031
Junxiao Shi0de23a22015-12-03 20:07:02 +000032#include <ndn-cxx/encoding/nfd-constants.hpp>
Eric Newberrya98bf932015-09-21 00:58:47 -070033
34namespace nfd {
35namespace face {
36
Junxiao Shicde37ad2015-12-24 01:02:05 -070037class Face;
Eric Newberrya98bf932015-09-21 00:58:47 -070038class LinkService;
39
ashiqopu77d0bfd2019-02-20 20:37:31 +000040/** \brief identifies an endpoint on the link
41 */
42typedef uint64_t EndpointId;
43
Eric Newberrya98bf932015-09-21 00:58:47 -070044/** \brief indicates the state of a transport
45 */
46enum class TransportState {
47 NONE,
Davide Pesavento68ab43d2017-07-02 13:37:35 -040048 UP, ///< the transport is up and can transmit packets
49 DOWN, ///< the transport is temporarily down, and is being recovered
50 CLOSING, ///< the transport is being closed gracefully, either by the peer or by a call to close()
Eric Newberrya98bf932015-09-21 00:58:47 -070051 FAILED, ///< the transport is being closed due to a failure
52 CLOSED ///< the transport is closed, and can be safely deallocated
53};
54
55std::ostream&
56operator<<(std::ostream& os, TransportState state);
57
Junxiao Shi57df2882015-11-11 06:12:35 -070058/** \brief counters provided by Transport
59 * \note The type name 'TransportCounters' is implementation detail.
60 * Use 'Transport::Counters' in public API.
61 */
62class TransportCounters
63{
64public:
65 /** \brief count of incoming packets
66 *
67 * A 'packet' typically means a top-level TLV block.
68 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
69 * would not be counted.
70 */
71 PacketCounter nInPackets;
72
73 /** \brief count of outgoing packets
74 *
75 * A 'packet' typically means a top-level TLV block.
76 * This counter is incremented only if transport is UP.
77 */
78 PacketCounter nOutPackets;
79
80 /** \brief total incoming bytes
81 *
82 * This counter includes headers imposed by NFD (such as NDNLP),
83 * but excludes overhead of underlying protocol (such as IP header).
84 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
85 * would not be counted.
86 */
87 ByteCounter nInBytes;
88
89 /** \brief total outgoing bytes
90 *
91 * This counter includes headers imposed by NFD (such as NDNLP),
92 * but excludes overhead of underlying protocol (such as IP header).
93 * This counter is increased only if transport is UP.
94 */
95 ByteCounter nOutBytes;
96};
97
Junxiao Shi13546112015-10-14 19:33:07 -070098/** \brief indicates the transport has no limit on payload size
99 */
100const ssize_t MTU_UNLIMITED = -1;
101
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700102/** \brief (for internal use) indicates MTU field is unset
103 */
104const ssize_t MTU_INVALID = -2;
105
Eric Newberryb49313d2017-12-24 20:22:27 -0700106/** \brief indicates that the transport does not support reading the queue capacity/length
107 */
108const ssize_t QUEUE_UNSUPPORTED = -1;
109
110/** \brief indicates that the transport was unable to retrieve the queue capacity/length
111 */
112const ssize_t QUEUE_ERROR = -2;
113
Junxiao Shicde37ad2015-12-24 01:02:05 -0700114/** \brief the lower part of a Face
115 * \sa Face
Eric Newberrya98bf932015-09-21 00:58:47 -0700116 */
Junxiao Shi57df2882015-11-11 06:12:35 -0700117class Transport : protected virtual TransportCounters, noncopyable
Eric Newberrya98bf932015-09-21 00:58:47 -0700118{
119public:
Eric Newberrya98bf932015-09-21 00:58:47 -0700120 /** \brief stores a packet along with the remote endpoint
121 */
122 class Packet
123 {
124 public:
125 Packet() = default;
126
127 explicit
128 Packet(Block&& packet);
129
130 public:
131 /** \brief the packet as a TLV block
132 */
133 Block packet;
134
135 /** \brief identifies the remote endpoint
136 *
137 * This ID is only meaningful in the context of the same Transport.
138 * Incoming packets from the same remote endpoint have the same EndpointId,
139 * and incoming packets from different remote endpoints have different EndpointIds.
140 */
141 EndpointId remoteEndpoint;
142 };
143
Junxiao Shi57df2882015-11-11 06:12:35 -0700144 /** \brief counters provided by Transport
145 */
146 typedef TransportCounters Counters;
147
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700148 /** \brief constructor
149 *
150 * Transport constructor initializes static properties to invalid values.
151 * Subclass constructor must explicitly set every static property.
152 *
153 * This constructor initializes TransportState to UP;
154 * subclass constructor can rely on this default value.
155 */
Eric Newberrya98bf932015-09-21 00:58:47 -0700156 Transport();
157
158 virtual
159 ~Transport();
160
161public:
162 /** \brief set Face and LinkService for Transport
163 * \pre setFaceAndLinkService has not been called
164 */
165 void
Junxiao Shicde37ad2015-12-24 01:02:05 -0700166 setFaceAndLinkService(Face& face, LinkService& service);
Eric Newberrya98bf932015-09-21 00:58:47 -0700167
168 /** \return Face to which this Transport is attached
169 */
Junxiao Shicde37ad2015-12-24 01:02:05 -0700170 const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700171 getFace() const;
172
173 /** \return LinkService to which this Transport is attached
174 */
175 const LinkService*
176 getLinkService() const;
177
178 /** \return LinkService to which this Transport is attached
179 */
180 LinkService*
181 getLinkService();
182
Junxiao Shi57df2882015-11-11 06:12:35 -0700183 virtual const Counters&
184 getCounters() const;
185
Eric Newberrya98bf932015-09-21 00:58:47 -0700186public: // upper interface
187 /** \brief request the transport to be closed
188 *
189 * This operation is effective only if transport is in UP or DOWN state,
190 * otherwise it has no effect.
191 * The transport changes state to CLOSING, and performs cleanup procedure.
192 * The state will be changed to CLOSED when cleanup is complete, which may
193 * happen synchronously or asynchronously.
194 */
195 void
196 close();
197
198 /** \brief send a link-layer packet
Junxiao Shi13546112015-10-14 19:33:07 -0700199 * \note This operation has no effect if \p getState() is neither UP nor DOWN
200 * \warning undefined behavior if packet size exceeds MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700201 */
202 void
203 send(Packet&& packet);
204
Eric Newberrya98bf932015-09-21 00:58:47 -0700205public: // static properties
206 /** \return a FaceUri representing local endpoint
207 */
208 FaceUri
209 getLocalUri() const;
210
211 /** \return a FaceUri representing remote endpoint
212 */
213 FaceUri
214 getRemoteUri() const;
215
216 /** \return whether face is local or non-local for scope control purpose
217 */
218 ndn::nfd::FaceScope
219 getScope() const;
220
221 /** \return face persistency setting
222 */
223 ndn::nfd::FacePersistency
224 getPersistency() const;
225
Davide Pesavento32065652017-01-15 01:52:21 -0500226 /** \brief check whether the face persistency can be changed to \p newPersistency
Yanbiao Li32dab972016-11-27 12:26:09 +0800227 *
Davide Pesavento32065652017-01-15 01:52:21 -0500228 * This function serves as the external API, and invokes the protected function
229 * canChangePersistencyToImpl to perform further checks if \p newPersistency differs
230 * from the current persistency.
Yanbiao Li32dab972016-11-27 12:26:09 +0800231 *
Davide Pesavento32065652017-01-15 01:52:21 -0500232 * \return true if the change can be performed, false otherwise
Yanbiao Li32dab972016-11-27 12:26:09 +0800233 */
234 bool
235 canChangePersistencyTo(ndn::nfd::FacePersistency newPersistency) const;
236
Eric Newberrya98bf932015-09-21 00:58:47 -0700237 /** \brief changes face persistency setting
238 */
239 void
Davide Pesavento32065652017-01-15 01:52:21 -0500240 setPersistency(ndn::nfd::FacePersistency newPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700241
242 /** \return whether face is point-to-point or multi-access
243 */
244 ndn::nfd::LinkType
245 getLinkType() const;
246
Junxiao Shi13546112015-10-14 19:33:07 -0700247 /** \return maximum payload size
248 * \retval MTU_UNLIMITED transport has no limit on payload size
249 *
250 * This size is the maximum packet size that can be sent or received through this transport.
251 *
252 * For a datagram-based transport, this is typically the Maximum Transmission Unit (MTU),
253 * after the overhead of headers introduced by the transport has been accounted for.
254 * For a stream-based transport, this is typically unlimited (MTU_UNLIMITED).
255 */
256 ssize_t
257 getMtu() const;
258
Eric Newberryb49313d2017-12-24 20:22:27 -0700259 /** \return capacity of the send queue (in bytes)
260 * \retval QUEUE_UNSUPPORTED transport does not support queue capacity retrieval
261 * \retval QUEUE_ERROR transport was unable to retrieve the queue capacity
262 */
263 ssize_t
264 getSendQueueCapacity() const;
265
Eric Newberrya98bf932015-09-21 00:58:47 -0700266public: // dynamic properties
267 /** \return transport state
268 */
269 TransportState
270 getState() const;
271
272 /** \brief signals when transport state changes
273 */
274 signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;
275
Eric Newberryc64d30a2015-12-26 11:07:27 -0700276 /** \return expiration time of the transport
277 * \retval time::steady_clock::TimePoint::max() the transport has indefinite lifetime
278 */
279 time::steady_clock::TimePoint
280 getExpirationTime() const;
281
Eric Newberryb49313d2017-12-24 20:22:27 -0700282 /** \return current send queue length of the transport (in octets)
283 * \retval QUEUE_UNSUPPORTED transport does not support queue length retrieval
284 * \retval QUEUE_ERROR transport was unable to retrieve the queue length
285 */
286 virtual ssize_t
Eric Newberry812d6152018-06-06 15:06:01 -0700287 getSendQueueLength()
288 {
289 return QUEUE_UNSUPPORTED;
290 }
291
292protected: // upper interface to be invoked by subclass
293 /** \brief receive a link-layer packet
294 * \warning undefined behavior if packet size exceeds MTU limit
295 */
296 void
297 receive(Packet&& packet);
Eric Newberryb49313d2017-12-24 20:22:27 -0700298
Eric Newberrya98bf932015-09-21 00:58:47 -0700299protected: // properties to be set by subclass
300 void
301 setLocalUri(const FaceUri& uri);
302
303 void
304 setRemoteUri(const FaceUri& uri);
305
306 void
307 setScope(ndn::nfd::FaceScope scope);
308
309 void
310 setLinkType(ndn::nfd::LinkType linkType);
311
Junxiao Shi13546112015-10-14 19:33:07 -0700312 void
313 setMtu(ssize_t mtu);
314
Eric Newberryb49313d2017-12-24 20:22:27 -0700315 void
316 setSendQueueCapacity(ssize_t sendQueueCapacity);
317
Eric Newberrya98bf932015-09-21 00:58:47 -0700318 /** \brief set transport state
319 *
320 * Only the following transitions are valid:
321 * UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
322 *
323 * \throw std::runtime_error transition is invalid.
324 */
325 void
326 setState(TransportState newState);
327
Eric Newberryc64d30a2015-12-26 11:07:27 -0700328 void
329 setExpirationTime(const time::steady_clock::TimePoint& expirationTime);
330
Eric Newberrya98bf932015-09-21 00:58:47 -0700331protected: // to be overridden by subclass
Yanbiao Li32dab972016-11-27 12:26:09 +0800332 /** \brief invoked by canChangePersistencyTo to perform the check
333 *
334 * Base class implementation returns false.
335 *
336 * \param newPersistency the new persistency, guaranteed to be different from current persistency
337 */
338 virtual bool
339 canChangePersistencyToImpl(ndn::nfd::FacePersistency newPersistency) const;
340
341 /** \brief invoked after the persistency has been changed
342 *
343 * The base class implementation does nothing.
344 * When overridden in a subclass, the function should update internal states
345 * after persistency setting has been changed.
Eric Newberrya98bf932015-09-21 00:58:47 -0700346 */
347 virtual void
Yanbiao Li32dab972016-11-27 12:26:09 +0800348 afterChangePersistency(ndn::nfd::FacePersistency oldPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700349
350 /** \brief performs Transport specific operations to close the transport
351 *
Junxiao Shi13546112015-10-14 19:33:07 -0700352 * This is invoked once by \p close() after changing state to CLOSING.
353 * It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
354 *
Eric Newberrya98bf932015-09-21 00:58:47 -0700355 * When the cleanup procedure is complete, this method should change state to CLOSED.
Junxiao Shi13546112015-10-14 19:33:07 -0700356 * This transition can happen synchronously or asynchronously.
Eric Newberrya98bf932015-09-21 00:58:47 -0700357 */
358 virtual void
359 doClose() = 0;
360
361private: // to be overridden by subclass
362 /** \brief performs Transport specific operations to send a packet
363 * \param packet the packet, which must be a well-formed TLV block
Junxiao Shi13546112015-10-14 19:33:07 -0700364 * \pre state is either UP or DOWN
Eric Newberrya98bf932015-09-21 00:58:47 -0700365 */
366 virtual void
367 doSend(Packet&& packet) = 0;
368
Eric Newberry812d6152018-06-06 15:06:01 -0700369public:
370 /** \brief minimum MTU that may be set on a transport
371 *
372 * This is done to ensure the NDNLPv2 fragmentation feature functions properly.
373 */
374 static constexpr ssize_t MIN_MTU = 64;
375
Eric Newberrya98bf932015-09-21 00:58:47 -0700376private:
Junxiao Shicde37ad2015-12-24 01:02:05 -0700377 Face* m_face;
Eric Newberrya98bf932015-09-21 00:58:47 -0700378 LinkService* m_service;
379 FaceUri m_localUri;
380 FaceUri m_remoteUri;
381 ndn::nfd::FaceScope m_scope;
382 ndn::nfd::FacePersistency m_persistency;
383 ndn::nfd::LinkType m_linkType;
Junxiao Shi13546112015-10-14 19:33:07 -0700384 ssize_t m_mtu;
Davide Pesavento3e7fc832018-09-08 14:07:29 -0400385 ssize_t m_sendQueueCapacity;
Eric Newberrya98bf932015-09-21 00:58:47 -0700386 TransportState m_state;
Eric Newberryc64d30a2015-12-26 11:07:27 -0700387 time::steady_clock::TimePoint m_expirationTime;
Eric Newberrya98bf932015-09-21 00:58:47 -0700388};
389
Junxiao Shicde37ad2015-12-24 01:02:05 -0700390inline const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700391Transport::getFace() const
392{
393 return m_face;
394}
395
396inline const LinkService*
397Transport::getLinkService() const
398{
399 return m_service;
400}
401
402inline LinkService*
403Transport::getLinkService()
404{
405 return m_service;
406}
407
Junxiao Shi57df2882015-11-11 06:12:35 -0700408inline const Transport::Counters&
409Transport::getCounters() const
410{
411 return *this;
412}
413
Eric Newberrya98bf932015-09-21 00:58:47 -0700414inline FaceUri
415Transport::getLocalUri() const
416{
417 return m_localUri;
418}
419
Junxiao Shi13546112015-10-14 19:33:07 -0700420inline void
421Transport::setLocalUri(const FaceUri& uri)
422{
423 m_localUri = uri;
424}
425
Eric Newberrya98bf932015-09-21 00:58:47 -0700426inline FaceUri
427Transport::getRemoteUri() const
428{
429 return m_remoteUri;
430}
431
Junxiao Shi13546112015-10-14 19:33:07 -0700432inline void
433Transport::setRemoteUri(const FaceUri& uri)
434{
435 m_remoteUri = uri;
436}
437
Eric Newberrya98bf932015-09-21 00:58:47 -0700438inline ndn::nfd::FaceScope
439Transport::getScope() const
440{
441 return m_scope;
442}
443
Junxiao Shi13546112015-10-14 19:33:07 -0700444inline void
445Transport::setScope(ndn::nfd::FaceScope scope)
446{
447 m_scope = scope;
448}
449
Eric Newberrya98bf932015-09-21 00:58:47 -0700450inline ndn::nfd::FacePersistency
451Transport::getPersistency() const
452{
453 return m_persistency;
454}
455
Eric Newberrya98bf932015-09-21 00:58:47 -0700456inline ndn::nfd::LinkType
457Transport::getLinkType() const
458{
459 return m_linkType;
460}
461
Eric Newberrya98bf932015-09-21 00:58:47 -0700462inline void
463Transport::setLinkType(ndn::nfd::LinkType linkType)
464{
465 m_linkType = linkType;
466}
467
Junxiao Shi13546112015-10-14 19:33:07 -0700468inline ssize_t
469Transport::getMtu() const
470{
471 return m_mtu;
472}
473
474inline void
475Transport::setMtu(ssize_t mtu)
476{
477 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
478 m_mtu = mtu;
479}
480
Eric Newberryb49313d2017-12-24 20:22:27 -0700481inline ssize_t
482Transport::getSendQueueCapacity() const
483{
484 return m_sendQueueCapacity;
485}
486
487inline void
488Transport::setSendQueueCapacity(ssize_t sendQueueCapacity)
489{
490 m_sendQueueCapacity = sendQueueCapacity;
491}
492
Junxiao Shi13546112015-10-14 19:33:07 -0700493inline TransportState
494Transport::getState() const
495{
496 return m_state;
497}
498
Eric Newberryc64d30a2015-12-26 11:07:27 -0700499inline time::steady_clock::TimePoint
500Transport::getExpirationTime() const
501{
502 return m_expirationTime;
503}
504
505inline void
506Transport::setExpirationTime(const time::steady_clock::TimePoint& expirationTime)
507{
508 m_expirationTime = expirationTime;
509}
510
Eric Newberrya98bf932015-09-21 00:58:47 -0700511std::ostream&
512operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
513
514template<typename T>
515typename std::enable_if<std::is_base_of<Transport, T>::value &&
516 !std::is_same<Transport, T>::value, std::ostream&>::type
517operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
518{
519 return os << FaceLogHelper<Transport>(flh.obj);
520}
521
522} // namespace face
523} // namespace nfd
524
525#endif // NFD_DAEMON_FACE_TRANSPORT_HPP