blob: 386dd7f42f1531683eb39878f6ffc0198766c593 [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 Shi82e7f582014-09-07 15:15:40 -070072 * \note The strategy is permitted to store a shared reference to pitEntry.
73 * pitEntry is passed by value to reflect this fact.
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 Shi82e7f582014-09-07 15:15:40 -070077 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 *
86 * \note The strategy is permitted to store a shared reference to pitEntry.
87 * pitEntry is passed by value to reflect this fact.
Junxiao Shi22be22c2014-02-16 22:53:48 -070088 */
89 virtual void
Junxiao Shi82e7f582014-09-07 15:15:40 -070090 beforeSatisfyInterest(shared_ptr<pit::Entry> pitEntry,
91 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 *
102 * \note The strategy is permitted to store a shared reference to pitEntry.
103 * pitEntry is passed by value to reflect this fact.
Junxiao Shi679e9272014-02-15 20:10:21 -0700104 */
105 virtual void
106 beforeExpirePendingInterest(shared_ptr<pit::Entry> pitEntry);
Junxiao Shidbe71732014-02-21 22:23:28 -0700107
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700108 /** \brief trigger after Nack is received
109 *
110 * This trigger is invoked when an incoming Nack is received in response to
111 * an forwarded Interest.
112 * The Nack has been confirmed to be a response to the last Interest forwarded
113 * to that upstream, i.e. the PIT out-record exists and has a matching Nonce.
114 * The NackHeader has been recorded in the PIT out-record.
115 *
116 * In this base class this method does nothing.
117 *
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700118 * \note The strategy is permitted to store a shared reference to pitEntry.
119 * pitEntry is passed by value to reflect this fact.
120 */
121 virtual void
122 afterReceiveNack(const Face& inFace, const lp::Nack& nack,
Junxiao Shi8d843142016-07-11 22:42:42 +0000123 shared_ptr<pit::Entry> pitEntry);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700124
Junxiao Shid3c792f2014-01-30 00:46:13 -0700125protected: // actions
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700126 /** \brief send Interest to outFace
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500127 * \param pitEntry PIT entry
128 * \param outFace face through which to send out the Interest
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700129 * \param wantNewNonce if true, a new Nonce will be generated,
130 * rather than reusing a Nonce from one of the PIT in-records
131 */
Junxiao Shi727ed292014-02-19 23:26:45 -0700132 VIRTUAL_WITH_TESTS void
Junxiao Shia6de4292016-07-12 02:08:10 +0000133 sendInterest(shared_ptr<pit::Entry> pitEntry, Face& outFace,
Junxiao Shid938a6b2014-05-11 23:40:29 -0700134 bool wantNewNonce = false);
Junxiao Shidbe71732014-02-21 22:23:28 -0700135
Junxiao Shid3c792f2014-01-30 00:46:13 -0700136 /** \brief decide that a pending Interest cannot be forwarded
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500137 * \param pitEntry PIT entry
Junxiao Shi679e9272014-02-15 20:10:21 -0700138 *
Junxiao Shid3c792f2014-01-30 00:46:13 -0700139 * This shall not be called if the pending Interest has been
140 * forwarded earlier, and does not need to be resent now.
141 */
Junxiao Shi727ed292014-02-19 23:26:45 -0700142 VIRTUAL_WITH_TESTS void
Junxiao Shi09498f02014-02-26 19:41:08 -0700143 rejectPendingInterest(shared_ptr<pit::Entry> pitEntry);
Junxiao Shidbe71732014-02-21 22:23:28 -0700144
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700145 /** \brief send Nack to outFace
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500146 * \param pitEntry PIT entry
147 * \param outFace face through which to send out the Nack
148 * \param header Nack header
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700149 *
150 * The outFace must have a PIT in-record, otherwise this method has no effect.
151 */
152 VIRTUAL_WITH_TESTS void
153 sendNack(shared_ptr<pit::Entry> pitEntry, const Face& outFace,
154 const lp::NackHeader& header);
155
156 /** \brief send Nack to every face that has an in-record,
157 * except those in \p exceptFaces
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -0500158 * \param pitEntry PIT entry
159 * \param header NACK header
160 * \param exceptFaces list of faces that should be excluded from sending Nacks
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700161 * \note This is not an action, but a helper that invokes the sendNack action.
162 */
163 void
164 sendNacks(shared_ptr<pit::Entry> pitEntry, const lp::NackHeader& header,
165 std::initializer_list<const Face*> exceptFaces = std::initializer_list<const Face*>());
166
Junxiao Shidbe71732014-02-21 22:23:28 -0700167protected: // accessors
Junxiao Shi8d843142016-07-11 22:42:42 +0000168 const fib::Entry&
169 lookupFib(const pit::Entry& pitEntry);
170
Junxiao Shidbe71732014-02-21 22:23:28 -0700171 MeasurementsAccessor&
172 getMeasurements();
173
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700174 shared_ptr<Face>
175 getFace(FaceId id);
176
Junxiao Shi49e11e72014-12-14 19:46:05 -0700177 const FaceTable&
178 getFaceTable();
179
180protected: // accessors
181 signal::Signal<FaceTable, shared_ptr<Face>>& afterAddFace;
182 signal::Signal<FaceTable, shared_ptr<Face>>& beforeRemoveFace;
183
Junxiao Shid3c792f2014-01-30 00:46:13 -0700184private:
Junxiao Shibb5105f2014-03-03 12:06:45 -0700185 Name m_name;
186
Junxiao Shi679e9272014-02-15 20:10:21 -0700187 /** \brief reference to the forwarder
188 *
189 * Triggers can access forwarder indirectly via actions.
190 */
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700191 Forwarder& m_forwarder;
Junxiao Shidbe71732014-02-21 22:23:28 -0700192
193 MeasurementsAccessor m_measurements;
Junxiao Shid3c792f2014-01-30 00:46:13 -0700194};
195
Junxiao Shibb5105f2014-03-03 12:06:45 -0700196inline const Name&
197Strategy::getName() const
198{
199 return m_name;
200}
201
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700202inline void
Junxiao Shia6de4292016-07-12 02:08:10 +0000203Strategy::sendInterest(shared_ptr<pit::Entry> pitEntry, Face& outFace, bool wantNewNonce)
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700204{
Junxiao Shia6de4292016-07-12 02:08:10 +0000205 m_forwarder.onOutgoingInterest(pitEntry, outFace, wantNewNonce);
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700206}
207
208inline void
209Strategy::rejectPendingInterest(shared_ptr<pit::Entry> pitEntry)
210{
211 m_forwarder.onInterestReject(pitEntry);
212}
213
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700214inline void
215Strategy::sendNack(shared_ptr<pit::Entry> pitEntry, const Face& outFace,
216 const lp::NackHeader& header)
217{
218 m_forwarder.onOutgoingNack(pitEntry, outFace, header);
219}
220
Junxiao Shi8d843142016-07-11 22:42:42 +0000221inline const fib::Entry&
222Strategy::lookupFib(const pit::Entry& pitEntry)
223{
224 return m_forwarder.lookupFib(pitEntry);
225}
226
Junxiao Shidbe71732014-02-21 22:23:28 -0700227inline MeasurementsAccessor&
228Strategy::getMeasurements()
229{
230 return m_measurements;
231}
232
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700233inline shared_ptr<Face>
234Strategy::getFace(FaceId id)
235{
236 return m_forwarder.getFace(id);
237}
238
Junxiao Shi49e11e72014-12-14 19:46:05 -0700239inline const FaceTable&
240Strategy::getFaceTable()
241{
242 return m_forwarder.getFaceTable();
243}
244
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700245} // namespace fw
Junxiao Shid3c792f2014-01-30 00:46:13 -0700246} // namespace nfd
247
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700248#endif // NFD_DAEMON_FW_STRATEGY_HPP