blob: 2725596fbf81c05d9c0a602ce89d5e8125062b74 [file] [log] [blame]
Eric Newberrya98bf932015-09-21 00:58:47 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberryb49313d2017-12-24 20:22:27 -07002/*
Davide Pesaventob7bfcb92022-05-22 23:55:23 -04003 * Copyright (c) 2014-2022, Regents of the University of California,
Eric Newberrya98bf932015-09-21 00:58:47 -07004 * 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
Davide Pesaventocb425e82019-07-14 21:48:22 -040029#include "face-common.hpp"
Davide Pesavento2cae8ca2019-04-18 20:48:05 -040030#include "common/counter.hpp"
Eric Newberryb49313d2017-12-24 20:22:27 -070031
Eric Newberrya98bf932015-09-21 00:58:47 -070032namespace nfd {
33namespace face {
34
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040035/** \brief Indicates the state of a transport.
Eric Newberrya98bf932015-09-21 00:58:47 -070036 */
37enum class TransportState {
38 NONE,
Davide Pesavento68ab43d2017-07-02 13:37:35 -040039 UP, ///< the transport is up and can transmit packets
40 DOWN, ///< the transport is temporarily down, and is being recovered
41 CLOSING, ///< the transport is being closed gracefully, either by the peer or by a call to close()
Eric Newberrya98bf932015-09-21 00:58:47 -070042 FAILED, ///< the transport is being closed due to a failure
43 CLOSED ///< the transport is closed, and can be safely deallocated
44};
45
46std::ostream&
47operator<<(std::ostream& os, TransportState state);
48
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040049/** \brief Counters provided by a transport.
50 * \note The type name TransportCounters is an implementation detail.
51 * Use Transport::Counters in public API.
Junxiao Shi57df2882015-11-11 06:12:35 -070052 */
53class TransportCounters
54{
55public:
56 /** \brief count of incoming packets
57 *
58 * A 'packet' typically means a top-level TLV block.
59 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
60 * would not be counted.
61 */
62 PacketCounter nInPackets;
63
64 /** \brief count of outgoing packets
65 *
66 * A 'packet' typically means a top-level TLV block.
67 * This counter is incremented only if transport is UP.
68 */
69 PacketCounter nOutPackets;
70
71 /** \brief total incoming bytes
72 *
73 * This counter includes headers imposed by NFD (such as NDNLP),
74 * but excludes overhead of underlying protocol (such as IP header).
75 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
76 * would not be counted.
77 */
78 ByteCounter nInBytes;
79
80 /** \brief total outgoing bytes
81 *
82 * This counter includes headers imposed by NFD (such as NDNLP),
83 * but excludes overhead of underlying protocol (such as IP header).
84 * This counter is increased only if transport is UP.
85 */
86 ByteCounter nOutBytes;
87};
88
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040089/**
90 * \brief Indicates that the transport has no limit on payload size
Junxiao Shi13546112015-10-14 19:33:07 -070091 */
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040092constexpr ssize_t MTU_UNLIMITED = -1;
Junxiao Shi13546112015-10-14 19:33:07 -070093
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040094/**
95 * \brief (for internal use) Indicates that the MTU field is unset
Junxiao Shi5b8a2b22015-10-22 17:20:44 -070096 */
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040097constexpr ssize_t MTU_INVALID = -2;
Junxiao Shi5b8a2b22015-10-22 17:20:44 -070098
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040099/**
100 * \brief Indicates that the transport does not support reading the queue capacity/length
Eric Newberryb49313d2017-12-24 20:22:27 -0700101 */
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400102constexpr ssize_t QUEUE_UNSUPPORTED = -1;
Eric Newberryb49313d2017-12-24 20:22:27 -0700103
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400104/**
105 * \brief Indicates that the transport was unable to retrieve the queue capacity/length
Eric Newberryb49313d2017-12-24 20:22:27 -0700106 */
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400107constexpr ssize_t QUEUE_ERROR = -2;
Eric Newberryb49313d2017-12-24 20:22:27 -0700108
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400109/**
110 * \brief The lower half of a Face.
111 * \sa Face
Eric Newberrya98bf932015-09-21 00:58:47 -0700112 */
Junxiao Shi57df2882015-11-11 06:12:35 -0700113class Transport : protected virtual TransportCounters, noncopyable
Eric Newberrya98bf932015-09-21 00:58:47 -0700114{
115public:
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400116 /** \brief Counters provided by a transport.
117 * \sa TransportCounters
Eric Newberrya98bf932015-09-21 00:58:47 -0700118 */
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400119 using Counters = TransportCounters;
Eric Newberrya98bf932015-09-21 00:58:47 -0700120
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400121 /** \brief Default constructor.
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700122 *
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400123 * This constructor initializes static properties to invalid values.
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700124 * Subclass constructor must explicitly set every static property.
125 *
126 * This constructor initializes TransportState to UP;
127 * subclass constructor can rely on this default value.
128 */
Eric Newberrya98bf932015-09-21 00:58:47 -0700129 Transport();
130
131 virtual
132 ~Transport();
133
134public:
135 /** \brief set Face and LinkService for Transport
136 * \pre setFaceAndLinkService has not been called
137 */
138 void
Junxiao Shicde37ad2015-12-24 01:02:05 -0700139 setFaceAndLinkService(Face& face, LinkService& service);
Eric Newberrya98bf932015-09-21 00:58:47 -0700140
141 /** \return Face to which this Transport is attached
142 */
Junxiao Shicde37ad2015-12-24 01:02:05 -0700143 const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700144 getFace() const;
145
146 /** \return LinkService to which this Transport is attached
147 */
148 const LinkService*
149 getLinkService() const;
150
151 /** \return LinkService to which this Transport is attached
152 */
153 LinkService*
154 getLinkService();
155
Junxiao Shi57df2882015-11-11 06:12:35 -0700156 virtual const Counters&
157 getCounters() const;
158
Eric Newberrya98bf932015-09-21 00:58:47 -0700159public: // upper interface
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400160 /** \brief Request the transport to be closed
Eric Newberrya98bf932015-09-21 00:58:47 -0700161 *
162 * This operation is effective only if transport is in UP or DOWN state,
163 * otherwise it has no effect.
164 * The transport changes state to CLOSING, and performs cleanup procedure.
165 * The state will be changed to CLOSED when cleanup is complete, which may
166 * happen synchronously or asynchronously.
167 */
168 void
169 close();
170
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400171 /** \brief Send a link-layer packet
172 * \param packet the packet to be sent, must be a valid and well-formed TLV block
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400173 * \note This operation has no effect if getState() is neither UP nor DOWN
174 * \warning Behavior is undefined if packet size exceeds the MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700175 */
176 void
Teng Liang13d582a2020-07-21 20:23:11 -0700177 send(const Block& packet);
Eric Newberrya98bf932015-09-21 00:58:47 -0700178
Eric Newberrya98bf932015-09-21 00:58:47 -0700179public: // static properties
180 /** \return a FaceUri representing local endpoint
181 */
182 FaceUri
183 getLocalUri() const;
184
185 /** \return a FaceUri representing remote endpoint
186 */
187 FaceUri
188 getRemoteUri() const;
189
190 /** \return whether face is local or non-local for scope control purpose
191 */
192 ndn::nfd::FaceScope
193 getScope() const;
194
195 /** \return face persistency setting
196 */
197 ndn::nfd::FacePersistency
198 getPersistency() const;
199
Davide Pesavento32065652017-01-15 01:52:21 -0500200 /** \brief check whether the face persistency can be changed to \p newPersistency
Yanbiao Li32dab972016-11-27 12:26:09 +0800201 *
Davide Pesavento32065652017-01-15 01:52:21 -0500202 * This function serves as the external API, and invokes the protected function
203 * canChangePersistencyToImpl to perform further checks if \p newPersistency differs
204 * from the current persistency.
Yanbiao Li32dab972016-11-27 12:26:09 +0800205 *
Davide Pesavento32065652017-01-15 01:52:21 -0500206 * \return true if the change can be performed, false otherwise
Yanbiao Li32dab972016-11-27 12:26:09 +0800207 */
208 bool
209 canChangePersistencyTo(ndn::nfd::FacePersistency newPersistency) const;
210
Eric Newberrya98bf932015-09-21 00:58:47 -0700211 /** \brief changes face persistency setting
212 */
213 void
Davide Pesavento32065652017-01-15 01:52:21 -0500214 setPersistency(ndn::nfd::FacePersistency newPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700215
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400216 /** \return the link type of the transport
Eric Newberrya98bf932015-09-21 00:58:47 -0700217 */
218 ndn::nfd::LinkType
219 getLinkType() const;
220
Junxiao Shi13546112015-10-14 19:33:07 -0700221 /** \return maximum payload size
222 * \retval MTU_UNLIMITED transport has no limit on payload size
223 *
224 * This size is the maximum packet size that can be sent or received through this transport.
225 *
226 * For a datagram-based transport, this is typically the Maximum Transmission Unit (MTU),
227 * after the overhead of headers introduced by the transport has been accounted for.
228 * For a stream-based transport, this is typically unlimited (MTU_UNLIMITED).
229 */
230 ssize_t
231 getMtu() const;
232
Eric Newberryb49313d2017-12-24 20:22:27 -0700233 /** \return capacity of the send queue (in bytes)
234 * \retval QUEUE_UNSUPPORTED transport does not support queue capacity retrieval
235 * \retval QUEUE_ERROR transport was unable to retrieve the queue capacity
236 */
237 ssize_t
238 getSendQueueCapacity() const;
239
Eric Newberrya98bf932015-09-21 00:58:47 -0700240public: // dynamic properties
241 /** \return transport state
242 */
243 TransportState
244 getState() const;
245
246 /** \brief signals when transport state changes
247 */
248 signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;
249
Eric Newberryc64d30a2015-12-26 11:07:27 -0700250 /** \return expiration time of the transport
251 * \retval time::steady_clock::TimePoint::max() the transport has indefinite lifetime
252 */
253 time::steady_clock::TimePoint
254 getExpirationTime() const;
255
Eric Newberryb49313d2017-12-24 20:22:27 -0700256 /** \return current send queue length of the transport (in octets)
257 * \retval QUEUE_UNSUPPORTED transport does not support queue length retrieval
258 * \retval QUEUE_ERROR transport was unable to retrieve the queue length
259 */
260 virtual ssize_t
Eric Newberry812d6152018-06-06 15:06:01 -0700261 getSendQueueLength()
262 {
263 return QUEUE_UNSUPPORTED;
264 }
265
266protected: // upper interface to be invoked by subclass
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400267 /** \brief Pass a received link-layer packet to the upper layer for further processing
268 * \param packet the received packet, must be a valid and well-formed TLV block
269 * \param endpoint the source endpoint
270 * \warning Behavior is undefined if packet size exceeds the MTU limit
Eric Newberry812d6152018-06-06 15:06:01 -0700271 */
272 void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400273 receive(const Block& packet, const EndpointId& endpoint = 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700274
Eric Newberrya98bf932015-09-21 00:58:47 -0700275protected: // properties to be set by subclass
276 void
277 setLocalUri(const FaceUri& uri);
278
279 void
280 setRemoteUri(const FaceUri& uri);
281
282 void
283 setScope(ndn::nfd::FaceScope scope);
284
285 void
286 setLinkType(ndn::nfd::LinkType linkType);
287
Junxiao Shi13546112015-10-14 19:33:07 -0700288 void
289 setMtu(ssize_t mtu);
290
Eric Newberryb49313d2017-12-24 20:22:27 -0700291 void
292 setSendQueueCapacity(ssize_t sendQueueCapacity);
293
Eric Newberrya98bf932015-09-21 00:58:47 -0700294 /** \brief set transport state
295 *
296 * Only the following transitions are valid:
297 * UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
298 *
299 * \throw std::runtime_error transition is invalid.
300 */
301 void
302 setState(TransportState newState);
303
Eric Newberryc64d30a2015-12-26 11:07:27 -0700304 void
305 setExpirationTime(const time::steady_clock::TimePoint& expirationTime);
306
Eric Newberrya98bf932015-09-21 00:58:47 -0700307protected: // to be overridden by subclass
Yanbiao Li32dab972016-11-27 12:26:09 +0800308 /** \brief invoked by canChangePersistencyTo to perform the check
309 *
310 * Base class implementation returns false.
311 *
312 * \param newPersistency the new persistency, guaranteed to be different from current persistency
313 */
314 virtual bool
315 canChangePersistencyToImpl(ndn::nfd::FacePersistency newPersistency) const;
316
317 /** \brief invoked after the persistency has been changed
318 *
319 * The base class implementation does nothing.
320 * When overridden in a subclass, the function should update internal states
321 * after persistency setting has been changed.
Eric Newberrya98bf932015-09-21 00:58:47 -0700322 */
323 virtual void
Yanbiao Li32dab972016-11-27 12:26:09 +0800324 afterChangePersistency(ndn::nfd::FacePersistency oldPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700325
326 /** \brief performs Transport specific operations to close the transport
327 *
Junxiao Shi13546112015-10-14 19:33:07 -0700328 * This is invoked once by \p close() after changing state to CLOSING.
329 * It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
330 *
Eric Newberrya98bf932015-09-21 00:58:47 -0700331 * When the cleanup procedure is complete, this method should change state to CLOSED.
Junxiao Shi13546112015-10-14 19:33:07 -0700332 * This transition can happen synchronously or asynchronously.
Eric Newberrya98bf932015-09-21 00:58:47 -0700333 */
334 virtual void
335 doClose() = 0;
336
337private: // to be overridden by subclass
338 /** \brief performs Transport specific operations to send a packet
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400339 * \param packet the packet to be sent, can be assumed to be valid and well-formed
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400340 * \pre transport state is either UP or DOWN
Eric Newberrya98bf932015-09-21 00:58:47 -0700341 */
342 virtual void
Teng Liang13d582a2020-07-21 20:23:11 -0700343 doSend(const Block& packet) = 0;
Eric Newberrya98bf932015-09-21 00:58:47 -0700344
345private:
Junxiao Shicde37ad2015-12-24 01:02:05 -0700346 Face* m_face;
Eric Newberrya98bf932015-09-21 00:58:47 -0700347 LinkService* m_service;
348 FaceUri m_localUri;
349 FaceUri m_remoteUri;
350 ndn::nfd::FaceScope m_scope;
351 ndn::nfd::FacePersistency m_persistency;
352 ndn::nfd::LinkType m_linkType;
Junxiao Shi13546112015-10-14 19:33:07 -0700353 ssize_t m_mtu;
Davide Pesavento3e7fc832018-09-08 14:07:29 -0400354 ssize_t m_sendQueueCapacity;
Eric Newberrya98bf932015-09-21 00:58:47 -0700355 TransportState m_state;
Eric Newberryc64d30a2015-12-26 11:07:27 -0700356 time::steady_clock::TimePoint m_expirationTime;
Eric Newberrya98bf932015-09-21 00:58:47 -0700357};
358
Junxiao Shicde37ad2015-12-24 01:02:05 -0700359inline const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700360Transport::getFace() const
361{
362 return m_face;
363}
364
365inline const LinkService*
366Transport::getLinkService() const
367{
368 return m_service;
369}
370
371inline LinkService*
372Transport::getLinkService()
373{
374 return m_service;
375}
376
Junxiao Shi57df2882015-11-11 06:12:35 -0700377inline const Transport::Counters&
378Transport::getCounters() const
379{
380 return *this;
381}
382
Eric Newberrya98bf932015-09-21 00:58:47 -0700383inline FaceUri
384Transport::getLocalUri() const
385{
386 return m_localUri;
387}
388
Junxiao Shi13546112015-10-14 19:33:07 -0700389inline void
390Transport::setLocalUri(const FaceUri& uri)
391{
392 m_localUri = uri;
393}
394
Eric Newberrya98bf932015-09-21 00:58:47 -0700395inline FaceUri
396Transport::getRemoteUri() const
397{
398 return m_remoteUri;
399}
400
Junxiao Shi13546112015-10-14 19:33:07 -0700401inline void
402Transport::setRemoteUri(const FaceUri& uri)
403{
404 m_remoteUri = uri;
405}
406
Eric Newberrya98bf932015-09-21 00:58:47 -0700407inline ndn::nfd::FaceScope
408Transport::getScope() const
409{
410 return m_scope;
411}
412
Junxiao Shi13546112015-10-14 19:33:07 -0700413inline void
414Transport::setScope(ndn::nfd::FaceScope scope)
415{
416 m_scope = scope;
417}
418
Eric Newberrya98bf932015-09-21 00:58:47 -0700419inline ndn::nfd::FacePersistency
420Transport::getPersistency() const
421{
422 return m_persistency;
423}
424
Eric Newberrya98bf932015-09-21 00:58:47 -0700425inline ndn::nfd::LinkType
426Transport::getLinkType() const
427{
428 return m_linkType;
429}
430
Eric Newberrya98bf932015-09-21 00:58:47 -0700431inline void
432Transport::setLinkType(ndn::nfd::LinkType linkType)
433{
434 m_linkType = linkType;
435}
436
Junxiao Shi13546112015-10-14 19:33:07 -0700437inline ssize_t
438Transport::getMtu() const
439{
440 return m_mtu;
441}
442
Eric Newberryb49313d2017-12-24 20:22:27 -0700443inline ssize_t
444Transport::getSendQueueCapacity() const
445{
446 return m_sendQueueCapacity;
447}
448
449inline void
450Transport::setSendQueueCapacity(ssize_t sendQueueCapacity)
451{
452 m_sendQueueCapacity = sendQueueCapacity;
453}
454
Junxiao Shi13546112015-10-14 19:33:07 -0700455inline TransportState
456Transport::getState() const
457{
458 return m_state;
459}
460
Eric Newberryc64d30a2015-12-26 11:07:27 -0700461inline time::steady_clock::TimePoint
462Transport::getExpirationTime() const
463{
464 return m_expirationTime;
465}
466
467inline void
468Transport::setExpirationTime(const time::steady_clock::TimePoint& expirationTime)
469{
470 m_expirationTime = expirationTime;
471}
472
Eric Newberrya98bf932015-09-21 00:58:47 -0700473std::ostream&
474operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
475
476template<typename T>
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400477std::enable_if_t<std::is_base_of_v<Transport, T> && !std::is_same_v<Transport, T>,
478 std::ostream&>
Eric Newberrya98bf932015-09-21 00:58:47 -0700479operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
480{
481 return os << FaceLogHelper<Transport>(flh.obj);
482}
483
484} // namespace face
485} // namespace nfd
486
487#endif // NFD_DAEMON_FACE_TRANSPORT_HPP