blob: 3db47140522412b2ab195aa3c58891668c9e4de4 [file] [log] [blame]
Eric Newberrya98bf932015-09-21 00:58:47 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Yanbiao Li32dab972016-11-27 12:26:09 +08003 * Copyright (c) 2014-2017, 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"
Junxiao Shi0de23a22015-12-03 20:07:02 +000031#include <ndn-cxx/encoding/nfd-constants.hpp>
Eric Newberrya98bf932015-09-21 00:58:47 -070032
33namespace nfd {
34namespace face {
35
Junxiao Shicde37ad2015-12-24 01:02:05 -070036class Face;
Eric Newberrya98bf932015-09-21 00:58:47 -070037class LinkService;
38
39/** \brief indicates the state of a transport
40 */
41enum class TransportState {
42 NONE,
43 UP, ///< the transport is up
44 DOWN, ///< the transport is down temporarily, and is being recovered
45 CLOSING, ///< the transport is requested to be closed
46 FAILED, ///< the transport is being closed due to a failure
47 CLOSED ///< the transport is closed, and can be safely deallocated
48};
49
50std::ostream&
51operator<<(std::ostream& os, TransportState state);
52
Junxiao Shi57df2882015-11-11 06:12:35 -070053/** \brief counters provided by Transport
54 * \note The type name 'TransportCounters' is implementation detail.
55 * Use 'Transport::Counters' in public API.
56 */
57class TransportCounters
58{
59public:
60 /** \brief count of incoming packets
61 *
62 * A 'packet' typically means a top-level TLV block.
63 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
64 * would not be counted.
65 */
66 PacketCounter nInPackets;
67
68 /** \brief count of outgoing packets
69 *
70 * A 'packet' typically means a top-level TLV block.
71 * This counter is incremented only if transport is UP.
72 */
73 PacketCounter nOutPackets;
74
75 /** \brief total incoming bytes
76 *
77 * This counter includes headers imposed by NFD (such as NDNLP),
78 * but excludes overhead of underlying protocol (such as IP header).
79 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
80 * would not be counted.
81 */
82 ByteCounter nInBytes;
83
84 /** \brief total outgoing bytes
85 *
86 * This counter includes headers imposed by NFD (such as NDNLP),
87 * but excludes overhead of underlying protocol (such as IP header).
88 * This counter is increased only if transport is UP.
89 */
90 ByteCounter nOutBytes;
91};
92
Junxiao Shi13546112015-10-14 19:33:07 -070093/** \brief indicates the transport has no limit on payload size
94 */
95const ssize_t MTU_UNLIMITED = -1;
96
Junxiao Shi5b8a2b22015-10-22 17:20:44 -070097/** \brief (for internal use) indicates MTU field is unset
98 */
99const ssize_t MTU_INVALID = -2;
100
Junxiao Shicde37ad2015-12-24 01:02:05 -0700101/** \brief the lower part of a Face
102 * \sa Face
Eric Newberrya98bf932015-09-21 00:58:47 -0700103 */
Junxiao Shi57df2882015-11-11 06:12:35 -0700104class Transport : protected virtual TransportCounters, noncopyable
Eric Newberrya98bf932015-09-21 00:58:47 -0700105{
106public:
107 /** \brief identifies an endpoint on the link
108 */
109 typedef uint64_t EndpointId;
110
111 /** \brief stores a packet along with the remote endpoint
112 */
113 class Packet
114 {
115 public:
116 Packet() = default;
117
118 explicit
119 Packet(Block&& packet);
120
121 public:
122 /** \brief the packet as a TLV block
123 */
124 Block packet;
125
126 /** \brief identifies the remote endpoint
127 *
128 * This ID is only meaningful in the context of the same Transport.
129 * Incoming packets from the same remote endpoint have the same EndpointId,
130 * and incoming packets from different remote endpoints have different EndpointIds.
131 */
132 EndpointId remoteEndpoint;
133 };
134
Junxiao Shi57df2882015-11-11 06:12:35 -0700135 /** \brief counters provided by Transport
136 */
137 typedef TransportCounters Counters;
138
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700139 /** \brief constructor
140 *
141 * Transport constructor initializes static properties to invalid values.
142 * Subclass constructor must explicitly set every static property.
143 *
144 * This constructor initializes TransportState to UP;
145 * subclass constructor can rely on this default value.
146 */
Eric Newberrya98bf932015-09-21 00:58:47 -0700147 Transport();
148
149 virtual
150 ~Transport();
151
152public:
153 /** \brief set Face and LinkService for Transport
154 * \pre setFaceAndLinkService has not been called
155 */
156 void
Junxiao Shicde37ad2015-12-24 01:02:05 -0700157 setFaceAndLinkService(Face& face, LinkService& service);
Eric Newberrya98bf932015-09-21 00:58:47 -0700158
159 /** \return Face to which this Transport is attached
160 */
Junxiao Shicde37ad2015-12-24 01:02:05 -0700161 const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700162 getFace() const;
163
164 /** \return LinkService to which this Transport is attached
165 */
166 const LinkService*
167 getLinkService() const;
168
169 /** \return LinkService to which this Transport is attached
170 */
171 LinkService*
172 getLinkService();
173
Junxiao Shi57df2882015-11-11 06:12:35 -0700174 virtual const Counters&
175 getCounters() const;
176
Eric Newberrya98bf932015-09-21 00:58:47 -0700177public: // upper interface
178 /** \brief request the transport to be closed
179 *
180 * This operation is effective only if transport is in UP or DOWN state,
181 * otherwise it has no effect.
182 * The transport changes state to CLOSING, and performs cleanup procedure.
183 * The state will be changed to CLOSED when cleanup is complete, which may
184 * happen synchronously or asynchronously.
185 */
186 void
187 close();
188
189 /** \brief send a link-layer packet
Junxiao Shi13546112015-10-14 19:33:07 -0700190 * \note This operation has no effect if \p getState() is neither UP nor DOWN
191 * \warning undefined behavior if packet size exceeds MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700192 */
193 void
194 send(Packet&& packet);
195
196protected: // upper interface to be invoked by subclass
197 /** \brief receive a link-layer packet
Junxiao Shi13546112015-10-14 19:33:07 -0700198 * \warning undefined behavior if packet size exceeds MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700199 */
200 void
201 receive(Packet&& packet);
202
203public: // static properties
204 /** \return a FaceUri representing local endpoint
205 */
206 FaceUri
207 getLocalUri() const;
208
209 /** \return a FaceUri representing remote endpoint
210 */
211 FaceUri
212 getRemoteUri() const;
213
214 /** \return whether face is local or non-local for scope control purpose
215 */
216 ndn::nfd::FaceScope
217 getScope() const;
218
219 /** \return face persistency setting
220 */
221 ndn::nfd::FacePersistency
222 getPersistency() const;
223
Yanbiao Li32dab972016-11-27 12:26:09 +0800224 /** \brief check whether the intended change from the current persistency to \p newPersistency
225 * can be performed
226 *
227 * This function serves as an external API, and invokes the internal function
228 * canChangePersistencyToImpl to perform further checks if \p newPersistency differs from
229 * the current persistency.
230 *
231 * \pre getPersistency() != NONE
232 *
233 * \return true if the intended change can be performed, otherwise false
234 */
235 bool
236 canChangePersistencyTo(ndn::nfd::FacePersistency newPersistency) const;
237
Eric Newberrya98bf932015-09-21 00:58:47 -0700238 /** \brief changes face persistency setting
239 */
240 void
241 setPersistency(ndn::nfd::FacePersistency persistency);
242
243 /** \return whether face is point-to-point or multi-access
244 */
245 ndn::nfd::LinkType
246 getLinkType() const;
247
Junxiao Shi13546112015-10-14 19:33:07 -0700248 /** \return maximum payload size
249 * \retval MTU_UNLIMITED transport has no limit on payload size
250 *
251 * This size is the maximum packet size that can be sent or received through this transport.
252 *
253 * For a datagram-based transport, this is typically the Maximum Transmission Unit (MTU),
254 * after the overhead of headers introduced by the transport has been accounted for.
255 * For a stream-based transport, this is typically unlimited (MTU_UNLIMITED).
256 */
257 ssize_t
258 getMtu() const;
259
Eric Newberrya98bf932015-09-21 00:58:47 -0700260public: // dynamic properties
261 /** \return transport state
262 */
263 TransportState
264 getState() const;
265
266 /** \brief signals when transport state changes
267 */
268 signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;
269
Eric Newberryc64d30a2015-12-26 11:07:27 -0700270 /** \return expiration time of the transport
271 * \retval time::steady_clock::TimePoint::max() the transport has indefinite lifetime
272 */
273 time::steady_clock::TimePoint
274 getExpirationTime() const;
275
Eric Newberrya98bf932015-09-21 00:58:47 -0700276protected: // properties to be set by subclass
277 void
278 setLocalUri(const FaceUri& uri);
279
280 void
281 setRemoteUri(const FaceUri& uri);
282
283 void
284 setScope(ndn::nfd::FaceScope scope);
285
286 void
287 setLinkType(ndn::nfd::LinkType linkType);
288
Junxiao Shi13546112015-10-14 19:33:07 -0700289 void
290 setMtu(ssize_t mtu);
291
Eric Newberrya98bf932015-09-21 00:58:47 -0700292 /** \brief set transport state
293 *
294 * Only the following transitions are valid:
295 * UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
296 *
297 * \throw std::runtime_error transition is invalid.
298 */
299 void
300 setState(TransportState newState);
301
Eric Newberryc64d30a2015-12-26 11:07:27 -0700302 void
303 setExpirationTime(const time::steady_clock::TimePoint& expirationTime);
304
Eric Newberrya98bf932015-09-21 00:58:47 -0700305protected: // to be overridden by subclass
Yanbiao Li32dab972016-11-27 12:26:09 +0800306 /** \brief invoked by canChangePersistencyTo to perform the check
307 *
308 * Base class implementation returns false.
309 *
310 * \param newPersistency the new persistency, guaranteed to be different from current persistency
311 */
312 virtual bool
313 canChangePersistencyToImpl(ndn::nfd::FacePersistency newPersistency) const;
314
315 /** \brief invoked after the persistency has been changed
316 *
317 * The base class implementation does nothing.
318 * When overridden in a subclass, the function should update internal states
319 * after persistency setting has been changed.
Eric Newberrya98bf932015-09-21 00:58:47 -0700320 */
321 virtual void
Yanbiao Li32dab972016-11-27 12:26:09 +0800322 afterChangePersistency(ndn::nfd::FacePersistency oldPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700323
324 /** \brief performs Transport specific operations to close the transport
325 *
Junxiao Shi13546112015-10-14 19:33:07 -0700326 * This is invoked once by \p close() after changing state to CLOSING.
327 * It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
328 *
Eric Newberrya98bf932015-09-21 00:58:47 -0700329 * When the cleanup procedure is complete, this method should change state to CLOSED.
Junxiao Shi13546112015-10-14 19:33:07 -0700330 * This transition can happen synchronously or asynchronously.
Eric Newberrya98bf932015-09-21 00:58:47 -0700331 */
332 virtual void
333 doClose() = 0;
334
335private: // to be overridden by subclass
336 /** \brief performs Transport specific operations to send a packet
337 * \param packet the packet, which must be a well-formed TLV block
Junxiao Shi13546112015-10-14 19:33:07 -0700338 * \pre state is either UP or DOWN
Eric Newberrya98bf932015-09-21 00:58:47 -0700339 */
340 virtual void
341 doSend(Packet&& packet) = 0;
342
343private:
Junxiao Shicde37ad2015-12-24 01:02:05 -0700344 Face* m_face;
Eric Newberrya98bf932015-09-21 00:58:47 -0700345 LinkService* m_service;
346 FaceUri m_localUri;
347 FaceUri m_remoteUri;
348 ndn::nfd::FaceScope m_scope;
349 ndn::nfd::FacePersistency m_persistency;
350 ndn::nfd::LinkType m_linkType;
Junxiao Shi13546112015-10-14 19:33:07 -0700351 ssize_t m_mtu;
Eric Newberrya98bf932015-09-21 00:58:47 -0700352 TransportState m_state;
Eric Newberryc64d30a2015-12-26 11:07:27 -0700353 time::steady_clock::TimePoint m_expirationTime;
Eric Newberrya98bf932015-09-21 00:58:47 -0700354};
355
Junxiao Shicde37ad2015-12-24 01:02:05 -0700356inline const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700357Transport::getFace() const
358{
359 return m_face;
360}
361
362inline const LinkService*
363Transport::getLinkService() const
364{
365 return m_service;
366}
367
368inline LinkService*
369Transport::getLinkService()
370{
371 return m_service;
372}
373
Junxiao Shi57df2882015-11-11 06:12:35 -0700374inline const Transport::Counters&
375Transport::getCounters() const
376{
377 return *this;
378}
379
Eric Newberrya98bf932015-09-21 00:58:47 -0700380inline FaceUri
381Transport::getLocalUri() const
382{
383 return m_localUri;
384}
385
Junxiao Shi13546112015-10-14 19:33:07 -0700386inline void
387Transport::setLocalUri(const FaceUri& uri)
388{
389 m_localUri = uri;
390}
391
Eric Newberrya98bf932015-09-21 00:58:47 -0700392inline FaceUri
393Transport::getRemoteUri() const
394{
395 return m_remoteUri;
396}
397
Junxiao Shi13546112015-10-14 19:33:07 -0700398inline void
399Transport::setRemoteUri(const FaceUri& uri)
400{
401 m_remoteUri = uri;
402}
403
Eric Newberrya98bf932015-09-21 00:58:47 -0700404inline ndn::nfd::FaceScope
405Transport::getScope() const
406{
407 return m_scope;
408}
409
Junxiao Shi13546112015-10-14 19:33:07 -0700410inline void
411Transport::setScope(ndn::nfd::FaceScope scope)
412{
413 m_scope = scope;
414}
415
Eric Newberrya98bf932015-09-21 00:58:47 -0700416inline ndn::nfd::FacePersistency
417Transport::getPersistency() const
418{
419 return m_persistency;
420}
421
Eric Newberrya98bf932015-09-21 00:58:47 -0700422inline ndn::nfd::LinkType
423Transport::getLinkType() const
424{
425 return m_linkType;
426}
427
Eric Newberrya98bf932015-09-21 00:58:47 -0700428inline void
429Transport::setLinkType(ndn::nfd::LinkType linkType)
430{
431 m_linkType = linkType;
432}
433
Junxiao Shi13546112015-10-14 19:33:07 -0700434inline ssize_t
435Transport::getMtu() const
436{
437 return m_mtu;
438}
439
440inline void
441Transport::setMtu(ssize_t mtu)
442{
443 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
444 m_mtu = mtu;
445}
446
447inline TransportState
448Transport::getState() const
449{
450 return m_state;
451}
452
Eric Newberryc64d30a2015-12-26 11:07:27 -0700453inline time::steady_clock::TimePoint
454Transport::getExpirationTime() const
455{
456 return m_expirationTime;
457}
458
459inline void
460Transport::setExpirationTime(const time::steady_clock::TimePoint& expirationTime)
461{
462 m_expirationTime = expirationTime;
463}
464
Eric Newberrya98bf932015-09-21 00:58:47 -0700465std::ostream&
466operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
467
468template<typename T>
469typename std::enable_if<std::is_base_of<Transport, T>::value &&
470 !std::is_same<Transport, T>::value, std::ostream&>::type
471operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
472{
473 return os << FaceLogHelper<Transport>(flh.obj);
474}
475
476} // namespace face
477} // namespace nfd
478
479#endif // NFD_DAEMON_FACE_TRANSPORT_HPP