blob: 55efe3b7020cb8b25ebec7cac3de6aab4d952bff [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
240 *
241 * Base class implementation does nothing.
242 */
243 virtual void
244 beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
245 {
246 }
247
248 /** \brief performs Transport specific operations to close the transport
249 *
Junxiao Shi13546112015-10-14 19:33:07 -0700250 * This is invoked once by \p close() after changing state to CLOSING.
251 * It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
252 *
Eric Newberrya98bf932015-09-21 00:58:47 -0700253 * When the cleanup procedure is complete, this method should change state to CLOSED.
Junxiao Shi13546112015-10-14 19:33:07 -0700254 * This transition can happen synchronously or asynchronously.
Eric Newberrya98bf932015-09-21 00:58:47 -0700255 */
256 virtual void
257 doClose() = 0;
258
259private: // to be overridden by subclass
260 /** \brief performs Transport specific operations to send a packet
261 * \param packet the packet, which must be a well-formed TLV block
Junxiao Shi13546112015-10-14 19:33:07 -0700262 * \pre state is either UP or DOWN
Eric Newberrya98bf932015-09-21 00:58:47 -0700263 */
264 virtual void
265 doSend(Packet&& packet) = 0;
266
267private:
268 LpFace* m_face;
269 LinkService* m_service;
270 FaceUri m_localUri;
271 FaceUri m_remoteUri;
272 ndn::nfd::FaceScope m_scope;
273 ndn::nfd::FacePersistency m_persistency;
274 ndn::nfd::LinkType m_linkType;
Junxiao Shi13546112015-10-14 19:33:07 -0700275 ssize_t m_mtu;
Eric Newberrya98bf932015-09-21 00:58:47 -0700276 TransportState m_state;
277 LinkLayerCounters* m_counters; // TODO#3177 change into LinkCounters
278};
279
280inline const LpFace*
281Transport::getFace() const
282{
283 return m_face;
284}
285
286inline const LinkService*
287Transport::getLinkService() const
288{
289 return m_service;
290}
291
292inline LinkService*
293Transport::getLinkService()
294{
295 return m_service;
296}
297
298inline FaceUri
299Transport::getLocalUri() const
300{
301 return m_localUri;
302}
303
Junxiao Shi13546112015-10-14 19:33:07 -0700304inline void
305Transport::setLocalUri(const FaceUri& uri)
306{
307 m_localUri = uri;
308}
309
Eric Newberrya98bf932015-09-21 00:58:47 -0700310inline FaceUri
311Transport::getRemoteUri() const
312{
313 return m_remoteUri;
314}
315
Junxiao Shi13546112015-10-14 19:33:07 -0700316inline void
317Transport::setRemoteUri(const FaceUri& uri)
318{
319 m_remoteUri = uri;
320}
321
Eric Newberrya98bf932015-09-21 00:58:47 -0700322inline ndn::nfd::FaceScope
323Transport::getScope() const
324{
325 return m_scope;
326}
327
Junxiao Shi13546112015-10-14 19:33:07 -0700328inline void
329Transport::setScope(ndn::nfd::FaceScope scope)
330{
331 m_scope = scope;
332}
333
Eric Newberrya98bf932015-09-21 00:58:47 -0700334inline ndn::nfd::FacePersistency
335Transport::getPersistency() const
336{
337 return m_persistency;
338}
339
340inline void
341Transport::setPersistency(ndn::nfd::FacePersistency persistency)
342{
343 this->beforeChangePersistency(persistency);
344 m_persistency = persistency;
345}
346
347inline ndn::nfd::LinkType
348Transport::getLinkType() const
349{
350 return m_linkType;
351}
352
Eric Newberrya98bf932015-09-21 00:58:47 -0700353inline void
354Transport::setLinkType(ndn::nfd::LinkType linkType)
355{
356 m_linkType = linkType;
357}
358
Junxiao Shi13546112015-10-14 19:33:07 -0700359inline ssize_t
360Transport::getMtu() const
361{
362 return m_mtu;
363}
364
365inline void
366Transport::setMtu(ssize_t mtu)
367{
368 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
369 m_mtu = mtu;
370}
371
372inline TransportState
373Transport::getState() const
374{
375 return m_state;
376}
377
Eric Newberrya98bf932015-09-21 00:58:47 -0700378std::ostream&
379operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
380
381template<typename T>
382typename std::enable_if<std::is_base_of<Transport, T>::value &&
383 !std::is_same<Transport, T>::value, std::ostream&>::type
384operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
385{
386 return os << FaceLogHelper<Transport>(flh.obj);
387}
388
389} // namespace face
390} // namespace nfd
391
392#endif // NFD_DAEMON_FACE_TRANSPORT_HPP