blob: d069a0e564d54f229023a6e881e384ac62d21e7e [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 Shi13546112015-10-14 19:33:07 -070054/** \brief indicates the transport has no limit on payload size
55 */
56const ssize_t MTU_UNLIMITED = -1;
57
Junxiao Shi5b8a2b22015-10-22 17:20:44 -070058/** \brief (for internal use) indicates MTU field is unset
59 */
60const ssize_t MTU_INVALID = -2;
61
Eric Newberrya98bf932015-09-21 00:58:47 -070062/** \brief the lower part of an LpFace
63 * \sa LpFace
64 */
65class Transport : noncopyable
66{
67public:
68 /** \brief identifies an endpoint on the link
69 */
70 typedef uint64_t EndpointId;
71
72 /** \brief stores a packet along with the remote endpoint
73 */
74 class Packet
75 {
76 public:
77 Packet() = default;
78
79 explicit
80 Packet(Block&& packet);
81
82 public:
83 /** \brief the packet as a TLV block
84 */
85 Block packet;
86
87 /** \brief identifies the remote endpoint
88 *
89 * This ID is only meaningful in the context of the same Transport.
90 * Incoming packets from the same remote endpoint have the same EndpointId,
91 * and incoming packets from different remote endpoints have different EndpointIds.
92 */
93 EndpointId remoteEndpoint;
94 };
95
Junxiao Shi5b8a2b22015-10-22 17:20:44 -070096 /** \brief constructor
97 *
98 * Transport constructor initializes static properties to invalid values.
99 * Subclass constructor must explicitly set every static property.
100 *
101 * This constructor initializes TransportState to UP;
102 * subclass constructor can rely on this default value.
103 */
Eric Newberrya98bf932015-09-21 00:58:47 -0700104 Transport();
105
106 virtual
107 ~Transport();
108
109public:
110 /** \brief set Face and LinkService for Transport
111 * \pre setFaceAndLinkService has not been called
112 */
113 void
114 setFaceAndLinkService(LpFace& face, LinkService& service);
115
116 /** \return Face to which this Transport is attached
117 */
118 const LpFace*
119 getFace() const;
120
121 /** \return LinkService to which this Transport is attached
122 */
123 const LinkService*
124 getLinkService() const;
125
126 /** \return LinkService to which this Transport is attached
127 */
128 LinkService*
129 getLinkService();
130
131public: // upper interface
132 /** \brief request the transport to be closed
133 *
134 * This operation is effective only if transport is in UP or DOWN state,
135 * otherwise it has no effect.
136 * The transport changes state to CLOSING, and performs cleanup procedure.
137 * The state will be changed to CLOSED when cleanup is complete, which may
138 * happen synchronously or asynchronously.
139 */
140 void
141 close();
142
143 /** \brief send a link-layer packet
Junxiao Shi13546112015-10-14 19:33:07 -0700144 * \note This operation has no effect if \p getState() is neither UP nor DOWN
145 * \warning undefined behavior if packet size exceeds MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700146 */
147 void
148 send(Packet&& packet);
149
150protected: // upper interface to be invoked by subclass
151 /** \brief receive a link-layer packet
Junxiao Shi13546112015-10-14 19:33:07 -0700152 * \warning undefined behavior if packet size exceeds MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700153 */
154 void
155 receive(Packet&& packet);
156
157public: // static properties
158 /** \return a FaceUri representing local endpoint
159 */
160 FaceUri
161 getLocalUri() const;
162
163 /** \return a FaceUri representing remote endpoint
164 */
165 FaceUri
166 getRemoteUri() const;
167
168 /** \return whether face is local or non-local for scope control purpose
169 */
170 ndn::nfd::FaceScope
171 getScope() const;
172
173 /** \return face persistency setting
174 */
175 ndn::nfd::FacePersistency
176 getPersistency() const;
177
178 /** \brief changes face persistency setting
179 */
180 void
181 setPersistency(ndn::nfd::FacePersistency persistency);
182
183 /** \return whether face is point-to-point or multi-access
184 */
185 ndn::nfd::LinkType
186 getLinkType() const;
187
Junxiao Shi13546112015-10-14 19:33:07 -0700188 /** \return maximum payload size
189 * \retval MTU_UNLIMITED transport has no limit on payload size
190 *
191 * This size is the maximum packet size that can be sent or received through this transport.
192 *
193 * For a datagram-based transport, this is typically the Maximum Transmission Unit (MTU),
194 * after the overhead of headers introduced by the transport has been accounted for.
195 * For a stream-based transport, this is typically unlimited (MTU_UNLIMITED).
196 */
197 ssize_t
198 getMtu() const;
199
Eric Newberrya98bf932015-09-21 00:58:47 -0700200public: // dynamic properties
201 /** \return transport state
202 */
203 TransportState
204 getState() const;
205
206 /** \brief signals when transport state changes
207 */
208 signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;
209
210protected: // properties to be set by subclass
211 void
212 setLocalUri(const FaceUri& uri);
213
214 void
215 setRemoteUri(const FaceUri& uri);
216
217 void
218 setScope(ndn::nfd::FaceScope scope);
219
220 void
221 setLinkType(ndn::nfd::LinkType linkType);
222
Junxiao Shi13546112015-10-14 19:33:07 -0700223 void
224 setMtu(ssize_t mtu);
225
Eric Newberrya98bf932015-09-21 00:58:47 -0700226 /** \brief set transport state
227 *
228 * Only the following transitions are valid:
229 * UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
230 *
231 * \throw std::runtime_error transition is invalid.
232 */
233 void
234 setState(TransportState newState);
235
236protected: // to be overridden by subclass
237 /** \brief invoked before persistency is changed
238 * \throw std::invalid_argument new persistency is not supported
239 * \throw std::runtime_error transition is disallowed
Eric Newberrya98bf932015-09-21 00:58:47 -0700240 */
241 virtual void
Davide Pesavento8728a252015-11-06 04:01:22 +0100242 beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) = 0;
Eric Newberrya98bf932015-09-21 00:58:47 -0700243
244 /** \brief performs Transport specific operations to close the transport
245 *
Junxiao Shi13546112015-10-14 19:33:07 -0700246 * This is invoked once by \p close() after changing state to CLOSING.
247 * It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
248 *
Eric Newberrya98bf932015-09-21 00:58:47 -0700249 * When the cleanup procedure is complete, this method should change state to CLOSED.
Junxiao Shi13546112015-10-14 19:33:07 -0700250 * This transition can happen synchronously or asynchronously.
Eric Newberrya98bf932015-09-21 00:58:47 -0700251 */
252 virtual void
253 doClose() = 0;
254
255private: // to be overridden by subclass
256 /** \brief performs Transport specific operations to send a packet
257 * \param packet the packet, which must be a well-formed TLV block
Junxiao Shi13546112015-10-14 19:33:07 -0700258 * \pre state is either UP or DOWN
Eric Newberrya98bf932015-09-21 00:58:47 -0700259 */
260 virtual void
261 doSend(Packet&& packet) = 0;
262
263private:
264 LpFace* m_face;
265 LinkService* m_service;
266 FaceUri m_localUri;
267 FaceUri m_remoteUri;
268 ndn::nfd::FaceScope m_scope;
269 ndn::nfd::FacePersistency m_persistency;
270 ndn::nfd::LinkType m_linkType;
Junxiao Shi13546112015-10-14 19:33:07 -0700271 ssize_t m_mtu;
Eric Newberrya98bf932015-09-21 00:58:47 -0700272 TransportState m_state;
273 LinkLayerCounters* m_counters; // TODO#3177 change into LinkCounters
274};
275
276inline const LpFace*
277Transport::getFace() const
278{
279 return m_face;
280}
281
282inline const LinkService*
283Transport::getLinkService() const
284{
285 return m_service;
286}
287
288inline LinkService*
289Transport::getLinkService()
290{
291 return m_service;
292}
293
294inline FaceUri
295Transport::getLocalUri() const
296{
297 return m_localUri;
298}
299
Junxiao Shi13546112015-10-14 19:33:07 -0700300inline void
301Transport::setLocalUri(const FaceUri& uri)
302{
303 m_localUri = uri;
304}
305
Eric Newberrya98bf932015-09-21 00:58:47 -0700306inline FaceUri
307Transport::getRemoteUri() const
308{
309 return m_remoteUri;
310}
311
Junxiao Shi13546112015-10-14 19:33:07 -0700312inline void
313Transport::setRemoteUri(const FaceUri& uri)
314{
315 m_remoteUri = uri;
316}
317
Eric Newberrya98bf932015-09-21 00:58:47 -0700318inline ndn::nfd::FaceScope
319Transport::getScope() const
320{
321 return m_scope;
322}
323
Junxiao Shi13546112015-10-14 19:33:07 -0700324inline void
325Transport::setScope(ndn::nfd::FaceScope scope)
326{
327 m_scope = scope;
328}
329
Eric Newberrya98bf932015-09-21 00:58:47 -0700330inline ndn::nfd::FacePersistency
331Transport::getPersistency() const
332{
333 return m_persistency;
334}
335
Eric Newberrya98bf932015-09-21 00:58:47 -0700336inline ndn::nfd::LinkType
337Transport::getLinkType() const
338{
339 return m_linkType;
340}
341
Eric Newberrya98bf932015-09-21 00:58:47 -0700342inline void
343Transport::setLinkType(ndn::nfd::LinkType linkType)
344{
345 m_linkType = linkType;
346}
347
Junxiao Shi13546112015-10-14 19:33:07 -0700348inline ssize_t
349Transport::getMtu() const
350{
351 return m_mtu;
352}
353
354inline void
355Transport::setMtu(ssize_t mtu)
356{
357 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
358 m_mtu = mtu;
359}
360
361inline TransportState
362Transport::getState() const
363{
364 return m_state;
365}
366
Eric Newberrya98bf932015-09-21 00:58:47 -0700367std::ostream&
368operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
369
370template<typename T>
371typename std::enable_if<std::is_base_of<Transport, T>::value &&
372 !std::is_same<Transport, T>::value, std::ostream&>::type
373operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
374{
375 return os << FaceLogHelper<Transport>(flh.obj);
376}
377
378} // namespace face
379} // namespace nfd
380
381#endif // NFD_DAEMON_FACE_TRANSPORT_HPP