blob: ed91cbcae8d70a1636c180e9a8d6a442391f5a63 [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
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040032namespace nfd::face {
Eric Newberrya98bf932015-09-21 00:58:47 -070033
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040034/** \brief Indicates the state of a transport.
Eric Newberrya98bf932015-09-21 00:58:47 -070035 */
36enum class TransportState {
37 NONE,
Davide Pesavento68ab43d2017-07-02 13:37:35 -040038 UP, ///< the transport is up and can transmit packets
39 DOWN, ///< the transport is temporarily down, and is being recovered
40 CLOSING, ///< the transport is being closed gracefully, either by the peer or by a call to close()
Eric Newberrya98bf932015-09-21 00:58:47 -070041 FAILED, ///< the transport is being closed due to a failure
42 CLOSED ///< the transport is closed, and can be safely deallocated
43};
44
45std::ostream&
46operator<<(std::ostream& os, TransportState state);
47
Davide Pesaventob3a23ca2019-05-04 20:40:21 -040048/** \brief Counters provided by a transport.
49 * \note The type name TransportCounters is an implementation detail.
50 * Use Transport::Counters in public API.
Junxiao Shi57df2882015-11-11 06:12:35 -070051 */
52class TransportCounters
53{
54public:
55 /** \brief count of incoming packets
56 *
57 * A 'packet' typically means a top-level TLV block.
58 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
59 * would not be counted.
60 */
61 PacketCounter nInPackets;
62
63 /** \brief count of outgoing packets
64 *
65 * A 'packet' typically means a top-level TLV block.
66 * This counter is incremented only if transport is UP.
67 */
68 PacketCounter nOutPackets;
69
70 /** \brief total incoming bytes
71 *
72 * This counter includes headers imposed by NFD (such as NDNLP),
73 * but excludes overhead of underlying protocol (such as IP header).
74 * For a datagram-based transport, an incoming packet that cannot be parsed as TLV
75 * would not be counted.
76 */
77 ByteCounter nInBytes;
78
79 /** \brief total outgoing bytes
80 *
81 * This counter includes headers imposed by NFD (such as NDNLP),
82 * but excludes overhead of underlying protocol (such as IP header).
83 * This counter is increased only if transport is UP.
84 */
85 ByteCounter nOutBytes;
86};
87
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040088/**
89 * \brief Indicates that the transport has no limit on payload size
Junxiao Shi13546112015-10-14 19:33:07 -070090 */
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040091constexpr ssize_t MTU_UNLIMITED = -1;
Junxiao Shi13546112015-10-14 19:33:07 -070092
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040093/**
94 * \brief (for internal use) Indicates that the MTU field is unset
Junxiao Shi5b8a2b22015-10-22 17:20:44 -070095 */
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040096constexpr ssize_t MTU_INVALID = -2;
Junxiao Shi5b8a2b22015-10-22 17:20:44 -070097
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040098/**
99 * \brief Indicates that the transport does not support reading the queue capacity/length
Eric Newberryb49313d2017-12-24 20:22:27 -0700100 */
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400101constexpr ssize_t QUEUE_UNSUPPORTED = -1;
Eric Newberryb49313d2017-12-24 20:22:27 -0700102
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400103/**
104 * \brief Indicates that the transport was unable to retrieve the queue capacity/length
Eric Newberryb49313d2017-12-24 20:22:27 -0700105 */
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400106constexpr ssize_t QUEUE_ERROR = -2;
Eric Newberryb49313d2017-12-24 20:22:27 -0700107
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400108/**
109 * \brief The lower half of a Face.
110 * \sa Face
Eric Newberrya98bf932015-09-21 00:58:47 -0700111 */
Junxiao Shi57df2882015-11-11 06:12:35 -0700112class Transport : protected virtual TransportCounters, noncopyable
Eric Newberrya98bf932015-09-21 00:58:47 -0700113{
114public:
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400115 /** \brief Counters provided by a transport.
116 * \sa TransportCounters
Eric Newberrya98bf932015-09-21 00:58:47 -0700117 */
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400118 using Counters = TransportCounters;
Eric Newberrya98bf932015-09-21 00:58:47 -0700119
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400120 /** \brief Default constructor.
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700121 *
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400122 * This constructor initializes static properties to invalid values.
Junxiao Shi5b8a2b22015-10-22 17:20:44 -0700123 * Subclass constructor must explicitly set every static property.
124 *
125 * This constructor initializes TransportState to UP;
126 * subclass constructor can rely on this default value.
127 */
Eric Newberrya98bf932015-09-21 00:58:47 -0700128 Transport();
129
130 virtual
131 ~Transport();
132
133public:
134 /** \brief set Face and LinkService for Transport
135 * \pre setFaceAndLinkService has not been called
136 */
137 void
Junxiao Shicde37ad2015-12-24 01:02:05 -0700138 setFaceAndLinkService(Face& face, LinkService& service);
Eric Newberrya98bf932015-09-21 00:58:47 -0700139
140 /** \return Face to which this Transport is attached
141 */
Junxiao Shicde37ad2015-12-24 01:02:05 -0700142 const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700143 getFace() const;
144
145 /** \return LinkService to which this Transport is attached
146 */
147 const LinkService*
148 getLinkService() const;
149
150 /** \return LinkService to which this Transport is attached
151 */
152 LinkService*
153 getLinkService();
154
Junxiao Shi57df2882015-11-11 06:12:35 -0700155 virtual const Counters&
156 getCounters() const;
157
Eric Newberrya98bf932015-09-21 00:58:47 -0700158public: // upper interface
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400159 /** \brief Request the transport to be closed
Eric Newberrya98bf932015-09-21 00:58:47 -0700160 *
161 * This operation is effective only if transport is in UP or DOWN state,
162 * otherwise it has no effect.
163 * The transport changes state to CLOSING, and performs cleanup procedure.
164 * The state will be changed to CLOSED when cleanup is complete, which may
165 * happen synchronously or asynchronously.
166 */
167 void
168 close();
169
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400170 /** \brief Send a link-layer packet
171 * \param packet the packet to be sent, must be a valid and well-formed TLV block
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400172 * \note This operation has no effect if getState() is neither UP nor DOWN
173 * \warning Behavior is undefined if packet size exceeds the MTU limit
Eric Newberrya98bf932015-09-21 00:58:47 -0700174 */
175 void
Teng Liang13d582a2020-07-21 20:23:11 -0700176 send(const Block& packet);
Eric Newberrya98bf932015-09-21 00:58:47 -0700177
Eric Newberrya98bf932015-09-21 00:58:47 -0700178public: // static properties
179 /** \return a FaceUri representing local endpoint
180 */
181 FaceUri
182 getLocalUri() const;
183
184 /** \return a FaceUri representing remote endpoint
185 */
186 FaceUri
187 getRemoteUri() const;
188
189 /** \return whether face is local or non-local for scope control purpose
190 */
191 ndn::nfd::FaceScope
192 getScope() const;
193
194 /** \return face persistency setting
195 */
196 ndn::nfd::FacePersistency
197 getPersistency() const;
198
Davide Pesavento32065652017-01-15 01:52:21 -0500199 /** \brief check whether the face persistency can be changed to \p newPersistency
Yanbiao Li32dab972016-11-27 12:26:09 +0800200 *
Davide Pesavento32065652017-01-15 01:52:21 -0500201 * This function serves as the external API, and invokes the protected function
202 * canChangePersistencyToImpl to perform further checks if \p newPersistency differs
203 * from the current persistency.
Yanbiao Li32dab972016-11-27 12:26:09 +0800204 *
Davide Pesavento32065652017-01-15 01:52:21 -0500205 * \return true if the change can be performed, false otherwise
Yanbiao Li32dab972016-11-27 12:26:09 +0800206 */
207 bool
208 canChangePersistencyTo(ndn::nfd::FacePersistency newPersistency) const;
209
Eric Newberrya98bf932015-09-21 00:58:47 -0700210 /** \brief changes face persistency setting
211 */
212 void
Davide Pesavento32065652017-01-15 01:52:21 -0500213 setPersistency(ndn::nfd::FacePersistency newPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700214
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400215 /** \return the link type of the transport
Eric Newberrya98bf932015-09-21 00:58:47 -0700216 */
217 ndn::nfd::LinkType
218 getLinkType() const;
219
Junxiao Shi13546112015-10-14 19:33:07 -0700220 /** \return maximum payload size
221 * \retval MTU_UNLIMITED transport has no limit on payload size
222 *
223 * This size is the maximum packet size that can be sent or received through this transport.
224 *
225 * For a datagram-based transport, this is typically the Maximum Transmission Unit (MTU),
226 * after the overhead of headers introduced by the transport has been accounted for.
227 * For a stream-based transport, this is typically unlimited (MTU_UNLIMITED).
228 */
229 ssize_t
230 getMtu() const;
231
Eric Newberryb49313d2017-12-24 20:22:27 -0700232 /** \return capacity of the send queue (in bytes)
233 * \retval QUEUE_UNSUPPORTED transport does not support queue capacity retrieval
234 * \retval QUEUE_ERROR transport was unable to retrieve the queue capacity
235 */
236 ssize_t
237 getSendQueueCapacity() const;
238
Eric Newberrya98bf932015-09-21 00:58:47 -0700239public: // dynamic properties
240 /** \return transport state
241 */
242 TransportState
243 getState() const;
244
245 /** \brief signals when transport state changes
246 */
247 signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;
248
Eric Newberryc64d30a2015-12-26 11:07:27 -0700249 /** \return expiration time of the transport
250 * \retval time::steady_clock::TimePoint::max() the transport has indefinite lifetime
251 */
252 time::steady_clock::TimePoint
253 getExpirationTime() const;
254
Eric Newberryb49313d2017-12-24 20:22:27 -0700255 /** \return current send queue length of the transport (in octets)
256 * \retval QUEUE_UNSUPPORTED transport does not support queue length retrieval
257 * \retval QUEUE_ERROR transport was unable to retrieve the queue length
258 */
259 virtual ssize_t
Eric Newberry812d6152018-06-06 15:06:01 -0700260 getSendQueueLength()
261 {
262 return QUEUE_UNSUPPORTED;
263 }
264
265protected: // upper interface to be invoked by subclass
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400266 /** \brief Pass a received link-layer packet to the upper layer for further processing
267 * \param packet the received packet, must be a valid and well-formed TLV block
268 * \param endpoint the source endpoint
269 * \warning Behavior is undefined if packet size exceeds the MTU limit
Eric Newberry812d6152018-06-06 15:06:01 -0700270 */
271 void
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400272 receive(const Block& packet, const EndpointId& endpoint = 0);
Eric Newberryb49313d2017-12-24 20:22:27 -0700273
Eric Newberrya98bf932015-09-21 00:58:47 -0700274protected: // properties to be set by subclass
275 void
276 setLocalUri(const FaceUri& uri);
277
278 void
279 setRemoteUri(const FaceUri& uri);
280
281 void
282 setScope(ndn::nfd::FaceScope scope);
283
284 void
285 setLinkType(ndn::nfd::LinkType linkType);
286
Junxiao Shi13546112015-10-14 19:33:07 -0700287 void
288 setMtu(ssize_t mtu);
289
Eric Newberryb49313d2017-12-24 20:22:27 -0700290 void
291 setSendQueueCapacity(ssize_t sendQueueCapacity);
292
Eric Newberrya98bf932015-09-21 00:58:47 -0700293 /** \brief set transport state
294 *
295 * Only the following transitions are valid:
296 * UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
297 *
298 * \throw std::runtime_error transition is invalid.
299 */
300 void
301 setState(TransportState newState);
302
Eric Newberryc64d30a2015-12-26 11:07:27 -0700303 void
304 setExpirationTime(const time::steady_clock::TimePoint& expirationTime);
305
Eric Newberrya98bf932015-09-21 00:58:47 -0700306protected: // to be overridden by subclass
Yanbiao Li32dab972016-11-27 12:26:09 +0800307 /** \brief invoked by canChangePersistencyTo to perform the check
308 *
309 * Base class implementation returns false.
310 *
311 * \param newPersistency the new persistency, guaranteed to be different from current persistency
312 */
313 virtual bool
314 canChangePersistencyToImpl(ndn::nfd::FacePersistency newPersistency) const;
315
316 /** \brief invoked after the persistency has been changed
317 *
318 * The base class implementation does nothing.
319 * When overridden in a subclass, the function should update internal states
320 * after persistency setting has been changed.
Eric Newberrya98bf932015-09-21 00:58:47 -0700321 */
322 virtual void
Yanbiao Li32dab972016-11-27 12:26:09 +0800323 afterChangePersistency(ndn::nfd::FacePersistency oldPersistency);
Eric Newberrya98bf932015-09-21 00:58:47 -0700324
325 /** \brief performs Transport specific operations to close the transport
326 *
Junxiao Shi13546112015-10-14 19:33:07 -0700327 * This is invoked once by \p close() after changing state to CLOSING.
328 * It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
329 *
Eric Newberrya98bf932015-09-21 00:58:47 -0700330 * When the cleanup procedure is complete, this method should change state to CLOSED.
Junxiao Shi13546112015-10-14 19:33:07 -0700331 * This transition can happen synchronously or asynchronously.
Eric Newberrya98bf932015-09-21 00:58:47 -0700332 */
333 virtual void
334 doClose() = 0;
335
336private: // to be overridden by subclass
337 /** \brief performs Transport specific operations to send a packet
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400338 * \param packet the packet to be sent, can be assumed to be valid and well-formed
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400339 * \pre transport state is either UP or DOWN
Eric Newberrya98bf932015-09-21 00:58:47 -0700340 */
341 virtual void
Teng Liang13d582a2020-07-21 20:23:11 -0700342 doSend(const Block& packet) = 0;
Eric Newberrya98bf932015-09-21 00:58:47 -0700343
344private:
Junxiao Shicde37ad2015-12-24 01:02:05 -0700345 Face* m_face;
Eric Newberrya98bf932015-09-21 00:58:47 -0700346 LinkService* m_service;
347 FaceUri m_localUri;
348 FaceUri m_remoteUri;
349 ndn::nfd::FaceScope m_scope;
350 ndn::nfd::FacePersistency m_persistency;
351 ndn::nfd::LinkType m_linkType;
Junxiao Shi13546112015-10-14 19:33:07 -0700352 ssize_t m_mtu;
Davide Pesavento3e7fc832018-09-08 14:07:29 -0400353 ssize_t m_sendQueueCapacity;
Eric Newberrya98bf932015-09-21 00:58:47 -0700354 TransportState m_state;
Eric Newberryc64d30a2015-12-26 11:07:27 -0700355 time::steady_clock::TimePoint m_expirationTime;
Eric Newberrya98bf932015-09-21 00:58:47 -0700356};
357
Junxiao Shicde37ad2015-12-24 01:02:05 -0700358inline const Face*
Eric Newberrya98bf932015-09-21 00:58:47 -0700359Transport::getFace() const
360{
361 return m_face;
362}
363
364inline const LinkService*
365Transport::getLinkService() const
366{
367 return m_service;
368}
369
370inline LinkService*
371Transport::getLinkService()
372{
373 return m_service;
374}
375
Junxiao Shi57df2882015-11-11 06:12:35 -0700376inline const Transport::Counters&
377Transport::getCounters() const
378{
379 return *this;
380}
381
Eric Newberrya98bf932015-09-21 00:58:47 -0700382inline FaceUri
383Transport::getLocalUri() const
384{
385 return m_localUri;
386}
387
Junxiao Shi13546112015-10-14 19:33:07 -0700388inline void
389Transport::setLocalUri(const FaceUri& uri)
390{
391 m_localUri = uri;
392}
393
Eric Newberrya98bf932015-09-21 00:58:47 -0700394inline FaceUri
395Transport::getRemoteUri() const
396{
397 return m_remoteUri;
398}
399
Junxiao Shi13546112015-10-14 19:33:07 -0700400inline void
401Transport::setRemoteUri(const FaceUri& uri)
402{
403 m_remoteUri = uri;
404}
405
Eric Newberrya98bf932015-09-21 00:58:47 -0700406inline ndn::nfd::FaceScope
407Transport::getScope() const
408{
409 return m_scope;
410}
411
Junxiao Shi13546112015-10-14 19:33:07 -0700412inline void
413Transport::setScope(ndn::nfd::FaceScope scope)
414{
415 m_scope = scope;
416}
417
Eric Newberrya98bf932015-09-21 00:58:47 -0700418inline ndn::nfd::FacePersistency
419Transport::getPersistency() const
420{
421 return m_persistency;
422}
423
Eric Newberrya98bf932015-09-21 00:58:47 -0700424inline ndn::nfd::LinkType
425Transport::getLinkType() const
426{
427 return m_linkType;
428}
429
Eric Newberrya98bf932015-09-21 00:58:47 -0700430inline void
431Transport::setLinkType(ndn::nfd::LinkType linkType)
432{
433 m_linkType = linkType;
434}
435
Junxiao Shi13546112015-10-14 19:33:07 -0700436inline ssize_t
437Transport::getMtu() const
438{
439 return m_mtu;
440}
441
Eric Newberryb49313d2017-12-24 20:22:27 -0700442inline ssize_t
443Transport::getSendQueueCapacity() const
444{
445 return m_sendQueueCapacity;
446}
447
448inline void
449Transport::setSendQueueCapacity(ssize_t sendQueueCapacity)
450{
451 m_sendQueueCapacity = sendQueueCapacity;
452}
453
Junxiao Shi13546112015-10-14 19:33:07 -0700454inline TransportState
455Transport::getState() const
456{
457 return m_state;
458}
459
Eric Newberryc64d30a2015-12-26 11:07:27 -0700460inline time::steady_clock::TimePoint
461Transport::getExpirationTime() const
462{
463 return m_expirationTime;
464}
465
466inline void
467Transport::setExpirationTime(const time::steady_clock::TimePoint& expirationTime)
468{
469 m_expirationTime = expirationTime;
470}
471
Eric Newberrya98bf932015-09-21 00:58:47 -0700472std::ostream&
473operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
474
475template<typename T>
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400476std::enable_if_t<std::is_base_of_v<Transport, T> && !std::is_same_v<Transport, T>,
477 std::ostream&>
Eric Newberrya98bf932015-09-21 00:58:47 -0700478operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
479{
480 return os << FaceLogHelper<Transport>(flh.obj);
481}
482
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400483} // namespace nfd::face
Eric Newberrya98bf932015-09-21 00:58:47 -0700484
485#endif // NFD_DAEMON_FACE_TRANSPORT_HPP