blob: 85a0fd71be65e42c92780479e8bb12a820d1d9e0 [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,
Davide Pesavento68ab43d2017-07-02 13:37:35 -040043 UP, ///< the transport is up and can transmit packets
44 DOWN, ///< the transport is temporarily down, and is being recovered
45 CLOSING, ///< the transport is being closed gracefully, either by the peer or by a call to close()
Eric Newberrya98bf932015-09-21 00:58:47 -070046 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
Davide Pesavento32065652017-01-15 01:52:21 -0500224 /** \brief check whether the face persistency can be changed to \p newPersistency
Yanbiao Li32dab972016-11-27 12:26:09 +0800225 *
Davide Pesavento32065652017-01-15 01:52:21 -0500226 * This function serves as the external API, and invokes the protected function
227 * canChangePersistencyToImpl to perform further checks if \p newPersistency differs
228 * from the current persistency.
Yanbiao Li32dab972016-11-27 12:26:09 +0800229 *
Davide Pesavento32065652017-01-15 01:52:21 -0500230 * \return true if the change can be performed, false otherwise
Yanbiao Li32dab972016-11-27 12:26:09 +0800231 */
232 bool
233 canChangePersistencyTo(ndn::nfd::FacePersistency newPersistency) const;
234
Eric Newberrya98bf932015-09-21 00:58:47 -0700235 /** \brief changes face persistency setting
236 */
237 void
Davide Pesavento32065652017-01-15 01:52:21 -0500238 setPersistency(ndn::nfd::FacePersistency newPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700239
240 /** \return whether face is point-to-point or multi-access
241 */
242 ndn::nfd::LinkType
243 getLinkType() const;
244
Junxiao Shi13546112015-10-14 19:33:07 -0700245 /** \return maximum payload size
246 * \retval MTU_UNLIMITED transport has no limit on payload size
247 *
248 * This size is the maximum packet size that can be sent or received through this transport.
249 *
250 * For a datagram-based transport, this is typically the Maximum Transmission Unit (MTU),
251 * after the overhead of headers introduced by the transport has been accounted for.
252 * For a stream-based transport, this is typically unlimited (MTU_UNLIMITED).
253 */
254 ssize_t
255 getMtu() const;
256
Eric Newberrya98bf932015-09-21 00:58:47 -0700257public: // dynamic properties
258 /** \return transport state
259 */
260 TransportState
261 getState() const;
262
263 /** \brief signals when transport state changes
264 */
265 signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;
266
Eric Newberryc64d30a2015-12-26 11:07:27 -0700267 /** \return expiration time of the transport
268 * \retval time::steady_clock::TimePoint::max() the transport has indefinite lifetime
269 */
270 time::steady_clock::TimePoint
271 getExpirationTime() const;
272
Eric Newberrya98bf932015-09-21 00:58:47 -0700273protected: // properties to be set by subclass
274 void
275 setLocalUri(const FaceUri& uri);
276
277 void
278 setRemoteUri(const FaceUri& uri);
279
280 void
281 setScope(ndn::nfd::FaceScope scope);
282
283 void
284 setLinkType(ndn::nfd::LinkType linkType);
285
Junxiao Shi13546112015-10-14 19:33:07 -0700286 void
287 setMtu(ssize_t mtu);
288
Eric Newberrya98bf932015-09-21 00:58:47 -0700289 /** \brief set transport state
290 *
291 * Only the following transitions are valid:
292 * UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
293 *
294 * \throw std::runtime_error transition is invalid.
295 */
296 void
297 setState(TransportState newState);
298
Eric Newberryc64d30a2015-12-26 11:07:27 -0700299 void
300 setExpirationTime(const time::steady_clock::TimePoint& expirationTime);
301
Eric Newberrya98bf932015-09-21 00:58:47 -0700302protected: // to be overridden by subclass
Yanbiao Li32dab972016-11-27 12:26:09 +0800303 /** \brief invoked by canChangePersistencyTo to perform the check
304 *
305 * Base class implementation returns false.
306 *
307 * \param newPersistency the new persistency, guaranteed to be different from current persistency
308 */
309 virtual bool
310 canChangePersistencyToImpl(ndn::nfd::FacePersistency newPersistency) const;
311
312 /** \brief invoked after the persistency has been changed
313 *
314 * The base class implementation does nothing.
315 * When overridden in a subclass, the function should update internal states
316 * after persistency setting has been changed.
Eric Newberrya98bf932015-09-21 00:58:47 -0700317 */
318 virtual void
Yanbiao Li32dab972016-11-27 12:26:09 +0800319 afterChangePersistency(ndn::nfd::FacePersistency oldPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700320
321 /** \brief performs Transport specific operations to close the transport
322 *
Junxiao Shi13546112015-10-14 19:33:07 -0700323 * This is invoked once by \p close() after changing state to CLOSING.
324 * It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
325 *
Eric Newberrya98bf932015-09-21 00:58:47 -0700326 * When the cleanup procedure is complete, this method should change state to CLOSED.
Junxiao Shi13546112015-10-14 19:33:07 -0700327 * This transition can happen synchronously or asynchronously.
Eric Newberrya98bf932015-09-21 00:58:47 -0700328 */
329 virtual void
330 doClose() = 0;
331
332private: // to be overridden by subclass
333 /** \brief performs Transport specific operations to send a packet
334 * \param packet the packet, which must be a well-formed TLV block
Junxiao Shi13546112015-10-14 19:33:07 -0700335 * \pre state is either UP or DOWN
Eric Newberrya98bf932015-09-21 00:58:47 -0700336 */
337 virtual void
338 doSend(Packet&& packet) = 0;
339
340private:
Junxiao Shicde37ad2015-12-24 01:02:05 -0700341 Face* m_face;
Eric Newberrya98bf932015-09-21 00:58:47 -0700342 LinkService* m_service;
343 FaceUri m_localUri;
344 FaceUri m_remoteUri;
345 ndn::nfd::FaceScope m_scope;
346 ndn::nfd::FacePersistency m_persistency;
347 ndn::nfd::LinkType m_linkType;
Junxiao Shi13546112015-10-14 19:33:07 -0700348 ssize_t m_mtu;
Eric Newberrya98bf932015-09-21 00:58:47 -0700349 TransportState m_state;
Eric Newberryc64d30a2015-12-26 11:07:27 -0700350 time::steady_clock::TimePoint m_expirationTime;
Eric Newberrya98bf932015-09-21 00:58:47 -0700351};
352
Junxiao Shicde37ad2015-12-24 01:02:05 -0700353inline const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700354Transport::getFace() const
355{
356 return m_face;
357}
358
359inline const LinkService*
360Transport::getLinkService() const
361{
362 return m_service;
363}
364
365inline LinkService*
366Transport::getLinkService()
367{
368 return m_service;
369}
370
Junxiao Shi57df2882015-11-11 06:12:35 -0700371inline const Transport::Counters&
372Transport::getCounters() const
373{
374 return *this;
375}
376
Eric Newberrya98bf932015-09-21 00:58:47 -0700377inline FaceUri
378Transport::getLocalUri() const
379{
380 return m_localUri;
381}
382
Junxiao Shi13546112015-10-14 19:33:07 -0700383inline void
384Transport::setLocalUri(const FaceUri& uri)
385{
386 m_localUri = uri;
387}
388
Eric Newberrya98bf932015-09-21 00:58:47 -0700389inline FaceUri
390Transport::getRemoteUri() const
391{
392 return m_remoteUri;
393}
394
Junxiao Shi13546112015-10-14 19:33:07 -0700395inline void
396Transport::setRemoteUri(const FaceUri& uri)
397{
398 m_remoteUri = uri;
399}
400
Eric Newberrya98bf932015-09-21 00:58:47 -0700401inline ndn::nfd::FaceScope
402Transport::getScope() const
403{
404 return m_scope;
405}
406
Junxiao Shi13546112015-10-14 19:33:07 -0700407inline void
408Transport::setScope(ndn::nfd::FaceScope scope)
409{
410 m_scope = scope;
411}
412
Eric Newberrya98bf932015-09-21 00:58:47 -0700413inline ndn::nfd::FacePersistency
414Transport::getPersistency() const
415{
416 return m_persistency;
417}
418
Eric Newberrya98bf932015-09-21 00:58:47 -0700419inline ndn::nfd::LinkType
420Transport::getLinkType() const
421{
422 return m_linkType;
423}
424
Eric Newberrya98bf932015-09-21 00:58:47 -0700425inline void
426Transport::setLinkType(ndn::nfd::LinkType linkType)
427{
428 m_linkType = linkType;
429}
430
Junxiao Shi13546112015-10-14 19:33:07 -0700431inline ssize_t
432Transport::getMtu() const
433{
434 return m_mtu;
435}
436
437inline void
438Transport::setMtu(ssize_t mtu)
439{
440 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
441 m_mtu = mtu;
442}
443
444inline TransportState
445Transport::getState() const
446{
447 return m_state;
448}
449
Eric Newberryc64d30a2015-12-26 11:07:27 -0700450inline time::steady_clock::TimePoint
451Transport::getExpirationTime() const
452{
453 return m_expirationTime;
454}
455
456inline void
457Transport::setExpirationTime(const time::steady_clock::TimePoint& expirationTime)
458{
459 m_expirationTime = expirationTime;
460}
461
Eric Newberrya98bf932015-09-21 00:58:47 -0700462std::ostream&
463operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
464
465template<typename T>
466typename std::enable_if<std::is_base_of<Transport, T>::value &&
467 !std::is_same<Transport, T>::value, std::ostream&>::type
468operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
469{
470 return os << FaceLogHelper<Transport>(flh.obj);
471}
472
473} // namespace face
474} // namespace nfd
475
476#endif // NFD_DAEMON_FACE_TRANSPORT_HPP