38 , m_removeFaceInfoConn(this->beforeRemoveFace.connect(
43 BOOST_THROW_EXCEPTION(std::invalid_argument(
"AccessStrategy does not accept parameters"));
46 BOOST_THROW_EXCEPTION(std::invalid_argument(
47 "AccessStrategy does not support version " + std::to_string(*parsed.
version)));
55 static Name strategyName(
"/localhost/nfd/strategy/access/%FD%01");
61 const shared_ptr<pit::Entry>& pitEntry)
64 switch (suppressResult) {
66 this->afterReceiveNewInterest(inFace, interest, pitEntry);
69 this->afterReceiveRetxInterest(inFace, interest, pitEntry);
72 NFD_LOG_DEBUG(interest <<
" interestFrom " << inFace.getId() <<
" retx-suppress");
81 AccessStrategy::afterReceiveNewInterest(
const Face& inFace,
const Interest& interest,
82 const shared_ptr<pit::Entry>& pitEntry)
87 std::tie(miName, mi) = this->findPrefixMeasurements(*pitEntry);
91 NFD_LOG_DEBUG(interest <<
" interestFrom " << inFace.getId() <<
92 " new-interest mi=" << miName);
95 bool isSentToLastNexthop = this->sendToLastNexthop(inFace, interest, pitEntry, *mi, fibEntry);
97 if (isSentToLastNexthop) {
102 NFD_LOG_DEBUG(interest <<
" interestFrom " << inFace.getId() <<
103 " new-interest no-mi");
109 int nMulticastSent = this->multicast(inFace, interest, pitEntry, fibEntry);
111 if (nMulticastSent < 1) {
117 AccessStrategy::afterReceiveRetxInterest(
const Face& inFace,
const Interest& interest,
118 const shared_ptr<pit::Entry>& pitEntry)
121 NFD_LOG_DEBUG(interest <<
" interestFrom " << inFace.getId() <<
" retx-forward");
122 this->multicast(inFace, interest, pitEntry, fibEntry);
126 AccessStrategy::sendToLastNexthop(
const Face& inFace,
const Interest& interest,
127 const shared_ptr<pit::Entry>& pitEntry, MtInfo& mi,
131 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" no-last-nexthop");
135 if (mi.lastNexthop == inFace.getId()) {
136 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-is-downstream");
140 Face* outFace = this->
getFace(mi.lastNexthop);
141 if (outFace ==
nullptr || !fibEntry.
hasNextHop(*outFace)) {
142 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-gone");
147 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-violates-scope");
152 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" interestTo " << mi.lastNexthop <<
153 " last-nexthop rto=" << time::duration_cast<time::microseconds>(rto).count());
158 PitInfo* pi = pitEntry->insertStrategyInfo<PitInfo>().first;
160 bind(&AccessStrategy::afterRtoTimeout,
this, weak_ptr<pit::Entry>(pitEntry),
161 inFace.getId(), mi.lastNexthop));
167 AccessStrategy::afterRtoTimeout(weak_ptr<pit::Entry> pitWeak,
FaceId inFaceId,
FaceId firstOutFaceId)
169 shared_ptr<pit::Entry> pitEntry = pitWeak.lock();
170 BOOST_ASSERT(pitEntry !=
nullptr);
173 Face* inFace = this->
getFace(inFaceId);
174 if (inFace ==
nullptr) {
175 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" timeoutFrom " << firstOutFaceId <<
176 " inFace-gone " << inFaceId);
181 BOOST_ASSERT(inRecord != pitEntry->in_end());
186 const Interest& interest = inRecord->getInterest();
190 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" timeoutFrom " << firstOutFaceId <<
191 " multicast-except " << firstOutFaceId);
192 this->multicast(*inFace, interest, pitEntry, fibEntry, firstOutFaceId);
196 AccessStrategy::multicast(
const Face& inFace,
const Interest& interest,
197 const shared_ptr<pit::Entry>& pitEntry,
const fib::Entry& fibEntry,
202 Face& outFace = nexthop.getFace();
203 if (&outFace == &inFace || outFace.getId() == exceptFace ||
207 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" interestTo " << outFace.getId() <<
217 const Face& inFace,
const Data& data)
219 PitInfo* pi = pitEntry->getStrategyInfo<PitInfo>();
221 pi->rtoTimer.cancel();
224 if (!pitEntry->hasInRecords()) {
225 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << inFace.getId() <<
231 if (outRecord == pitEntry->out_end()) {
232 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << inFace.getId() <<
237 time::steady_clock::Duration rtt = time::steady_clock::now() - outRecord->getLastRenewed();
238 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << inFace.getId() <<
239 " rtt=" << time::duration_cast<time::microseconds>(rtt).count());
240 this->updateMeasurements(inFace, data, time::duration_cast<RttEstimator::Duration>(rtt));
244 AccessStrategy::updateMeasurements(
const Face& inFace,
const Data& data,
248 FaceInfo& fi = m_fit[inFace.getId()];
249 fi.rtt.addMeasurement(rtt);
251 MtInfo* mi = this->addPrefixMeasurements(data);
252 if (mi->lastNexthop != inFace.getId()) {
253 mi->lastNexthop = inFace.getId();
257 mi->rtt.addMeasurement(rtt);
261 AccessStrategy::MtInfo::MtInfo()
263 , rtt(1, time::milliseconds(1), 0.1)
267 std::tuple<Name, AccessStrategy::MtInfo*>
268 AccessStrategy::findPrefixMeasurements(
const pit::Entry& pitEntry)
272 return std::make_tuple(Name(),
nullptr);
276 BOOST_ASSERT(mi !=
nullptr);
279 return std::make_tuple(me->
getName(), mi);
282 AccessStrategy::MtInfo*
283 AccessStrategy::addPrefixMeasurements(
const Data& data)
286 if (!data.getName().empty()) {
292 BOOST_ASSERT(me !=
nullptr);
295 static const time::nanoseconds ME_LIFETIME = time::seconds(8);
301 AccessStrategy::FaceInfo::FaceInfo()
302 : rtt(1, time::milliseconds(1), 0.1)
307 AccessStrategy::removeFaceInfo(
const Face& face)
309 m_fit.erase(face.getId());
bool hasNextHop(const Face &face) const
Interest is retransmission and should be forwarded.
void setInstanceName(const Name &name)
set strategy instance name
const Name & getName() const
#define NFD_LOG_DEBUG(expression)
represents a Measurements entry
time::microseconds Duration
RetxSuppressionResult decidePerPitEntry(pit::Entry &pitEntry) const
determines whether Interest is a retransmission, and if so, whether it shall be forwarded or suppress...
void sendInterest(const shared_ptr< pit::Entry > &pitEntry, Face &outFace, const Interest &interest)
send Interest to outFace
Interest is retransmission and should be suppressed.
static Name makeInstanceName(const Name &input, const Name &strategyName)
construct a strategy instance name
std::pair< T *, bool > insertStrategyInfo(A &&...args)
insert a StrategyInfo item
AccessStrategy(Forwarder &forwarder, const Name &name=getStrategyName())
void beforeSatisfyInterest(const shared_ptr< pit::Entry > &pitEntry, const Face &inFace, const Data &data) override
trigger before PIT entry is satisfied
MeasurementsAccessor & getMeasurements()
#define NFD_REGISTER_STRATEGY(S)
registers a strategy
Table::const_iterator iterator
Access Router Strategy version 1.
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
void afterReceiveInterest(const Face &inFace, const Interest &interest, const shared_ptr< pit::Entry > &pitEntry) override
trigger after Interest is received
Interest is new (not a retransmission)
PartialName parameters
parameter components
ndn::optional< uint64_t > version
whether strategyName contains a version component
represents a forwarding strategy
This file contains common algorithms used by forwarding strategies.
#define NFD_LOG_INIT(name)
static ParsedInstanceName parseInstanceName(const Name &input)
parse a strategy instance name
EventId schedule(time::nanoseconds after, const EventCallback &event)
schedule an event
T * getStrategyInfo() const
get a StrategyInfo item
static const Name & getStrategyName()
uint64_t FaceId
identifies a face
represents a nexthop record in FIB entry
bool wouldViolateScope(const Face &inFace, const Interest &interest, const Face &outFace)
determine whether forwarding the Interest in pitEntry to outFace would violate scope ...
const NextHopList & getNextHops() const
const FaceId INVALID_FACEID
indicates an invalid FaceId
Face * getFace(FaceId id) const
void rejectPendingInterest(const shared_ptr< pit::Entry > &pitEntry)
decide that a pending Interest cannot be forwarded
const fib::Entry & lookupFib(const pit::Entry &pitEntry) const
performs a FIB lookup, considering Link object if present