blob: 8735de682b8cbba6a22971305e527721e97d742e [file] [log] [blame]
Eric Newberrya98bf932015-09-21 00:58:47 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2015, Regents of the University of California,
4 * 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"
31
32namespace nfd {
33namespace face {
34
35class LpFace;
36class LinkService;
37
38/** \brief indicates the state of a transport
39 */
40enum class TransportState {
41 NONE,
42 UP, ///< the transport is up
43 DOWN, ///< the transport is down temporarily, and is being recovered
44 CLOSING, ///< the transport is requested to be closed
45 FAILED, ///< the transport is being closed due to a failure
46 CLOSED ///< the transport is closed, and can be safely deallocated
47};
48
49std::ostream&
50operator<<(std::ostream& os, TransportState state);
51
Junxiao Shi57df2882015-11-11 06:12:35 -070052/** \brief counters provided by Transport
53 * \note The type name 'TransportCounters' is implementation detail.
54 * Use 'Transport::Counters' in public API.
55 */
56class TransportCounters
57{
58public:
59 /** \brief count of incoming packets
60 *
61 * A 'packet' typically means a top-level TLV block.
62 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
63 * would not be counted.
64 */
65 PacketCounter nInPackets;
66
67 /** \brief count of outgoing packets
68 *
69 * A 'packet' typically means a top-level TLV block.
70 * This counter is incremented only if transport is UP.
71 */
72 PacketCounter nOutPackets;
73
74 /** \brief total incoming bytes
75 *
76 * This counter includes headers imposed by NFD (such as NDNLP),
77 * but excludes overhead of underlying protocol (such as IP header).
78 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
79 * would not be counted.
80 */
81 ByteCounter nInBytes;
82
83 /** \brief total outgoing bytes
84 *
85 * This counter includes headers imposed by NFD (such as NDNLP),
86 * but excludes overhead of underlying protocol (such as IP header).
87 * This counter is increased only if transport is UP.
88 */
89 ByteCounter nOutBytes;
90};
91
Junxiao Shi13546112015-10-14 19:33:07 -070092/** \brief indicates the transport has no limit on payload size
93 */
94const ssize_t MTU_UNLIMITED = -1;
95
Junxiao Shi5b8a2b22015-10-22 17:20:44 -070096/** \brief (for internal use) indicates MTU field is unset
97 */
98const ssize_t MTU_INVALID = -2;
99
Eric Newberrya98bf932015-09-21 00:58:47 -0700100/** \brief the lower part of an LpFace
101 * \sa LpFace
102 */
Junxiao Shi57df2882015-11-11 06:12:35 -0700103class Transport : protected virtual TransportCounters, noncopyable
Eric Newberrya98bf932015-09-21 00:58:47 -0700104{
105public:
106 /** \brief identifies an endpoint on the link
107 */
108 typedef uint64_t EndpointId;
109
110 /** \brief stores a packet along with the remote endpoint
111 */
112 class Packet
113 {
114 public:
115 Packet() = default;
116
117 explicit
118 Packet(Block&& packet);
119
120 public:
121 /** \brief the packet as a TLV block
122 */
123 Block packet;
124
125 /** \brief identifies the remote endpoint
126 *
127 * This ID is only meaningful in the context of the same Transport.
128 * Incoming packets from the same remote endpoint have the same EndpointId,
129 * and incoming packets from different remote endpoints have different EndpointIds.
130 */
131 EndpointId remoteEndpoint;
132 };
133
Junxiao Shi57df2882015-11-11 06:12:35 -0700134 /** \brief counters provided by Transport
135 */
136 typedef TransportCounters Counters;
137
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700138 /** \brief constructor
139 *
140 * Transport constructor initializes static properties to invalid values.
141 * Subclass constructor must explicitly set every static property.
142 *
143 * This constructor initializes TransportState to UP;
144 * subclass constructor can rely on this default value.
145 */
Eric Newberrya98bf932015-09-21 00:58:47 -0700146 Transport();
147
148 virtual
149 ~Transport();
150
151public:
152 /** \brief set Face and LinkService for Transport
153 * \pre setFaceAndLinkService has not been called
154 */
155 void
156 setFaceAndLinkService(LpFace& face, LinkService& service);
157
158 /** \return Face to which this Transport is attached
159 */
160 const LpFace*
161 getFace() const;
162
163 /** \return LinkService to which this Transport is attached
164 */
165 const LinkService*
166 getLinkService() const;
167
168 /** \return LinkService to which this Transport is attached
169 */
170 LinkService*
171 getLinkService();
172
Junxiao Shi57df2882015-11-11 06:12:35 -0700173 virtual const Counters&
174 getCounters() const;
175
Eric Newberrya98bf932015-09-21 00:58:47 -0700176public: // upper interface
177 /** \brief request the transport to be closed
178 *
179 * This operation is effective only if transport is in UP or DOWN state,
180 * otherwise it has no effect.
181 * The transport changes state to CLOSING, and performs cleanup procedure.
182 * The state will be changed to CLOSED when cleanup is complete, which may
183 * happen synchronously or asynchronously.
184 */
185 void
186 close();
187
188 /** \brief send a link-layer packet
Junxiao Shi13546112015-10-14 19:33:07 -0700189 * \note This operation has no effect if \p getState() is neither UP nor DOWN
190 * \warning undefined behavior if packet size exceeds MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700191 */
192 void
193 send(Packet&& packet);
194
195protected: // upper interface to be invoked by subclass
196 /** \brief receive a link-layer packet
Junxiao Shi13546112015-10-14 19:33:07 -0700197 * \warning undefined behavior if packet size exceeds MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700198 */
199 void
200 receive(Packet&& packet);
201
202public: // static properties
203 /** \return a FaceUri representing local endpoint
204 */
205 FaceUri
206 getLocalUri() const;
207
208 /** \return a FaceUri representing remote endpoint
209 */
210 FaceUri
211 getRemoteUri() const;
212
213 /** \return whether face is local or non-local for scope control purpose
214 */
215 ndn::nfd::FaceScope
216 getScope() const;
217
218 /** \return face persistency setting
219 */
220 ndn::nfd::FacePersistency
221 getPersistency() const;
222
223 /** \brief changes face persistency setting
224 */
225 void
226 setPersistency(ndn::nfd::FacePersistency persistency);
227
228 /** \return whether face is point-to-point or multi-access
229 */
230 ndn::nfd::LinkType
231 getLinkType() const;
232
Junxiao Shi13546112015-10-14 19:33:07 -0700233 /** \return maximum payload size
234 * \retval MTU_UNLIMITED transport has no limit on payload size
235 *
236 * This size is the maximum packet size that can be sent or received through this transport.
237 *
238 * For a datagram-based transport, this is typically the Maximum Transmission Unit (MTU),
239 * after the overhead of headers introduced by the transport has been accounted for.
240 * For a stream-based transport, this is typically unlimited (MTU_UNLIMITED).
241 */
242 ssize_t
243 getMtu() const;
244
Eric Newberrya98bf932015-09-21 00:58:47 -0700245public: // dynamic properties
246 /** \return transport state
247 */
248 TransportState
249 getState() const;
250
251 /** \brief signals when transport state changes
252 */
253 signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;
254
255protected: // properties to be set by subclass
256 void
257 setLocalUri(const FaceUri& uri);
258
259 void
260 setRemoteUri(const FaceUri& uri);
261
262 void
263 setScope(ndn::nfd::FaceScope scope);
264
265 void
266 setLinkType(ndn::nfd::LinkType linkType);
267
Junxiao Shi13546112015-10-14 19:33:07 -0700268 void
269 setMtu(ssize_t mtu);
270
Eric Newberrya98bf932015-09-21 00:58:47 -0700271 /** \brief set transport state
272 *
273 * Only the following transitions are valid:
274 * UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
275 *
276 * \throw std::runtime_error transition is invalid.
277 */
278 void
279 setState(TransportState newState);
280
281protected: // to be overridden by subclass
282 /** \brief invoked before persistency is changed
283 * \throw std::invalid_argument new persistency is not supported
284 * \throw std::runtime_error transition is disallowed
Eric Newberrya98bf932015-09-21 00:58:47 -0700285 */
286 virtual void
Davide Pesavento8728a252015-11-06 04:01:22 +0100287 beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) = 0;
Eric Newberrya98bf932015-09-21 00:58:47 -0700288
289 /** \brief performs Transport specific operations to close the transport
290 *
Junxiao Shi13546112015-10-14 19:33:07 -0700291 * This is invoked once by \p close() after changing state to CLOSING.
292 * It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
293 *
Eric Newberrya98bf932015-09-21 00:58:47 -0700294 * When the cleanup procedure is complete, this method should change state to CLOSED.
Junxiao Shi13546112015-10-14 19:33:07 -0700295 * This transition can happen synchronously or asynchronously.
Eric Newberrya98bf932015-09-21 00:58:47 -0700296 */
297 virtual void
298 doClose() = 0;
299
300private: // to be overridden by subclass
301 /** \brief performs Transport specific operations to send a packet
302 * \param packet the packet, which must be a well-formed TLV block
Junxiao Shi13546112015-10-14 19:33:07 -0700303 * \pre state is either UP or DOWN
Eric Newberrya98bf932015-09-21 00:58:47 -0700304 */
305 virtual void
306 doSend(Packet&& packet) = 0;
307
308private:
309 LpFace* m_face;
310 LinkService* m_service;
311 FaceUri m_localUri;
312 FaceUri m_remoteUri;
313 ndn::nfd::FaceScope m_scope;
314 ndn::nfd::FacePersistency m_persistency;
315 ndn::nfd::LinkType m_linkType;
Junxiao Shi13546112015-10-14 19:33:07 -0700316 ssize_t m_mtu;
Eric Newberrya98bf932015-09-21 00:58:47 -0700317 TransportState m_state;
Eric Newberrya98bf932015-09-21 00:58:47 -0700318};
319
320inline const LpFace*
321Transport::getFace() const
322{
323 return m_face;
324}
325
326inline const LinkService*
327Transport::getLinkService() const
328{
329 return m_service;
330}
331
332inline LinkService*
333Transport::getLinkService()
334{
335 return m_service;
336}
337
Junxiao Shi57df2882015-11-11 06:12:35 -0700338inline const Transport::Counters&
339Transport::getCounters() const
340{
341 return *this;
342}
343
Eric Newberrya98bf932015-09-21 00:58:47 -0700344inline FaceUri
345Transport::getLocalUri() const
346{
347 return m_localUri;
348}
349
Junxiao Shi13546112015-10-14 19:33:07 -0700350inline void
351Transport::setLocalUri(const FaceUri& uri)
352{
353 m_localUri = uri;
354}
355
Eric Newberrya98bf932015-09-21 00:58:47 -0700356inline FaceUri
357Transport::getRemoteUri() const
358{
359 return m_remoteUri;
360}
361
Junxiao Shi13546112015-10-14 19:33:07 -0700362inline void
363Transport::setRemoteUri(const FaceUri& uri)
364{
365 m_remoteUri = uri;
366}
367
Eric Newberrya98bf932015-09-21 00:58:47 -0700368inline ndn::nfd::FaceScope
369Transport::getScope() const
370{
371 return m_scope;
372}
373
Junxiao Shi13546112015-10-14 19:33:07 -0700374inline void
375Transport::setScope(ndn::nfd::FaceScope scope)
376{
377 m_scope = scope;
378}
379
Eric Newberrya98bf932015-09-21 00:58:47 -0700380inline ndn::nfd::FacePersistency
381Transport::getPersistency() const
382{
383 return m_persistency;
384}
385
Eric Newberrya98bf932015-09-21 00:58:47 -0700386inline ndn::nfd::LinkType
387Transport::getLinkType() const
388{
389 return m_linkType;
390}
391
Eric Newberrya98bf932015-09-21 00:58:47 -0700392inline void
393Transport::setLinkType(ndn::nfd::LinkType linkType)
394{
395 m_linkType = linkType;
396}
397
Junxiao Shi13546112015-10-14 19:33:07 -0700398inline ssize_t
399Transport::getMtu() const
400{
401 return m_mtu;
402}
403
404inline void
405Transport::setMtu(ssize_t mtu)
406{
407 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
408 m_mtu = mtu;
409}
410
411inline TransportState
412Transport::getState() const
413{
414 return m_state;
415}
416
Eric Newberrya98bf932015-09-21 00:58:47 -0700417std::ostream&
418operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
419
420template<typename T>
421typename std::enable_if<std::is_base_of<Transport, T>::value &&
422 !std::is_same<Transport, T>::value, std::ostream&>::type
423operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
424{
425 return os << FaceLogHelper<Transport>(flh.obj);
426}
427
428} // namespace face
429} // namespace nfd
430
431#endif // NFD_DAEMON_FACE_TRANSPORT_HPP