blob: 4346e781afb34a763f67f7abf90ef7f20bd11ccd [file] [log] [blame]
Junxiao Shid3c792f2014-01-30 00:46:13 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi8d843142016-07-11 22:42:42 +00003 * Copyright (c) 2014-2016, Regents of the University of California,
Junxiao Shifaf3eb02015-02-16 10:50:36 -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.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
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/>.
Junxiao Shi82e7f582014-09-07 15:15:40 -070024 */
Junxiao Shid3c792f2014-01-30 00:46:13 -070025
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070026#ifndef NFD_DAEMON_FW_STRATEGY_HPP
27#define NFD_DAEMON_FW_STRATEGY_HPP
Junxiao Shid3c792f2014-01-30 00:46:13 -070028
Junxiao Shi2d9bdc82014-03-02 20:55:42 -070029#include "forwarder.hpp"
Junxiao Shifaf3eb02015-02-16 10:50:36 -070030#include "strategy-registry.hpp"
Junxiao Shidbe71732014-02-21 22:23:28 -070031#include "table/measurements-accessor.hpp"
Junxiao Shid3c792f2014-01-30 00:46:13 -070032
33namespace nfd {
Junxiao Shi8c8d2182014-01-30 22:33:00 -070034namespace fw {
35
Junxiao Shibb5105f2014-03-03 12:06:45 -070036/** \brief represents a forwarding strategy
Junxiao Shid3c792f2014-01-30 00:46:13 -070037 */
Junxiao Shibb5105f2014-03-03 12:06:45 -070038class Strategy : public enable_shared_from_this<Strategy>, noncopyable
Junxiao Shid3c792f2014-01-30 00:46:13 -070039{
40public:
Junxiao Shie93d6a32014-09-07 16:13:22 -070041 /** \brief construct a strategy instance
42 * \param forwarder a reference to the Forwarder, used to enable actions and accessors.
43 * Strategy subclasses should pass this reference,
44 * and should not keep a reference themselves.
45 * \param name the strategy Name.
46 * It's recommended to include a version number as the last component.
47 */
Junxiao Shibb5105f2014-03-03 12:06:45 -070048 Strategy(Forwarder& forwarder, const Name& name);
Junxiao Shidbe71732014-02-21 22:23:28 -070049
Junxiao Shid3c792f2014-01-30 00:46:13 -070050 virtual
51 ~Strategy();
Junxiao Shidbe71732014-02-21 22:23:28 -070052
Junxiao Shib9420cf2016-08-13 04:38:52 +000053 /** \return a Name that represents the strategy program
54 */
Junxiao Shibb5105f2014-03-03 12:06:45 -070055 const Name&
Junxiao Shib9420cf2016-08-13 04:38:52 +000056 getName() const
57 {
58 return m_name;
59 }
Junxiao Shibb5105f2014-03-03 12:06:45 -070060
Junxiao Shi679e9272014-02-15 20:10:21 -070061public: // triggers
62 /** \brief trigger after Interest is received
63 *
64 * The Interest:
65 * - does not violate Scope
66 * - is not looped
67 * - cannot be satisfied by ContentStore
68 * - is under a namespace managed by this strategy
69 *
70 * The strategy should decide whether and where to forward this Interest.
71 * - If the strategy decides to forward this Interest,
72 * invoke this->sendInterest one or more times, either now or shortly after
73 * - If strategy concludes that this Interest cannot be forwarded,
Junxiao Shi09498f02014-02-26 19:41:08 -070074 * invoke this->rejectPendingInterest so that PIT entry will be deleted shortly
Junxiao Shi82e7f582014-09-07 15:15:40 -070075 *
Junxiao Shi15e98b02016-08-12 11:21:44 +000076 * \warning The strategy must not retain shared_ptr<pit::Entry>, otherwise undefined behavior
77 * may occur. However, the strategy is allowed to store weak_ptr<pit::Entry>.
Junxiao Shi679e9272014-02-15 20:10:21 -070078 */
Junxiao Shid3c792f2014-01-30 00:46:13 -070079 virtual void
Junxiao Shi8d843142016-07-11 22:42:42 +000080 afterReceiveInterest(const Face& inFace, const Interest& interest,
Junxiao Shi15e98b02016-08-12 11:21:44 +000081 const shared_ptr<pit::Entry>& pitEntry) = 0;
Junxiao Shidbe71732014-02-21 22:23:28 -070082
Junxiao Shi22be22c2014-02-16 22:53:48 -070083 /** \brief trigger before PIT entry is satisfied
84 *
Junxiao Shi82e7f582014-09-07 15:15:40 -070085 * This trigger is invoked when an incoming Data satisfies the PIT entry.
86 * It can be invoked even if the PIT entry has already been satisfied.
87 *
Junxiao Shi22be22c2014-02-16 22:53:48 -070088 * In this base class this method does nothing.
Junxiao Shi82e7f582014-09-07 15:15:40 -070089 *
Junxiao Shi15e98b02016-08-12 11:21:44 +000090 * \warning The strategy must not retain shared_ptr<pit::Entry>, otherwise undefined behavior
91 * may occur. However, the strategy is allowed to store weak_ptr<pit::Entry>.
Junxiao Shi22be22c2014-02-16 22:53:48 -070092 */
93 virtual void
Junxiao Shi15e98b02016-08-12 11:21:44 +000094 beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
Junxiao Shi82e7f582014-09-07 15:15:40 -070095 const Face& inFace, const Data& data);
Junxiao Shidbe71732014-02-21 22:23:28 -070096
Junxiao Shi679e9272014-02-15 20:10:21 -070097 /** \brief trigger before PIT entry expires
98 *
99 * PIT entry expires when InterestLifetime has elapsed for all InRecords,
100 * and it is not satisfied by an incoming Data.
101 *
102 * This trigger is not invoked for PIT entry already satisfied.
103 *
104 * In this base class this method does nothing.
Junxiao Shi82e7f582014-09-07 15:15:40 -0700105 *
Junxiao Shi15e98b02016-08-12 11:21:44 +0000106 * \warning The strategy must not retain shared_ptr<pit::Entry>, otherwise undefined behavior
107 * may occur. However, the strategy is allowed to store weak_ptr<pit::Entry>,
108 * although this isn't useful here because PIT entry would be deleted shortly after.
Junxiao Shi679e9272014-02-15 20:10:21 -0700109 */
110 virtual void
Junxiao Shi15e98b02016-08-12 11:21:44 +0000111 beforeExpirePendingInterest(const shared_ptr<pit::Entry>& pitEntry);
Junxiao Shidbe71732014-02-21 22:23:28 -0700112
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700113 /** \brief trigger after Nack is received
114 *
115 * This trigger is invoked when an incoming Nack is received in response to
116 * an forwarded Interest.
117 * The Nack has been confirmed to be a response to the last Interest forwarded
118 * to that upstream, i.e. the PIT out-record exists and has a matching Nonce.
119 * The NackHeader has been recorded in the PIT out-record.
120 *
121 * In this base class this method does nothing.
122 *
Junxiao Shi15e98b02016-08-12 11:21:44 +0000123 * \warning The strategy must not retain shared_ptr<pit::Entry>, otherwise undefined behavior
124 * may occur. However, the strategy is allowed to store weak_ptr<pit::Entry>.
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700125 */
126 virtual void
127 afterReceiveNack(const Face& inFace, const lp::Nack& nack,
Junxiao Shi15e98b02016-08-12 11:21:44 +0000128 const shared_ptr<pit::Entry>& pitEntry);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700129
Junxiao Shid3c792f2014-01-30 00:46:13 -0700130protected: // actions
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700131 /** \brief send Interest to outFace
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500132 * \param pitEntry PIT entry
133 * \param outFace face through which to send out the Interest
Junxiao Shic5f651f2016-11-17 22:58:12 +0000134 * \param interest the Interest packet
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700135 */
Junxiao Shi727ed292014-02-19 23:26:45 -0700136 VIRTUAL_WITH_TESTS void
Junxiao Shib9420cf2016-08-13 04:38:52 +0000137 sendInterest(const shared_ptr<pit::Entry>& pitEntry, Face& outFace,
Junxiao Shic5f651f2016-11-17 22:58:12 +0000138 const Interest& interest)
Junxiao Shib9420cf2016-08-13 04:38:52 +0000139 {
Junxiao Shic5f651f2016-11-17 22:58:12 +0000140 m_forwarder.onOutgoingInterest(pitEntry, outFace, interest);
Junxiao Shib9420cf2016-08-13 04:38:52 +0000141 }
Junxiao Shidbe71732014-02-21 22:23:28 -0700142
Junxiao Shic5f651f2016-11-17 22:58:12 +0000143 /** \brief send Interest to outFace
144 * \param pitEntry PIT entry
145 * \param outFace face through which to send out the Interest
146 * \param wantNewNonce if true, a new Nonce will be generated,
147 * rather than reusing a Nonce from one of the PIT in-records
Junxiao Shi00dc9142016-11-21 14:23:12 +0000148 * \deprecated use sendInterest(pitEntry, outFace, interest) instead
Junxiao Shic5f651f2016-11-17 22:58:12 +0000149 */
Junxiao Shi00dc9142016-11-21 14:23:12 +0000150 DEPRECATED(
Junxiao Shic5f651f2016-11-17 22:58:12 +0000151 void
152 sendInterest(const shared_ptr<pit::Entry>& pitEntry, Face& outFace,
Junxiao Shi00dc9142016-11-21 14:23:12 +0000153 bool wantNewNonce = false));
Junxiao Shic5f651f2016-11-17 22:58:12 +0000154
Junxiao Shid3c792f2014-01-30 00:46:13 -0700155 /** \brief decide that a pending Interest cannot be forwarded
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500156 * \param pitEntry PIT entry
Junxiao Shi679e9272014-02-15 20:10:21 -0700157 *
Junxiao Shid3c792f2014-01-30 00:46:13 -0700158 * This shall not be called if the pending Interest has been
159 * forwarded earlier, and does not need to be resent now.
160 */
Junxiao Shi727ed292014-02-19 23:26:45 -0700161 VIRTUAL_WITH_TESTS void
Junxiao Shib9420cf2016-08-13 04:38:52 +0000162 rejectPendingInterest(const shared_ptr<pit::Entry>& pitEntry)
163 {
164 m_forwarder.onInterestReject(pitEntry);
165 }
Junxiao Shidbe71732014-02-21 22:23:28 -0700166
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700167 /** \brief send Nack to outFace
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500168 * \param pitEntry PIT entry
169 * \param outFace face through which to send out the Nack
170 * \param header Nack header
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700171 *
172 * The outFace must have a PIT in-record, otherwise this method has no effect.
173 */
174 VIRTUAL_WITH_TESTS void
Junxiao Shib9420cf2016-08-13 04:38:52 +0000175 sendNack(const shared_ptr<pit::Entry>& pitEntry, const Face& outFace,
176 const lp::NackHeader& header)
177 {
178 m_forwarder.onOutgoingNack(pitEntry, outFace, header);
179 }
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700180
181 /** \brief send Nack to every face that has an in-record,
182 * except those in \p exceptFaces
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500183 * \param pitEntry PIT entry
184 * \param header NACK header
185 * \param exceptFaces list of faces that should be excluded from sending Nacks
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700186 * \note This is not an action, but a helper that invokes the sendNack action.
187 */
188 void
Junxiao Shib9420cf2016-08-13 04:38:52 +0000189 sendNacks(const shared_ptr<pit::Entry>& pitEntry, const lp::NackHeader& header,
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700190 std::initializer_list<const Face*> exceptFaces = std::initializer_list<const Face*>());
191
Junxiao Shidbe71732014-02-21 22:23:28 -0700192protected: // accessors
Junxiao Shicf0f3ce2016-09-02 13:01:59 +0000193 /** \brief performs a FIB lookup, considering Link object if present
194 */
Junxiao Shi8d843142016-07-11 22:42:42 +0000195 const fib::Entry&
Junxiao Shicf0f3ce2016-09-02 13:01:59 +0000196 lookupFib(const pit::Entry& pitEntry) const;
Junxiao Shi8d843142016-07-11 22:42:42 +0000197
Junxiao Shidbe71732014-02-21 22:23:28 -0700198 MeasurementsAccessor&
Junxiao Shib9420cf2016-08-13 04:38:52 +0000199 getMeasurements()
200 {
201 return m_measurements;
202 }
Junxiao Shidbe71732014-02-21 22:23:28 -0700203
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000204 Face*
Junxiao Shib9420cf2016-08-13 04:38:52 +0000205 getFace(FaceId id) const
206 {
207 return m_forwarder.getFace(id);
208 }
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700209
Junxiao Shi49e11e72014-12-14 19:46:05 -0700210 const FaceTable&
Junxiao Shib9420cf2016-08-13 04:38:52 +0000211 getFaceTable() const
212 {
213 return m_forwarder.getFaceTable();
214 }
Junxiao Shi49e11e72014-12-14 19:46:05 -0700215
216protected: // accessors
Junxiao Shiae04d342016-07-19 13:20:22 +0000217 signal::Signal<FaceTable, Face&>& afterAddFace;
218 signal::Signal<FaceTable, Face&>& beforeRemoveFace;
Junxiao Shi49e11e72014-12-14 19:46:05 -0700219
Junxiao Shid3c792f2014-01-30 00:46:13 -0700220private:
Junxiao Shibb5105f2014-03-03 12:06:45 -0700221 Name m_name;
222
Junxiao Shi679e9272014-02-15 20:10:21 -0700223 /** \brief reference to the forwarder
224 *
225 * Triggers can access forwarder indirectly via actions.
226 */
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700227 Forwarder& m_forwarder;
Junxiao Shidbe71732014-02-21 22:23:28 -0700228
229 MeasurementsAccessor m_measurements;
Junxiao Shid3c792f2014-01-30 00:46:13 -0700230};
231
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700232} // namespace fw
Junxiao Shid3c792f2014-01-30 00:46:13 -0700233} // namespace nfd
234
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700235#endif // NFD_DAEMON_FW_STRATEGY_HPP