blob: dd6bb413402e5081d6bc453c9c5e745110149ac2 [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
Davide Pesaventocb425e82019-07-14 21:48:22 -040029#include "face-common.hpp"
Davide Pesavento2cae8ca2019-04-18 20:48:05 -040030#include "common/counter.hpp"
Eric Newberryb49313d2017-12-24 20:22:27 -070031
Eric Newberrya98bf932015-09-21 00:58:47 -070032namespace nfd {
33namespace face {
34
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040035/** \brief Indicates the state of a transport.
Eric Newberrya98bf932015-09-21 00:58:47 -070036 */
37enum class TransportState {
38 NONE,
Davide Pesavento68ab43d2017-07-02 13:37:35 -040039 UP, ///< the transport is up and can transmit packets
40 DOWN, ///< the transport is temporarily down, and is being recovered
41 CLOSING, ///< the transport is being closed gracefully, either by the peer or by a call to close()
Eric Newberrya98bf932015-09-21 00:58:47 -070042 FAILED, ///< the transport is being closed due to a failure
43 CLOSED ///< the transport is closed, and can be safely deallocated
44};
45
46std::ostream&
47operator<<(std::ostream& os, TransportState state);
48
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040049/** \brief Counters provided by a transport.
50 * \note The type name TransportCounters is an implementation detail.
51 * Use Transport::Counters in public API.
Junxiao Shi57df2882015-11-11 06:12:35 -070052 */
53class TransportCounters
54{
55public:
56 /** \brief count of incoming packets
57 *
58 * A 'packet' typically means a top-level TLV block.
59 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
60 * would not be counted.
61 */
62 PacketCounter nInPackets;
63
64 /** \brief count of outgoing packets
65 *
66 * A 'packet' typically means a top-level TLV block.
67 * This counter is incremented only if transport is UP.
68 */
69 PacketCounter nOutPackets;
70
71 /** \brief total incoming bytes
72 *
73 * This counter includes headers imposed by NFD (such as NDNLP),
74 * but excludes overhead of underlying protocol (such as IP header).
75 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
76 * would not be counted.
77 */
78 ByteCounter nInBytes;
79
80 /** \brief total outgoing 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 * This counter is increased only if transport is UP.
85 */
86 ByteCounter nOutBytes;
87};
88
Junxiao Shi13546112015-10-14 19:33:07 -070089/** \brief indicates the transport has no limit on payload size
90 */
91const ssize_t MTU_UNLIMITED = -1;
92
Junxiao Shi5b8a2b22015-10-22 17:20:44 -070093/** \brief (for internal use) indicates MTU field is unset
94 */
95const ssize_t MTU_INVALID = -2;
96
Eric Newberryb49313d2017-12-24 20:22:27 -070097/** \brief indicates that the transport does not support reading the queue capacity/length
98 */
99const ssize_t QUEUE_UNSUPPORTED = -1;
100
101/** \brief indicates that the transport was unable to retrieve the queue capacity/length
102 */
103const ssize_t QUEUE_ERROR = -2;
104
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400105/** \brief The lower half of a Face.
Junxiao Shicde37ad2015-12-24 01:02:05 -0700106 * \sa Face
Eric Newberrya98bf932015-09-21 00:58:47 -0700107 */
Junxiao Shi57df2882015-11-11 06:12:35 -0700108class Transport : protected virtual TransportCounters, noncopyable
Eric Newberrya98bf932015-09-21 00:58:47 -0700109{
110public:
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400111 /** \brief Counters provided by a transport.
112 * \sa TransportCounters
Eric Newberrya98bf932015-09-21 00:58:47 -0700113 */
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400114 using Counters = TransportCounters;
Eric Newberrya98bf932015-09-21 00:58:47 -0700115
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400116 /** \brief Default constructor.
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700117 *
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400118 * This constructor initializes static properties to invalid values.
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700119 * Subclass constructor must explicitly set every static property.
120 *
121 * This constructor initializes TransportState to UP;
122 * subclass constructor can rely on this default value.
123 */
Eric Newberrya98bf932015-09-21 00:58:47 -0700124 Transport();
125
126 virtual
127 ~Transport();
128
129public:
130 /** \brief set Face and LinkService for Transport
131 * \pre setFaceAndLinkService has not been called
132 */
133 void
Junxiao Shicde37ad2015-12-24 01:02:05 -0700134 setFaceAndLinkService(Face& face, LinkService& service);
Eric Newberrya98bf932015-09-21 00:58:47 -0700135
136 /** \return Face to which this Transport is attached
137 */
Junxiao Shicde37ad2015-12-24 01:02:05 -0700138 const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700139 getFace() const;
140
141 /** \return LinkService to which this Transport is attached
142 */
143 const LinkService*
144 getLinkService() const;
145
146 /** \return LinkService to which this Transport is attached
147 */
148 LinkService*
149 getLinkService();
150
Junxiao Shi57df2882015-11-11 06:12:35 -0700151 virtual const Counters&
152 getCounters() const;
153
Eric Newberrya98bf932015-09-21 00:58:47 -0700154public: // upper interface
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400155 /** \brief Request the transport to be closed
Eric Newberrya98bf932015-09-21 00:58:47 -0700156 *
157 * This operation is effective only if transport is in UP or DOWN state,
158 * otherwise it has no effect.
159 * The transport changes state to CLOSING, and performs cleanup procedure.
160 * The state will be changed to CLOSED when cleanup is complete, which may
161 * happen synchronously or asynchronously.
162 */
163 void
164 close();
165
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400166 /** \brief Send a link-layer packet
167 * \param packet the packet to be sent, must be a valid and well-formed TLV block
168 * \param endpoint the destination endpoint
169 * \note This operation has no effect if getState() is neither UP nor DOWN
170 * \warning Behavior is undefined if packet size exceeds the MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700171 */
172 void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400173 send(const Block& packet, const EndpointId& endpoint = 0);
Eric Newberrya98bf932015-09-21 00:58:47 -0700174
Eric Newberrya98bf932015-09-21 00:58:47 -0700175public: // static properties
176 /** \return a FaceUri representing local endpoint
177 */
178 FaceUri
179 getLocalUri() const;
180
181 /** \return a FaceUri representing remote endpoint
182 */
183 FaceUri
184 getRemoteUri() const;
185
186 /** \return whether face is local or non-local for scope control purpose
187 */
188 ndn::nfd::FaceScope
189 getScope() const;
190
191 /** \return face persistency setting
192 */
193 ndn::nfd::FacePersistency
194 getPersistency() const;
195
Davide Pesavento32065652017-01-15 01:52:21 -0500196 /** \brief check whether the face persistency can be changed to \p newPersistency
Yanbiao Li32dab972016-11-27 12:26:09 +0800197 *
Davide Pesavento32065652017-01-15 01:52:21 -0500198 * This function serves as the external API, and invokes the protected function
199 * canChangePersistencyToImpl to perform further checks if \p newPersistency differs
200 * from the current persistency.
Yanbiao Li32dab972016-11-27 12:26:09 +0800201 *
Davide Pesavento32065652017-01-15 01:52:21 -0500202 * \return true if the change can be performed, false otherwise
Yanbiao Li32dab972016-11-27 12:26:09 +0800203 */
204 bool
205 canChangePersistencyTo(ndn::nfd::FacePersistency newPersistency) const;
206
Eric Newberrya98bf932015-09-21 00:58:47 -0700207 /** \brief changes face persistency setting
208 */
209 void
Davide Pesavento32065652017-01-15 01:52:21 -0500210 setPersistency(ndn::nfd::FacePersistency newPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700211
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400212 /** \return the link type of the transport
Eric Newberrya98bf932015-09-21 00:58:47 -0700213 */
214 ndn::nfd::LinkType
215 getLinkType() const;
216
Junxiao Shi13546112015-10-14 19:33:07 -0700217 /** \return maximum payload size
218 * \retval MTU_UNLIMITED transport has no limit on payload size
219 *
220 * This size is the maximum packet size that can be sent or received through this transport.
221 *
222 * For a datagram-based transport, this is typically the Maximum Transmission Unit (MTU),
223 * after the overhead of headers introduced by the transport has been accounted for.
224 * For a stream-based transport, this is typically unlimited (MTU_UNLIMITED).
225 */
226 ssize_t
227 getMtu() const;
228
Eric Newberryb49313d2017-12-24 20:22:27 -0700229 /** \return capacity of the send queue (in bytes)
230 * \retval QUEUE_UNSUPPORTED transport does not support queue capacity retrieval
231 * \retval QUEUE_ERROR transport was unable to retrieve the queue capacity
232 */
233 ssize_t
234 getSendQueueCapacity() const;
235
Eric Newberrya98bf932015-09-21 00:58:47 -0700236public: // dynamic properties
237 /** \return transport state
238 */
239 TransportState
240 getState() const;
241
242 /** \brief signals when transport state changes
243 */
244 signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;
245
Eric Newberryc64d30a2015-12-26 11:07:27 -0700246 /** \return expiration time of the transport
247 * \retval time::steady_clock::TimePoint::max() the transport has indefinite lifetime
248 */
249 time::steady_clock::TimePoint
250 getExpirationTime() const;
251
Eric Newberryb49313d2017-12-24 20:22:27 -0700252 /** \return current send queue length of the transport (in octets)
253 * \retval QUEUE_UNSUPPORTED transport does not support queue length retrieval
254 * \retval QUEUE_ERROR transport was unable to retrieve the queue length
255 */
256 virtual ssize_t
Eric Newberry812d6152018-06-06 15:06:01 -0700257 getSendQueueLength()
258 {
259 return QUEUE_UNSUPPORTED;
260 }
261
262protected: // upper interface to be invoked by subclass
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400263 /** \brief Pass a received link-layer packet to the upper layer for further processing
264 * \param packet the received packet, must be a valid and well-formed TLV block
265 * \param endpoint the source endpoint
266 * \warning Behavior is undefined if packet size exceeds the MTU limit
Eric Newberry812d6152018-06-06 15:06:01 -0700267 */
268 void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400269 receive(const Block& packet, const EndpointId& endpoint = 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700270
Eric Newberrya98bf932015-09-21 00:58:47 -0700271protected: // properties to be set by subclass
272 void
273 setLocalUri(const FaceUri& uri);
274
275 void
276 setRemoteUri(const FaceUri& uri);
277
278 void
279 setScope(ndn::nfd::FaceScope scope);
280
281 void
282 setLinkType(ndn::nfd::LinkType linkType);
283
Junxiao Shi13546112015-10-14 19:33:07 -0700284 void
285 setMtu(ssize_t mtu);
286
Eric Newberryb49313d2017-12-24 20:22:27 -0700287 void
288 setSendQueueCapacity(ssize_t sendQueueCapacity);
289
Eric Newberrya98bf932015-09-21 00:58:47 -0700290 /** \brief set transport state
291 *
292 * Only the following transitions are valid:
293 * UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
294 *
295 * \throw std::runtime_error transition is invalid.
296 */
297 void
298 setState(TransportState newState);
299
Eric Newberryc64d30a2015-12-26 11:07:27 -0700300 void
301 setExpirationTime(const time::steady_clock::TimePoint& expirationTime);
302
Eric Newberrya98bf932015-09-21 00:58:47 -0700303protected: // to be overridden by subclass
Yanbiao Li32dab972016-11-27 12:26:09 +0800304 /** \brief invoked by canChangePersistencyTo to perform the check
305 *
306 * Base class implementation returns false.
307 *
308 * \param newPersistency the new persistency, guaranteed to be different from current persistency
309 */
310 virtual bool
311 canChangePersistencyToImpl(ndn::nfd::FacePersistency newPersistency) const;
312
313 /** \brief invoked after the persistency has been changed
314 *
315 * The base class implementation does nothing.
316 * When overridden in a subclass, the function should update internal states
317 * after persistency setting has been changed.
Eric Newberrya98bf932015-09-21 00:58:47 -0700318 */
319 virtual void
Yanbiao Li32dab972016-11-27 12:26:09 +0800320 afterChangePersistency(ndn::nfd::FacePersistency oldPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700321
322 /** \brief performs Transport specific operations to close the transport
323 *
Junxiao Shi13546112015-10-14 19:33:07 -0700324 * This is invoked once by \p close() after changing state to CLOSING.
325 * It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
326 *
Eric Newberrya98bf932015-09-21 00:58:47 -0700327 * When the cleanup procedure is complete, this method should change state to CLOSED.
Junxiao Shi13546112015-10-14 19:33:07 -0700328 * This transition can happen synchronously or asynchronously.
Eric Newberrya98bf932015-09-21 00:58:47 -0700329 */
330 virtual void
331 doClose() = 0;
332
333private: // to be overridden by subclass
334 /** \brief performs Transport specific operations to send a packet
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400335 * \param packet the packet to be sent, can be assumed to be valid and well-formed
336 * \param endpoint the destination endpoint
337 * \pre transport state is either UP or DOWN
Eric Newberrya98bf932015-09-21 00:58:47 -0700338 */
339 virtual void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400340 doSend(const Block& packet, const EndpointId& endpoint) = 0;
Eric Newberrya98bf932015-09-21 00:58:47 -0700341
Eric Newberry812d6152018-06-06 15:06:01 -0700342public:
343 /** \brief minimum MTU that may be set on a transport
344 *
345 * This is done to ensure the NDNLPv2 fragmentation feature functions properly.
346 */
347 static constexpr ssize_t MIN_MTU = 64;
348
Eric Newberrya98bf932015-09-21 00:58:47 -0700349private:
Junxiao Shicde37ad2015-12-24 01:02:05 -0700350 Face* m_face;
Eric Newberrya98bf932015-09-21 00:58:47 -0700351 LinkService* m_service;
352 FaceUri m_localUri;
353 FaceUri m_remoteUri;
354 ndn::nfd::FaceScope m_scope;
355 ndn::nfd::FacePersistency m_persistency;
356 ndn::nfd::LinkType m_linkType;
Junxiao Shi13546112015-10-14 19:33:07 -0700357 ssize_t m_mtu;
Davide Pesavento3e7fc832018-09-08 14:07:29 -0400358 ssize_t m_sendQueueCapacity;
Eric Newberrya98bf932015-09-21 00:58:47 -0700359 TransportState m_state;
Eric Newberryc64d30a2015-12-26 11:07:27 -0700360 time::steady_clock::TimePoint m_expirationTime;
Eric Newberrya98bf932015-09-21 00:58:47 -0700361};
362
Junxiao Shicde37ad2015-12-24 01:02:05 -0700363inline const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700364Transport::getFace() const
365{
366 return m_face;
367}
368
369inline const LinkService*
370Transport::getLinkService() const
371{
372 return m_service;
373}
374
375inline LinkService*
376Transport::getLinkService()
377{
378 return m_service;
379}
380
Junxiao Shi57df2882015-11-11 06:12:35 -0700381inline const Transport::Counters&
382Transport::getCounters() const
383{
384 return *this;
385}
386
Eric Newberrya98bf932015-09-21 00:58:47 -0700387inline FaceUri
388Transport::getLocalUri() const
389{
390 return m_localUri;
391}
392
Junxiao Shi13546112015-10-14 19:33:07 -0700393inline void
394Transport::setLocalUri(const FaceUri& uri)
395{
396 m_localUri = uri;
397}
398
Eric Newberrya98bf932015-09-21 00:58:47 -0700399inline FaceUri
400Transport::getRemoteUri() const
401{
402 return m_remoteUri;
403}
404
Junxiao Shi13546112015-10-14 19:33:07 -0700405inline void
406Transport::setRemoteUri(const FaceUri& uri)
407{
408 m_remoteUri = uri;
409}
410
Eric Newberrya98bf932015-09-21 00:58:47 -0700411inline ndn::nfd::FaceScope
412Transport::getScope() const
413{
414 return m_scope;
415}
416
Junxiao Shi13546112015-10-14 19:33:07 -0700417inline void
418Transport::setScope(ndn::nfd::FaceScope scope)
419{
420 m_scope = scope;
421}
422
Eric Newberrya98bf932015-09-21 00:58:47 -0700423inline ndn::nfd::FacePersistency
424Transport::getPersistency() const
425{
426 return m_persistency;
427}
428
Eric Newberrya98bf932015-09-21 00:58:47 -0700429inline ndn::nfd::LinkType
430Transport::getLinkType() const
431{
432 return m_linkType;
433}
434
Eric Newberrya98bf932015-09-21 00:58:47 -0700435inline void
436Transport::setLinkType(ndn::nfd::LinkType linkType)
437{
438 m_linkType = linkType;
439}
440
Junxiao Shi13546112015-10-14 19:33:07 -0700441inline ssize_t
442Transport::getMtu() const
443{
444 return m_mtu;
445}
446
447inline void
448Transport::setMtu(ssize_t mtu)
449{
450 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
451 m_mtu = mtu;
452}
453
Eric Newberryb49313d2017-12-24 20:22:27 -0700454inline ssize_t
455Transport::getSendQueueCapacity() const
456{
457 return m_sendQueueCapacity;
458}
459
460inline void
461Transport::setSendQueueCapacity(ssize_t sendQueueCapacity)
462{
463 m_sendQueueCapacity = sendQueueCapacity;
464}
465
Junxiao Shi13546112015-10-14 19:33:07 -0700466inline TransportState
467Transport::getState() const
468{
469 return m_state;
470}
471
Eric Newberryc64d30a2015-12-26 11:07:27 -0700472inline time::steady_clock::TimePoint
473Transport::getExpirationTime() const
474{
475 return m_expirationTime;
476}
477
478inline void
479Transport::setExpirationTime(const time::steady_clock::TimePoint& expirationTime)
480{
481 m_expirationTime = expirationTime;
482}
483
Eric Newberrya98bf932015-09-21 00:58:47 -0700484std::ostream&
485operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
486
487template<typename T>
488typename std::enable_if<std::is_base_of<Transport, T>::value &&
489 !std::is_same<Transport, T>::value, std::ostream&>::type
490operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
491{
492 return os << FaceLogHelper<Transport>(flh.obj);
493}
494
495} // namespace face
496} // namespace nfd
497
498#endif // NFD_DAEMON_FACE_TRANSPORT_HPP