blob: ebbb361514aeb80968a3f2bb0c7e08b58e1973d4 [file] [log] [blame]
Junxiao Shid3c792f2014-01-30 00:46:13 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shifaf3eb02015-02-16 10:50:36 -07003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * 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 *
72 * \note The strategy is permitted to store a weak reference to fibEntry.
Junxiao Shi5e5e4452015-09-24 16:56:52 -070073 * Do not store a shared reference, because FIB entry may be deleted at any moment.
Junxiao Shi82e7f582014-09-07 15:15:40 -070074 * fibEntry is passed by value to allow obtaining a weak reference from it.
75 * \note The strategy is permitted to store a shared reference to pitEntry.
76 * pitEntry is passed by value to reflect this fact.
Junxiao Shi679e9272014-02-15 20:10:21 -070077 */
Junxiao Shid3c792f2014-01-30 00:46:13 -070078 virtual void
79 afterReceiveInterest(const Face& inFace,
80 const Interest& interest,
81 shared_ptr<fib::Entry> fibEntry,
Junxiao Shi82e7f582014-09-07 15:15:40 -070082 shared_ptr<pit::Entry> pitEntry) = 0;
Junxiao Shidbe71732014-02-21 22:23:28 -070083
Junxiao Shi22be22c2014-02-16 22:53:48 -070084 /** \brief trigger before PIT entry is satisfied
85 *
Junxiao Shi82e7f582014-09-07 15:15:40 -070086 * This trigger is invoked when an incoming Data satisfies the PIT entry.
87 * It can be invoked even if the PIT entry has already been satisfied.
88 *
Junxiao Shi22be22c2014-02-16 22:53:48 -070089 * In this base class this method does nothing.
Junxiao Shi82e7f582014-09-07 15:15:40 -070090 *
91 * \note The strategy is permitted to store a shared reference to pitEntry.
92 * pitEntry is passed by value to reflect this fact.
Junxiao Shi22be22c2014-02-16 22:53:48 -070093 */
94 virtual void
Junxiao Shi82e7f582014-09-07 15:15:40 -070095 beforeSatisfyInterest(shared_ptr<pit::Entry> pitEntry,
96 const Face& inFace, const Data& data);
Junxiao Shidbe71732014-02-21 22:23:28 -070097
Junxiao Shi679e9272014-02-15 20:10:21 -070098 /** \brief trigger before PIT entry expires
99 *
100 * PIT entry expires when InterestLifetime has elapsed for all InRecords,
101 * and it is not satisfied by an incoming Data.
102 *
103 * This trigger is not invoked for PIT entry already satisfied.
104 *
105 * In this base class this method does nothing.
Junxiao Shi82e7f582014-09-07 15:15:40 -0700106 *
107 * \note The strategy is permitted to store a shared reference to pitEntry.
108 * pitEntry is passed by value to reflect this fact.
Junxiao Shi679e9272014-02-15 20:10:21 -0700109 */
110 virtual void
111 beforeExpirePendingInterest(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 *
123 * \note The strategy is permitted to store a weak reference to fibEntry.
124 * Do not store a shared reference, because PIT entry may be deleted at any moment.
125 * fibEntry is passed by value to allow obtaining a weak reference from it.
126 * \note The strategy is permitted to store a shared reference to pitEntry.
127 * pitEntry is passed by value to reflect this fact.
128 */
129 virtual void
130 afterReceiveNack(const Face& inFace, const lp::Nack& nack,
131 shared_ptr<fib::Entry> fibEntry, shared_ptr<pit::Entry> pitEntry);
132
Junxiao Shid3c792f2014-01-30 00:46:13 -0700133protected: // actions
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700134 /** \brief send Interest to outFace
135 * \param wantNewNonce if true, a new Nonce will be generated,
136 * rather than reusing a Nonce from one of the PIT in-records
137 */
Junxiao Shi727ed292014-02-19 23:26:45 -0700138 VIRTUAL_WITH_TESTS void
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700139 sendInterest(shared_ptr<pit::Entry> pitEntry, shared_ptr<Face> outFace,
Junxiao Shid938a6b2014-05-11 23:40:29 -0700140 bool wantNewNonce = false);
Junxiao Shidbe71732014-02-21 22:23:28 -0700141
Junxiao Shid3c792f2014-01-30 00:46:13 -0700142 /** \brief decide that a pending Interest cannot be forwarded
Junxiao Shi679e9272014-02-15 20:10:21 -0700143 *
Junxiao Shid3c792f2014-01-30 00:46:13 -0700144 * This shall not be called if the pending Interest has been
145 * forwarded earlier, and does not need to be resent now.
146 */
Junxiao Shi727ed292014-02-19 23:26:45 -0700147 VIRTUAL_WITH_TESTS void
Junxiao Shi09498f02014-02-26 19:41:08 -0700148 rejectPendingInterest(shared_ptr<pit::Entry> pitEntry);
Junxiao Shidbe71732014-02-21 22:23:28 -0700149
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700150 /** \brief send Nack to outFace
151 *
152 * The outFace must have a PIT in-record, otherwise this method has no effect.
153 */
154 VIRTUAL_WITH_TESTS void
155 sendNack(shared_ptr<pit::Entry> pitEntry, const Face& outFace,
156 const lp::NackHeader& header);
157
158 /** \brief send Nack to every face that has an in-record,
159 * except those in \p exceptFaces
160 * \note This is not an action, but a helper that invokes the sendNack action.
161 */
162 void
163 sendNacks(shared_ptr<pit::Entry> pitEntry, const lp::NackHeader& header,
164 std::initializer_list<const Face*> exceptFaces = std::initializer_list<const Face*>());
165
Junxiao Shidbe71732014-02-21 22:23:28 -0700166protected: // accessors
167 MeasurementsAccessor&
168 getMeasurements();
169
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700170 shared_ptr<Face>
171 getFace(FaceId id);
172
Junxiao Shi49e11e72014-12-14 19:46:05 -0700173 const FaceTable&
174 getFaceTable();
175
176protected: // accessors
177 signal::Signal<FaceTable, shared_ptr<Face>>& afterAddFace;
178 signal::Signal<FaceTable, shared_ptr<Face>>& beforeRemoveFace;
179
Junxiao Shid3c792f2014-01-30 00:46:13 -0700180private:
Junxiao Shibb5105f2014-03-03 12:06:45 -0700181 Name m_name;
182
Junxiao Shi679e9272014-02-15 20:10:21 -0700183 /** \brief reference to the forwarder
184 *
185 * Triggers can access forwarder indirectly via actions.
186 */
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700187 Forwarder& m_forwarder;
Junxiao Shidbe71732014-02-21 22:23:28 -0700188
189 MeasurementsAccessor m_measurements;
Junxiao Shid3c792f2014-01-30 00:46:13 -0700190};
191
Junxiao Shibb5105f2014-03-03 12:06:45 -0700192inline const Name&
193Strategy::getName() const
194{
195 return m_name;
196}
197
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700198inline void
199Strategy::sendInterest(shared_ptr<pit::Entry> pitEntry,
Junxiao Shid938a6b2014-05-11 23:40:29 -0700200 shared_ptr<Face> outFace,
201 bool wantNewNonce)
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700202{
Junxiao Shid938a6b2014-05-11 23:40:29 -0700203 m_forwarder.onOutgoingInterest(pitEntry, *outFace, wantNewNonce);
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700204}
205
206inline void
207Strategy::rejectPendingInterest(shared_ptr<pit::Entry> pitEntry)
208{
209 m_forwarder.onInterestReject(pitEntry);
210}
211
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700212inline void
213Strategy::sendNack(shared_ptr<pit::Entry> pitEntry, const Face& outFace,
214 const lp::NackHeader& header)
215{
216 m_forwarder.onOutgoingNack(pitEntry, outFace, header);
217}
218
Junxiao Shidbe71732014-02-21 22:23:28 -0700219inline MeasurementsAccessor&
220Strategy::getMeasurements()
221{
222 return m_measurements;
223}
224
Junxiao Shi2d9bdc82014-03-02 20:55:42 -0700225inline shared_ptr<Face>
226Strategy::getFace(FaceId id)
227{
228 return m_forwarder.getFace(id);
229}
230
Junxiao Shi49e11e72014-12-14 19:46:05 -0700231inline const FaceTable&
232Strategy::getFaceTable()
233{
234 return m_forwarder.getFaceTable();
235}
236
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700237} // namespace fw
Junxiao Shid3c792f2014-01-30 00:46:13 -0700238} // namespace nfd
239
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700240#endif // NFD_DAEMON_FW_STRATEGY_HPP