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