blob: 2dd81a05b1b50c0cbac2bd91e3728b3b987c1550 [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
Eric Newberrya98bf932015-09-21 00:58:47 -070029#include "face-log.hpp"
Davide Pesavento2cae8ca2019-04-18 20:48:05 -040030#include "common/counter.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
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040040/** \brief Identifies a remote endpoint on the link.
41 *
42 * This ID is only meaningful in the context of the same Transport.
43 * Incoming packets from the same remote endpoint have the same EndpointId,
44 * and incoming packets from different remote endpoints have different EndpointIds.
45 *
46 * Typically, a point-to-point Transport has only one meaningful EndpointId (usually 0).
47 *
48 * \sa FaceEndpoint
ashiqopu77d0bfd2019-02-20 20:37:31 +000049 */
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040050using EndpointId = uint64_t;
ashiqopu77d0bfd2019-02-20 20:37:31 +000051
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040052/** \brief Indicates the state of a transport.
Eric Newberrya98bf932015-09-21 00:58:47 -070053 */
54enum class TransportState {
55 NONE,
Davide Pesavento68ab43d2017-07-02 13:37:35 -040056 UP, ///< the transport is up and can transmit packets
57 DOWN, ///< the transport is temporarily down, and is being recovered
58 CLOSING, ///< the transport is being closed gracefully, either by the peer or by a call to close()
Eric Newberrya98bf932015-09-21 00:58:47 -070059 FAILED, ///< the transport is being closed due to a failure
60 CLOSED ///< the transport is closed, and can be safely deallocated
61};
62
63std::ostream&
64operator<<(std::ostream& os, TransportState state);
65
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040066/** \brief Counters provided by a transport.
67 * \note The type name TransportCounters is an implementation detail.
68 * Use Transport::Counters in public API.
Junxiao Shi57df2882015-11-11 06:12:35 -070069 */
70class TransportCounters
71{
72public:
73 /** \brief count of incoming packets
74 *
75 * A 'packet' typically means a top-level TLV block.
76 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
77 * would not be counted.
78 */
79 PacketCounter nInPackets;
80
81 /** \brief count of outgoing packets
82 *
83 * A 'packet' typically means a top-level TLV block.
84 * This counter is incremented only if transport is UP.
85 */
86 PacketCounter nOutPackets;
87
88 /** \brief total incoming bytes
89 *
90 * This counter includes headers imposed by NFD (such as NDNLP),
91 * but excludes overhead of underlying protocol (such as IP header).
92 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
93 * would not be counted.
94 */
95 ByteCounter nInBytes;
96
97 /** \brief total outgoing bytes
98 *
99 * This counter includes headers imposed by NFD (such as NDNLP),
100 * but excludes overhead of underlying protocol (such as IP header).
101 * This counter is increased only if transport is UP.
102 */
103 ByteCounter nOutBytes;
104};
105
Junxiao Shi13546112015-10-14 19:33:07 -0700106/** \brief indicates the transport has no limit on payload size
107 */
108const ssize_t MTU_UNLIMITED = -1;
109
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700110/** \brief (for internal use) indicates MTU field is unset
111 */
112const ssize_t MTU_INVALID = -2;
113
Eric Newberryb49313d2017-12-24 20:22:27 -0700114/** \brief indicates that the transport does not support reading the queue capacity/length
115 */
116const ssize_t QUEUE_UNSUPPORTED = -1;
117
118/** \brief indicates that the transport was unable to retrieve the queue capacity/length
119 */
120const ssize_t QUEUE_ERROR = -2;
121
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400122/** \brief The lower half of a Face.
Junxiao Shicde37ad2015-12-24 01:02:05 -0700123 * \sa Face
Eric Newberrya98bf932015-09-21 00:58:47 -0700124 */
Junxiao Shi57df2882015-11-11 06:12:35 -0700125class Transport : protected virtual TransportCounters, noncopyable
Eric Newberrya98bf932015-09-21 00:58:47 -0700126{
127public:
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400128 /** \brief Counters provided by a transport.
129 * \sa TransportCounters
Eric Newberrya98bf932015-09-21 00:58:47 -0700130 */
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400131 using Counters = TransportCounters;
Eric Newberrya98bf932015-09-21 00:58:47 -0700132
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400133 /** \brief Default constructor.
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700134 *
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400135 * This constructor initializes static properties to invalid values.
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700136 * Subclass constructor must explicitly set every static property.
137 *
138 * This constructor initializes TransportState to UP;
139 * subclass constructor can rely on this default value.
140 */
Eric Newberrya98bf932015-09-21 00:58:47 -0700141 Transport();
142
143 virtual
144 ~Transport();
145
146public:
147 /** \brief set Face and LinkService for Transport
148 * \pre setFaceAndLinkService has not been called
149 */
150 void
Junxiao Shicde37ad2015-12-24 01:02:05 -0700151 setFaceAndLinkService(Face& face, LinkService& service);
Eric Newberrya98bf932015-09-21 00:58:47 -0700152
153 /** \return Face to which this Transport is attached
154 */
Junxiao Shicde37ad2015-12-24 01:02:05 -0700155 const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700156 getFace() const;
157
158 /** \return LinkService to which this Transport is attached
159 */
160 const LinkService*
161 getLinkService() const;
162
163 /** \return LinkService to which this Transport is attached
164 */
165 LinkService*
166 getLinkService();
167
Junxiao Shi57df2882015-11-11 06:12:35 -0700168 virtual const Counters&
169 getCounters() const;
170
Eric Newberrya98bf932015-09-21 00:58:47 -0700171public: // upper interface
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400172 /** \brief Request the transport to be closed
Eric Newberrya98bf932015-09-21 00:58:47 -0700173 *
174 * This operation is effective only if transport is in UP or DOWN state,
175 * otherwise it has no effect.
176 * The transport changes state to CLOSING, and performs cleanup procedure.
177 * The state will be changed to CLOSED when cleanup is complete, which may
178 * happen synchronously or asynchronously.
179 */
180 void
181 close();
182
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400183 /** \brief Send a link-layer packet
184 * \param packet the packet to be sent, must be a valid and well-formed TLV block
185 * \param endpoint the destination endpoint
186 * \note This operation has no effect if getState() is neither UP nor DOWN
187 * \warning Behavior is undefined if packet size exceeds the MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700188 */
189 void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400190 send(const Block& packet, const EndpointId& endpoint = 0);
Eric Newberrya98bf932015-09-21 00:58:47 -0700191
Eric Newberrya98bf932015-09-21 00:58:47 -0700192public: // static properties
193 /** \return a FaceUri representing local endpoint
194 */
195 FaceUri
196 getLocalUri() const;
197
198 /** \return a FaceUri representing remote endpoint
199 */
200 FaceUri
201 getRemoteUri() const;
202
203 /** \return whether face is local or non-local for scope control purpose
204 */
205 ndn::nfd::FaceScope
206 getScope() const;
207
208 /** \return face persistency setting
209 */
210 ndn::nfd::FacePersistency
211 getPersistency() const;
212
Davide Pesavento32065652017-01-15 01:52:21 -0500213 /** \brief check whether the face persistency can be changed to \p newPersistency
Yanbiao Li32dab972016-11-27 12:26:09 +0800214 *
Davide Pesavento32065652017-01-15 01:52:21 -0500215 * This function serves as the external API, and invokes the protected function
216 * canChangePersistencyToImpl to perform further checks if \p newPersistency differs
217 * from the current persistency.
Yanbiao Li32dab972016-11-27 12:26:09 +0800218 *
Davide Pesavento32065652017-01-15 01:52:21 -0500219 * \return true if the change can be performed, false otherwise
Yanbiao Li32dab972016-11-27 12:26:09 +0800220 */
221 bool
222 canChangePersistencyTo(ndn::nfd::FacePersistency newPersistency) const;
223
Eric Newberrya98bf932015-09-21 00:58:47 -0700224 /** \brief changes face persistency setting
225 */
226 void
Davide Pesavento32065652017-01-15 01:52:21 -0500227 setPersistency(ndn::nfd::FacePersistency newPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700228
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400229 /** \return the link type of the transport
Eric Newberrya98bf932015-09-21 00:58:47 -0700230 */
231 ndn::nfd::LinkType
232 getLinkType() const;
233
Junxiao Shi13546112015-10-14 19:33:07 -0700234 /** \return maximum payload size
235 * \retval MTU_UNLIMITED transport has no limit on payload size
236 *
237 * This size is the maximum packet size that can be sent or received through this transport.
238 *
239 * For a datagram-based transport, this is typically the Maximum Transmission Unit (MTU),
240 * after the overhead of headers introduced by the transport has been accounted for.
241 * For a stream-based transport, this is typically unlimited (MTU_UNLIMITED).
242 */
243 ssize_t
244 getMtu() const;
245
Eric Newberryb49313d2017-12-24 20:22:27 -0700246 /** \return capacity of the send queue (in bytes)
247 * \retval QUEUE_UNSUPPORTED transport does not support queue capacity retrieval
248 * \retval QUEUE_ERROR transport was unable to retrieve the queue capacity
249 */
250 ssize_t
251 getSendQueueCapacity() const;
252
Eric Newberrya98bf932015-09-21 00:58:47 -0700253public: // dynamic properties
254 /** \return transport state
255 */
256 TransportState
257 getState() const;
258
259 /** \brief signals when transport state changes
260 */
261 signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;
262
Eric Newberryc64d30a2015-12-26 11:07:27 -0700263 /** \return expiration time of the transport
264 * \retval time::steady_clock::TimePoint::max() the transport has indefinite lifetime
265 */
266 time::steady_clock::TimePoint
267 getExpirationTime() const;
268
Eric Newberryb49313d2017-12-24 20:22:27 -0700269 /** \return current send queue length of the transport (in octets)
270 * \retval QUEUE_UNSUPPORTED transport does not support queue length retrieval
271 * \retval QUEUE_ERROR transport was unable to retrieve the queue length
272 */
273 virtual ssize_t
Eric Newberry812d6152018-06-06 15:06:01 -0700274 getSendQueueLength()
275 {
276 return QUEUE_UNSUPPORTED;
277 }
278
279protected: // upper interface to be invoked by subclass
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400280 /** \brief Pass a received link-layer packet to the upper layer for further processing
281 * \param packet the received packet, must be a valid and well-formed TLV block
282 * \param endpoint the source endpoint
283 * \warning Behavior is undefined if packet size exceeds the MTU limit
Eric Newberry812d6152018-06-06 15:06:01 -0700284 */
285 void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400286 receive(const Block& packet, const EndpointId& endpoint = 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700287
Eric Newberrya98bf932015-09-21 00:58:47 -0700288protected: // properties to be set by subclass
289 void
290 setLocalUri(const FaceUri& uri);
291
292 void
293 setRemoteUri(const FaceUri& uri);
294
295 void
296 setScope(ndn::nfd::FaceScope scope);
297
298 void
299 setLinkType(ndn::nfd::LinkType linkType);
300
Junxiao Shi13546112015-10-14 19:33:07 -0700301 void
302 setMtu(ssize_t mtu);
303
Eric Newberryb49313d2017-12-24 20:22:27 -0700304 void
305 setSendQueueCapacity(ssize_t sendQueueCapacity);
306
Eric Newberrya98bf932015-09-21 00:58:47 -0700307 /** \brief set transport state
308 *
309 * Only the following transitions are valid:
310 * UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
311 *
312 * \throw std::runtime_error transition is invalid.
313 */
314 void
315 setState(TransportState newState);
316
Eric Newberryc64d30a2015-12-26 11:07:27 -0700317 void
318 setExpirationTime(const time::steady_clock::TimePoint& expirationTime);
319
Eric Newberrya98bf932015-09-21 00:58:47 -0700320protected: // to be overridden by subclass
Yanbiao Li32dab972016-11-27 12:26:09 +0800321 /** \brief invoked by canChangePersistencyTo to perform the check
322 *
323 * Base class implementation returns false.
324 *
325 * \param newPersistency the new persistency, guaranteed to be different from current persistency
326 */
327 virtual bool
328 canChangePersistencyToImpl(ndn::nfd::FacePersistency newPersistency) const;
329
330 /** \brief invoked after the persistency has been changed
331 *
332 * The base class implementation does nothing.
333 * When overridden in a subclass, the function should update internal states
334 * after persistency setting has been changed.
Eric Newberrya98bf932015-09-21 00:58:47 -0700335 */
336 virtual void
Yanbiao Li32dab972016-11-27 12:26:09 +0800337 afterChangePersistency(ndn::nfd::FacePersistency oldPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700338
339 /** \brief performs Transport specific operations to close the transport
340 *
Junxiao Shi13546112015-10-14 19:33:07 -0700341 * This is invoked once by \p close() after changing state to CLOSING.
342 * It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
343 *
Eric Newberrya98bf932015-09-21 00:58:47 -0700344 * When the cleanup procedure is complete, this method should change state to CLOSED.
Junxiao Shi13546112015-10-14 19:33:07 -0700345 * This transition can happen synchronously or asynchronously.
Eric Newberrya98bf932015-09-21 00:58:47 -0700346 */
347 virtual void
348 doClose() = 0;
349
350private: // to be overridden by subclass
351 /** \brief performs Transport specific operations to send a packet
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400352 * \param packet the packet to be sent, can be assumed to be valid and well-formed
353 * \param endpoint the destination endpoint
354 * \pre transport state is either UP or DOWN
Eric Newberrya98bf932015-09-21 00:58:47 -0700355 */
356 virtual void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400357 doSend(const Block& packet, const EndpointId& endpoint) = 0;
Eric Newberrya98bf932015-09-21 00:58:47 -0700358
Eric Newberry812d6152018-06-06 15:06:01 -0700359public:
360 /** \brief minimum MTU that may be set on a transport
361 *
362 * This is done to ensure the NDNLPv2 fragmentation feature functions properly.
363 */
364 static constexpr ssize_t MIN_MTU = 64;
365
Eric Newberrya98bf932015-09-21 00:58:47 -0700366private:
Junxiao Shicde37ad2015-12-24 01:02:05 -0700367 Face* m_face;
Eric Newberrya98bf932015-09-21 00:58:47 -0700368 LinkService* m_service;
369 FaceUri m_localUri;
370 FaceUri m_remoteUri;
371 ndn::nfd::FaceScope m_scope;
372 ndn::nfd::FacePersistency m_persistency;
373 ndn::nfd::LinkType m_linkType;
Junxiao Shi13546112015-10-14 19:33:07 -0700374 ssize_t m_mtu;
Davide Pesavento3e7fc832018-09-08 14:07:29 -0400375 ssize_t m_sendQueueCapacity;
Eric Newberrya98bf932015-09-21 00:58:47 -0700376 TransportState m_state;
Eric Newberryc64d30a2015-12-26 11:07:27 -0700377 time::steady_clock::TimePoint m_expirationTime;
Eric Newberrya98bf932015-09-21 00:58:47 -0700378};
379
Junxiao Shicde37ad2015-12-24 01:02:05 -0700380inline const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700381Transport::getFace() const
382{
383 return m_face;
384}
385
386inline const LinkService*
387Transport::getLinkService() const
388{
389 return m_service;
390}
391
392inline LinkService*
393Transport::getLinkService()
394{
395 return m_service;
396}
397
Junxiao Shi57df2882015-11-11 06:12:35 -0700398inline const Transport::Counters&
399Transport::getCounters() const
400{
401 return *this;
402}
403
Eric Newberrya98bf932015-09-21 00:58:47 -0700404inline FaceUri
405Transport::getLocalUri() const
406{
407 return m_localUri;
408}
409
Junxiao Shi13546112015-10-14 19:33:07 -0700410inline void
411Transport::setLocalUri(const FaceUri& uri)
412{
413 m_localUri = uri;
414}
415
Eric Newberrya98bf932015-09-21 00:58:47 -0700416inline FaceUri
417Transport::getRemoteUri() const
418{
419 return m_remoteUri;
420}
421
Junxiao Shi13546112015-10-14 19:33:07 -0700422inline void
423Transport::setRemoteUri(const FaceUri& uri)
424{
425 m_remoteUri = uri;
426}
427
Eric Newberrya98bf932015-09-21 00:58:47 -0700428inline ndn::nfd::FaceScope
429Transport::getScope() const
430{
431 return m_scope;
432}
433
Junxiao Shi13546112015-10-14 19:33:07 -0700434inline void
435Transport::setScope(ndn::nfd::FaceScope scope)
436{
437 m_scope = scope;
438}
439
Eric Newberrya98bf932015-09-21 00:58:47 -0700440inline ndn::nfd::FacePersistency
441Transport::getPersistency() const
442{
443 return m_persistency;
444}
445
Eric Newberrya98bf932015-09-21 00:58:47 -0700446inline ndn::nfd::LinkType
447Transport::getLinkType() const
448{
449 return m_linkType;
450}
451
Eric Newberrya98bf932015-09-21 00:58:47 -0700452inline void
453Transport::setLinkType(ndn::nfd::LinkType linkType)
454{
455 m_linkType = linkType;
456}
457
Junxiao Shi13546112015-10-14 19:33:07 -0700458inline ssize_t
459Transport::getMtu() const
460{
461 return m_mtu;
462}
463
464inline void
465Transport::setMtu(ssize_t mtu)
466{
467 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
468 m_mtu = mtu;
469}
470
Eric Newberryb49313d2017-12-24 20:22:27 -0700471inline ssize_t
472Transport::getSendQueueCapacity() const
473{
474 return m_sendQueueCapacity;
475}
476
477inline void
478Transport::setSendQueueCapacity(ssize_t sendQueueCapacity)
479{
480 m_sendQueueCapacity = sendQueueCapacity;
481}
482
Junxiao Shi13546112015-10-14 19:33:07 -0700483inline TransportState
484Transport::getState() const
485{
486 return m_state;
487}
488
Eric Newberryc64d30a2015-12-26 11:07:27 -0700489inline time::steady_clock::TimePoint
490Transport::getExpirationTime() const
491{
492 return m_expirationTime;
493}
494
495inline void
496Transport::setExpirationTime(const time::steady_clock::TimePoint& expirationTime)
497{
498 m_expirationTime = expirationTime;
499}
500
Eric Newberrya98bf932015-09-21 00:58:47 -0700501std::ostream&
502operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
503
504template<typename T>
505typename std::enable_if<std::is_base_of<Transport, T>::value &&
506 !std::is_same<Transport, T>::value, std::ostream&>::type
507operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
508{
509 return os << FaceLogHelper<Transport>(flh.obj);
510}
511
512} // namespace face
513} // namespace nfd
514
515#endif // NFD_DAEMON_FACE_TRANSPORT_HPP