blob: 4f3da2cb268093210a82d5ce1b3541260480b038 [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 Shibb5105f2014-03-03 12:06:45 -070053 /// a Name that represent the Strategy program
54 const Name&
55 getName() const;
56
Junxiao Shi679e9272014-02-15 20:10:21 -070057public: // triggers
58 /** \brief trigger after Interest is received
59 *
60 * The Interest:
61 * - does not violate Scope
62 * - is not looped
63 * - cannot be satisfied by ContentStore
64 * - is under a namespace managed by this strategy
65 *
66 * The strategy should decide whether and where to forward this Interest.
67 * - If the strategy decides to forward this Interest,
68 * invoke this->sendInterest one or more times, either now or shortly after
69 * - If strategy concludes that this Interest cannot be forwarded,
Junxiao Shi09498f02014-02-26 19:41:08 -070070 * invoke this->rejectPendingInterest so that PIT entry will be deleted shortly
Junxiao Shi82e7f582014-09-07 15:15:40 -070071 *
Junxiao Shi15e98b02016-08-12 11:21:44 +000072 * \warning The strategy must not retain shared_ptr<pit::Entry>, otherwise undefined behavior
73 * may occur. However, the strategy is allowed to store weak_ptr<pit::Entry>.
Junxiao Shi679e9272014-02-15 20:10:21 -070074 */
Junxiao Shid3c792f2014-01-30 00:46:13 -070075 virtual void
Junxiao Shi8d843142016-07-11 22:42:42 +000076 afterReceiveInterest(const Face& inFace, const Interest& interest,
Junxiao Shi15e98b02016-08-12 11:21:44 +000077 const shared_ptr<pit::Entry>& pitEntry) = 0;
Junxiao Shidbe71732014-02-21 22:23:28 -070078
Junxiao Shi22be22c2014-02-16 22:53:48 -070079 /** \brief trigger before PIT entry is satisfied
80 *
Junxiao Shi82e7f582014-09-07 15:15:40 -070081 * This trigger is invoked when an incoming Data satisfies the PIT entry.
82 * It can be invoked even if the PIT entry has already been satisfied.
83 *
Junxiao Shi22be22c2014-02-16 22:53:48 -070084 * In this base class this method does nothing.
Junxiao Shi82e7f582014-09-07 15:15:40 -070085 *
Junxiao Shi15e98b02016-08-12 11:21:44 +000086 * \warning The strategy must not retain shared_ptr<pit::Entry>, otherwise undefined behavior
87 * may occur. However, the strategy is allowed to store weak_ptr<pit::Entry>.
Junxiao Shi22be22c2014-02-16 22:53:48 -070088 */
89 virtual void
Junxiao Shi15e98b02016-08-12 11:21:44 +000090 beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
Junxiao Shi82e7f582014-09-07 15:15:40 -070091 const Face& inFace, const Data& data);
Junxiao Shidbe71732014-02-21 22:23:28 -070092
Junxiao Shi679e9272014-02-15 20:10:21 -070093 /** \brief trigger before PIT entry expires
94 *
95 * PIT entry expires when InterestLifetime has elapsed for all InRecords,
96 * and it is not satisfied by an incoming Data.
97 *
98 * This trigger is not invoked for PIT entry already satisfied.
99 *
100 * In this base class this method does nothing.
Junxiao Shi82e7f582014-09-07 15:15:40 -0700101 *
Junxiao Shi15e98b02016-08-12 11:21:44 +0000102 * \warning The strategy must not retain shared_ptr<pit::Entry>, otherwise undefined behavior
103 * may occur. However, the strategy is allowed to store weak_ptr<pit::Entry>,
104 * although this isn't useful here because PIT entry would be deleted shortly after.
Junxiao Shi679e9272014-02-15 20:10:21 -0700105 */
106 virtual void
Junxiao Shi15e98b02016-08-12 11:21:44 +0000107 beforeExpirePendingInterest(const shared_ptr<pit::Entry>& pitEntry);
Junxiao Shidbe71732014-02-21 22:23:28 -0700108
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700109 /** \brief trigger after Nack is received
110 *
111 * This trigger is invoked when an incoming Nack is received in response to
112 * an forwarded Interest.
113 * The Nack has been confirmed to be a response to the last Interest forwarded
114 * to that upstream, i.e. the PIT out-record exists and has a matching Nonce.
115 * The NackHeader has been recorded in the PIT out-record.
116 *
117 * In this base class this method does nothing.
118 *
Junxiao Shi15e98b02016-08-12 11:21:44 +0000119 * \warning The strategy must not retain shared_ptr<pit::Entry>, otherwise undefined behavior
120 * may occur. However, the strategy is allowed to store weak_ptr<pit::Entry>.
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700121 */
122 virtual void
123 afterReceiveNack(const Face& inFace, const lp::Nack& nack,
Junxiao Shi15e98b02016-08-12 11:21:44 +0000124 const shared_ptr<pit::Entry>& pitEntry);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700125
Junxiao Shid3c792f2014-01-30 00:46:13 -0700126protected: // actions
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700127 /** \brief send Interest to outFace
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500128 * \param pitEntry PIT entry
129 * \param outFace face through which to send out the Interest
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700130 * \param wantNewNonce if true, a new Nonce will be generated,
131 * rather than reusing a Nonce from one of the PIT in-records
132 */
Junxiao Shi727ed292014-02-19 23:26:45 -0700133 VIRTUAL_WITH_TESTS void
Junxiao Shia6de4292016-07-12 02:08:10 +0000134 sendInterest(shared_ptr<pit::Entry> pitEntry, Face& outFace,
Junxiao Shid938a6b2014-05-11 23:40:29 -0700135 bool wantNewNonce = false);
Junxiao Shidbe71732014-02-21 22:23:28 -0700136
Junxiao Shid3c792f2014-01-30 00:46:13 -0700137 /** \brief decide that a pending Interest cannot be forwarded
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500138 * \param pitEntry PIT entry
Junxiao Shi679e9272014-02-15 20:10:21 -0700139 *
Junxiao Shid3c792f2014-01-30 00:46:13 -0700140 * This shall not be called if the pending Interest has been
141 * forwarded earlier, and does not need to be resent now.
142 */
Junxiao Shi727ed292014-02-19 23:26:45 -0700143 VIRTUAL_WITH_TESTS void
Junxiao Shi09498f02014-02-26 19:41:08 -0700144 rejectPendingInterest(shared_ptr<pit::Entry> pitEntry);
Junxiao Shidbe71732014-02-21 22:23:28 -0700145
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700146 /** \brief send Nack to outFace
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500147 * \param pitEntry PIT entry
148 * \param outFace face through which to send out the Nack
149 * \param header Nack header
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700150 *
151 * The outFace must have a PIT in-record, otherwise this method has no effect.
152 */
153 VIRTUAL_WITH_TESTS void
154 sendNack(shared_ptr<pit::Entry> pitEntry, const Face& outFace,
155 const lp::NackHeader& header);
156
157 /** \brief send Nack to every face that has an in-record,
158 * except those in \p exceptFaces
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500159 * \param pitEntry PIT entry
160 * \param header NACK header
161 * \param exceptFaces list of faces that should be excluded from sending Nacks
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700162 * \note This is not an action, but a helper that invokes the sendNack action.
163 */
164 void
165 sendNacks(shared_ptr<pit::Entry> pitEntry, const lp::NackHeader& header,
166 std::initializer_list<const Face*> exceptFaces = std::initializer_list<const Face*>());
167
Junxiao Shidbe71732014-02-21 22:23:28 -0700168protected: // accessors
Junxiao Shi8d843142016-07-11 22:42:42 +0000169 const fib::Entry&
170 lookupFib(const pit::Entry& pitEntry);
171
Junxiao Shidbe71732014-02-21 22:23:28 -0700172 MeasurementsAccessor&
173 getMeasurements();
174
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000175 Face*
176 getFace(FaceId id) const;
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700177
Junxiao Shi49e11e72014-12-14 19:46:05 -0700178 const FaceTable&
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000179 getFaceTable() const;
Junxiao Shi49e11e72014-12-14 19:46:05 -0700180
181protected: // accessors
Junxiao Shiae04d342016-07-19 13:20:22 +0000182 signal::Signal<FaceTable, Face&>& afterAddFace;
183 signal::Signal<FaceTable, Face&>& beforeRemoveFace;
Junxiao Shi49e11e72014-12-14 19:46:05 -0700184
Junxiao Shid3c792f2014-01-30 00:46:13 -0700185private:
Junxiao Shibb5105f2014-03-03 12:06:45 -0700186 Name m_name;
187
Junxiao Shi679e9272014-02-15 20:10:21 -0700188 /** \brief reference to the forwarder
189 *
190 * Triggers can access forwarder indirectly via actions.
191 */
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700192 Forwarder& m_forwarder;
Junxiao Shidbe71732014-02-21 22:23:28 -0700193
194 MeasurementsAccessor m_measurements;
Junxiao Shid3c792f2014-01-30 00:46:13 -0700195};
196
Junxiao Shibb5105f2014-03-03 12:06:45 -0700197inline const Name&
198Strategy::getName() const
199{
200 return m_name;
201}
202
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700203inline void
Junxiao Shia6de4292016-07-12 02:08:10 +0000204Strategy::sendInterest(shared_ptr<pit::Entry> pitEntry, Face& outFace, bool wantNewNonce)
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700205{
Junxiao Shia6de4292016-07-12 02:08:10 +0000206 m_forwarder.onOutgoingInterest(pitEntry, outFace, wantNewNonce);
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700207}
208
209inline void
210Strategy::rejectPendingInterest(shared_ptr<pit::Entry> pitEntry)
211{
212 m_forwarder.onInterestReject(pitEntry);
213}
214
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700215inline void
216Strategy::sendNack(shared_ptr<pit::Entry> pitEntry, const Face& outFace,
217 const lp::NackHeader& header)
218{
219 m_forwarder.onOutgoingNack(pitEntry, outFace, header);
220}
221
Junxiao Shi8d843142016-07-11 22:42:42 +0000222inline const fib::Entry&
223Strategy::lookupFib(const pit::Entry& pitEntry)
224{
225 return m_forwarder.lookupFib(pitEntry);
226}
227
Junxiao Shidbe71732014-02-21 22:23:28 -0700228inline MeasurementsAccessor&
229Strategy::getMeasurements()
230{
231 return m_measurements;
232}
233
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000234inline Face*
235Strategy::getFace(FaceId id) const
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700236{
237 return m_forwarder.getFace(id);
238}
239
Junxiao Shi49e11e72014-12-14 19:46:05 -0700240inline const FaceTable&
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000241Strategy::getFaceTable() const
Junxiao Shi49e11e72014-12-14 19:46:05 -0700242{
243 return m_forwarder.getFaceTable();
244}
245
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700246} // namespace fw
Junxiao Shid3c792f2014-01-30 00:46:13 -0700247} // namespace nfd
248
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700249#endif // NFD_DAEMON_FW_STRATEGY_HPP