blob: b0d10f449088c365cacd883babe0d7e9e93a6096 [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
29#include "common.hpp"
30
31#include "face-counters.hpp"
32#include "face-log.hpp"
33
34namespace nfd {
35namespace face {
36
37class LpFace;
38class LinkService;
39
40/** \brief indicates the state of a transport
41 */
42enum class TransportState {
43 NONE,
44 UP, ///< the transport is up
45 DOWN, ///< the transport is down temporarily, and is being recovered
46 CLOSING, ///< the transport is requested to be closed
47 FAILED, ///< the transport is being closed due to a failure
48 CLOSED ///< the transport is closed, and can be safely deallocated
49};
50
51std::ostream&
52operator<<(std::ostream& os, TransportState state);
53
Junxiao Shi57df2882015-11-11 06:12:35 -070054/** \brief counters provided by Transport
55 * \note The type name 'TransportCounters' is implementation detail.
56 * Use 'Transport::Counters' in public API.
57 */
58class TransportCounters
59{
60public:
61 /** \brief count of incoming packets
62 *
63 * A 'packet' typically means a top-level TLV block.
64 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
65 * would not be counted.
66 */
67 PacketCounter nInPackets;
68
69 /** \brief count of outgoing packets
70 *
71 * A 'packet' typically means a top-level TLV block.
72 * This counter is incremented only if transport is UP.
73 */
74 PacketCounter nOutPackets;
75
76 /** \brief total incoming bytes
77 *
78 * This counter includes headers imposed by NFD (such as NDNLP),
79 * but excludes overhead of underlying protocol (such as IP header).
80 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
81 * would not be counted.
82 */
83 ByteCounter nInBytes;
84
85 /** \brief total outgoing bytes
86 *
87 * This counter includes headers imposed by NFD (such as NDNLP),
88 * but excludes overhead of underlying protocol (such as IP header).
89 * This counter is increased only if transport is UP.
90 */
91 ByteCounter nOutBytes;
92};
93
Junxiao Shi13546112015-10-14 19:33:07 -070094/** \brief indicates the transport has no limit on payload size
95 */
96const ssize_t MTU_UNLIMITED = -1;
97
Junxiao Shi5b8a2b22015-10-22 17:20:44 -070098/** \brief (for internal use) indicates MTU field is unset
99 */
100const ssize_t MTU_INVALID = -2;
101
Eric Newberrya98bf932015-09-21 00:58:47 -0700102/** \brief the lower part of an LpFace
103 * \sa LpFace
104 */
Junxiao Shi57df2882015-11-11 06:12:35 -0700105class Transport : protected virtual TransportCounters, noncopyable
Eric Newberrya98bf932015-09-21 00:58:47 -0700106{
107public:
108 /** \brief identifies an endpoint on the link
109 */
110 typedef uint64_t EndpointId;
111
112 /** \brief stores a packet along with the remote endpoint
113 */
114 class Packet
115 {
116 public:
117 Packet() = default;
118
119 explicit
120 Packet(Block&& packet);
121
122 public:
123 /** \brief the packet as a TLV block
124 */
125 Block packet;
126
127 /** \brief identifies the remote endpoint
128 *
129 * This ID is only meaningful in the context of the same Transport.
130 * Incoming packets from the same remote endpoint have the same EndpointId,
131 * and incoming packets from different remote endpoints have different EndpointIds.
132 */
133 EndpointId remoteEndpoint;
134 };
135
Junxiao Shi57df2882015-11-11 06:12:35 -0700136 /** \brief counters provided by Transport
137 */
138 typedef TransportCounters Counters;
139
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700140 /** \brief constructor
141 *
142 * Transport constructor initializes static properties to invalid values.
143 * Subclass constructor must explicitly set every static property.
144 *
145 * This constructor initializes TransportState to UP;
146 * subclass constructor can rely on this default value.
147 */
Eric Newberrya98bf932015-09-21 00:58:47 -0700148 Transport();
149
150 virtual
151 ~Transport();
152
153public:
154 /** \brief set Face and LinkService for Transport
155 * \pre setFaceAndLinkService has not been called
156 */
157 void
158 setFaceAndLinkService(LpFace& face, LinkService& service);
159
160 /** \return Face to which this Transport is attached
161 */
162 const LpFace*
163 getFace() const;
164
165 /** \return LinkService to which this Transport is attached
166 */
167 const LinkService*
168 getLinkService() const;
169
170 /** \return LinkService to which this Transport is attached
171 */
172 LinkService*
173 getLinkService();
174
Junxiao Shi57df2882015-11-11 06:12:35 -0700175 virtual const Counters&
176 getCounters() const;
177
Eric Newberrya98bf932015-09-21 00:58:47 -0700178public: // upper interface
179 /** \brief request the transport to be closed
180 *
181 * This operation is effective only if transport is in UP or DOWN state,
182 * otherwise it has no effect.
183 * The transport changes state to CLOSING, and performs cleanup procedure.
184 * The state will be changed to CLOSED when cleanup is complete, which may
185 * happen synchronously or asynchronously.
186 */
187 void
188 close();
189
190 /** \brief send a link-layer packet
Junxiao Shi13546112015-10-14 19:33:07 -0700191 * \note This operation has no effect if \p getState() is neither UP nor DOWN
192 * \warning undefined behavior if packet size exceeds MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700193 */
194 void
195 send(Packet&& packet);
196
197protected: // upper interface to be invoked by subclass
198 /** \brief receive a link-layer packet
Junxiao Shi13546112015-10-14 19:33:07 -0700199 * \warning undefined behavior if packet size exceeds MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700200 */
201 void
202 receive(Packet&& packet);
203
204public: // static properties
205 /** \return a FaceUri representing local endpoint
206 */
207 FaceUri
208 getLocalUri() const;
209
210 /** \return a FaceUri representing remote endpoint
211 */
212 FaceUri
213 getRemoteUri() const;
214
215 /** \return whether face is local or non-local for scope control purpose
216 */
217 ndn::nfd::FaceScope
218 getScope() const;
219
220 /** \return face persistency setting
221 */
222 ndn::nfd::FacePersistency
223 getPersistency() const;
224
225 /** \brief changes face persistency setting
226 */
227 void
228 setPersistency(ndn::nfd::FacePersistency persistency);
229
230 /** \return whether face is point-to-point or multi-access
231 */
232 ndn::nfd::LinkType
233 getLinkType() const;
234
Junxiao Shi13546112015-10-14 19:33:07 -0700235 /** \return maximum payload size
236 * \retval MTU_UNLIMITED transport has no limit on payload size
237 *
238 * This size is the maximum packet size that can be sent or received through this transport.
239 *
240 * For a datagram-based transport, this is typically the Maximum Transmission Unit (MTU),
241 * after the overhead of headers introduced by the transport has been accounted for.
242 * For a stream-based transport, this is typically unlimited (MTU_UNLIMITED).
243 */
244 ssize_t
245 getMtu() const;
246
Eric Newberrya98bf932015-09-21 00:58:47 -0700247public: // dynamic properties
248 /** \return transport state
249 */
250 TransportState
251 getState() const;
252
253 /** \brief signals when transport state changes
254 */
255 signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;
256
257protected: // properties to be set by subclass
258 void
259 setLocalUri(const FaceUri& uri);
260
261 void
262 setRemoteUri(const FaceUri& uri);
263
264 void
265 setScope(ndn::nfd::FaceScope scope);
266
267 void
268 setLinkType(ndn::nfd::LinkType linkType);
269
Junxiao Shi13546112015-10-14 19:33:07 -0700270 void
271 setMtu(ssize_t mtu);
272
Eric Newberrya98bf932015-09-21 00:58:47 -0700273 /** \brief set transport state
274 *
275 * Only the following transitions are valid:
276 * UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
277 *
278 * \throw std::runtime_error transition is invalid.
279 */
280 void
281 setState(TransportState newState);
282
283protected: // to be overridden by subclass
284 /** \brief invoked before persistency is changed
285 * \throw std::invalid_argument new persistency is not supported
286 * \throw std::runtime_error transition is disallowed
Eric Newberrya98bf932015-09-21 00:58:47 -0700287 */
288 virtual void
Davide Pesavento8728a252015-11-06 04:01:22 +0100289 beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) = 0;
Eric Newberrya98bf932015-09-21 00:58:47 -0700290
291 /** \brief performs Transport specific operations to close the transport
292 *
Junxiao Shi13546112015-10-14 19:33:07 -0700293 * This is invoked once by \p close() after changing state to CLOSING.
294 * It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
295 *
Eric Newberrya98bf932015-09-21 00:58:47 -0700296 * When the cleanup procedure is complete, this method should change state to CLOSED.
Junxiao Shi13546112015-10-14 19:33:07 -0700297 * This transition can happen synchronously or asynchronously.
Eric Newberrya98bf932015-09-21 00:58:47 -0700298 */
299 virtual void
300 doClose() = 0;
301
302private: // to be overridden by subclass
303 /** \brief performs Transport specific operations to send a packet
304 * \param packet the packet, which must be a well-formed TLV block
Junxiao Shi13546112015-10-14 19:33:07 -0700305 * \pre state is either UP or DOWN
Eric Newberrya98bf932015-09-21 00:58:47 -0700306 */
307 virtual void
308 doSend(Packet&& packet) = 0;
309
310private:
311 LpFace* m_face;
312 LinkService* m_service;
313 FaceUri m_localUri;
314 FaceUri m_remoteUri;
315 ndn::nfd::FaceScope m_scope;
316 ndn::nfd::FacePersistency m_persistency;
317 ndn::nfd::LinkType m_linkType;
Junxiao Shi13546112015-10-14 19:33:07 -0700318 ssize_t m_mtu;
Eric Newberrya98bf932015-09-21 00:58:47 -0700319 TransportState m_state;
Junxiao Shi57df2882015-11-11 06:12:35 -0700320 LinkLayerCounters* m_oldCounters; // TODO#3177 change into LinkCounters
Eric Newberrya98bf932015-09-21 00:58:47 -0700321};
322
323inline const LpFace*
324Transport::getFace() const
325{
326 return m_face;
327}
328
329inline const LinkService*
330Transport::getLinkService() const
331{
332 return m_service;
333}
334
335inline LinkService*
336Transport::getLinkService()
337{
338 return m_service;
339}
340
Junxiao Shi57df2882015-11-11 06:12:35 -0700341inline const Transport::Counters&
342Transport::getCounters() const
343{
344 return *this;
345}
346
Eric Newberrya98bf932015-09-21 00:58:47 -0700347inline FaceUri
348Transport::getLocalUri() const
349{
350 return m_localUri;
351}
352
Junxiao Shi13546112015-10-14 19:33:07 -0700353inline void
354Transport::setLocalUri(const FaceUri& uri)
355{
356 m_localUri = uri;
357}
358
Eric Newberrya98bf932015-09-21 00:58:47 -0700359inline FaceUri
360Transport::getRemoteUri() const
361{
362 return m_remoteUri;
363}
364
Junxiao Shi13546112015-10-14 19:33:07 -0700365inline void
366Transport::setRemoteUri(const FaceUri& uri)
367{
368 m_remoteUri = uri;
369}
370
Eric Newberrya98bf932015-09-21 00:58:47 -0700371inline ndn::nfd::FaceScope
372Transport::getScope() const
373{
374 return m_scope;
375}
376
Junxiao Shi13546112015-10-14 19:33:07 -0700377inline void
378Transport::setScope(ndn::nfd::FaceScope scope)
379{
380 m_scope = scope;
381}
382
Eric Newberrya98bf932015-09-21 00:58:47 -0700383inline ndn::nfd::FacePersistency
384Transport::getPersistency() const
385{
386 return m_persistency;
387}
388
Eric Newberrya98bf932015-09-21 00:58:47 -0700389inline ndn::nfd::LinkType
390Transport::getLinkType() const
391{
392 return m_linkType;
393}
394
Eric Newberrya98bf932015-09-21 00:58:47 -0700395inline void
396Transport::setLinkType(ndn::nfd::LinkType linkType)
397{
398 m_linkType = linkType;
399}
400
Junxiao Shi13546112015-10-14 19:33:07 -0700401inline ssize_t
402Transport::getMtu() const
403{
404 return m_mtu;
405}
406
407inline void
408Transport::setMtu(ssize_t mtu)
409{
410 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
411 m_mtu = mtu;
412}
413
414inline TransportState
415Transport::getState() const
416{
417 return m_state;
418}
419
Eric Newberrya98bf932015-09-21 00:58:47 -0700420std::ostream&
421operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
422
423template<typename T>
424typename std::enable_if<std::is_base_of<Transport, T>::value &&
425 !std::is_same<Transport, T>::value, std::ostream&>::type
426operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
427{
428 return os << FaceLogHelper<Transport>(flh.obj);
429}
430
431} // namespace face
432} // namespace nfd
433
434#endif // NFD_DAEMON_FACE_TRANSPORT_HPP