38 , m_removeFaceInfoConn(beforeRemoveFace.connect([this] (const
Face& face) { removeFaceInfo(face); }))
41 if (!parsed.parameters.empty()) {
42 BOOST_THROW_EXCEPTION(std::invalid_argument(
"AccessStrategy does not accept parameters"));
44 if (parsed.version && *parsed.version !=
getStrategyName()[-1].toVersion()) {
45 BOOST_THROW_EXCEPTION(std::invalid_argument(
46 "AccessStrategy does not support version " +
to_string(*parsed.version)));
54 static Name strategyName(
"/localhost/nfd/strategy/access/%FD%01");
60 const shared_ptr<pit::Entry>& pitEntry)
63 switch (suppressResult) {
65 this->afterReceiveNewInterest(inFace, interest, pitEntry);
68 this->afterReceiveRetxInterest(inFace, interest, pitEntry);
80 AccessStrategy::afterReceiveNewInterest(
const Face& inFace,
const Interest& interest,
81 const shared_ptr<pit::Entry>& pitEntry)
86 std::tie(miName, mi) = this->findPrefixMeasurements(*pitEntry);
91 " new-interest mi=" << miName);
94 bool isSentToLastNexthop = this->sendToLastNexthop(inFace, interest, pitEntry, *mi, fibEntry);
96 if (isSentToLastNexthop) {
102 " new-interest no-mi");
108 int nMulticastSent = this->multicast(inFace, interest, pitEntry, fibEntry);
110 if (nMulticastSent < 1) {
116 AccessStrategy::afterReceiveRetxInterest(
const Face& inFace,
const Interest& interest,
117 const shared_ptr<pit::Entry>& pitEntry)
119 const fib::Entry& fibEntry = this->
lookupFib(*pitEntry);
120 NFD_LOG_DEBUG(interest <<
" interestFrom " << inFace.getId() <<
" retx-forward");
121 this->multicast(inFace, interest, pitEntry, fibEntry);
125 AccessStrategy::sendToLastNexthop(
const Face& inFace,
const Interest& interest,
126 const shared_ptr<pit::Entry>& pitEntry, MtInfo& mi,
127 const fib::Entry& fibEntry)
130 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" no-last-nexthop");
134 if (mi.lastNexthop == inFace.getId()) {
135 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-is-downstream");
140 if (outFace ==
nullptr || !fibEntry.hasNextHop(*outFace, 0)) {
141 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-gone");
146 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-violates-scope");
151 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" interestTo " << mi.lastNexthop <<
152 " last-nexthop rto=" << time::duration_cast<time::microseconds>(rto).count());
157 PitInfo* pi = pitEntry->insertStrategyInfo<PitInfo>().first;
159 bind(&AccessStrategy::afterRtoTimeout,
this, weak_ptr<pit::Entry>(pitEntry),
160 inFace.getId(), mi.lastNexthop));
166 AccessStrategy::afterRtoTimeout(weak_ptr<pit::Entry> pitWeak,
FaceId inFaceId,
FaceId firstOutFaceId)
168 shared_ptr<pit::Entry> pitEntry = pitWeak.lock();
169 BOOST_ASSERT(pitEntry !=
nullptr);
173 if (inFace ==
nullptr) {
174 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" timeoutFrom " << firstOutFaceId <<
175 " inFace-gone " << inFaceId);
179 auto inRecord = pitEntry->getInRecord(*inFace);
180 BOOST_ASSERT(inRecord != pitEntry->in_end());
185 const Interest& interest = inRecord->getInterest();
186 const fib::Entry& fibEntry = this->
lookupFib(*pitEntry);
188 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" timeoutFrom " << firstOutFaceId <<
189 " multicast-except " << firstOutFaceId);
190 this->multicast(*inFace, interest, pitEntry, fibEntry, firstOutFaceId);
194 AccessStrategy::multicast(
const Face& inFace,
const Interest& interest,
195 const shared_ptr<pit::Entry>& pitEntry,
const fib::Entry& fibEntry,
199 for (
const fib::NextHop& nexthop : fibEntry.getNextHops()) {
200 Face& outFace = nexthop.getFace();
201 if (&outFace == &inFace || outFace.getId() == exceptFace ||
205 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" interestTo " << outFace.getId() <<
215 const Face& inFace,
const Data& data)
217 PitInfo* pi = pitEntry->getStrategyInfo<PitInfo>();
219 pi->rtoTimer.cancel();
222 if (!pitEntry->hasInRecords()) {
228 auto outRecord = pitEntry->getOutRecord(inFace);
229 if (outRecord == pitEntry->out_end()) {
237 " rtt=" << time::duration_cast<time::microseconds>(rtt).count());
238 this->updateMeasurements(inFace, data, time::duration_cast<RttEstimator::Duration>(rtt));
242 AccessStrategy::updateMeasurements(
const Face& inFace,
const Data& data,
246 FaceInfo& fi = m_fit[inFace.
getId()];
247 fi.rtt.addMeasurement(rtt);
249 MtInfo* mi = this->addPrefixMeasurements(data);
250 if (mi->lastNexthop != inFace.
getId()) {
251 mi->lastNexthop = inFace.
getId();
255 mi->rtt.addMeasurement(rtt);
259 AccessStrategy::MtInfo::MtInfo()
265 std::tuple<Name, AccessStrategy::MtInfo*>
266 AccessStrategy::findPrefixMeasurements(
const pit::Entry& pitEntry)
270 return std::make_tuple(
Name(),
nullptr);
273 MtInfo* mi = me->getStrategyInfo<MtInfo>();
274 BOOST_ASSERT(mi !=
nullptr);
277 return std::make_tuple(me->getName(), mi);
280 AccessStrategy::MtInfo*
281 AccessStrategy::addPrefixMeasurements(
const Data& data)
283 measurements::Entry* me =
nullptr;
284 if (!data.getName().empty()) {
290 BOOST_ASSERT(me !=
nullptr);
295 return me->insertStrategyInfo<MtInfo>().first;
298 AccessStrategy::FaceInfo::FaceInfo()
304 AccessStrategy::removeFaceInfo(
const Face& face)
306 m_fit.erase(face.getId());
Interest is retransmission and should be forwarded.
static ParsedInstanceName parseInstanceName(const Name &input)
parse a strategy instance name
time::microseconds Duration
generalization of a network interface
static time_point now() noexcept
Face * getFace(FaceId id) const
Interest is retransmission and should be suppressed.
void setInstanceName(const Name &name)
set strategy instance name
Represents an Interest packet.
void afterReceiveInterest(const Face &inFace, const Interest &interest, const shared_ptr< pit::Entry > &pitEntry) override
trigger after Interest is received
void extendLifetime(Entry &entry, const time::nanoseconds &lifetime)
extend lifetime of an entry
Entry * findLongestPrefixMatch(const Name &name, const EntryPredicate &pred=AnyEntry()) const
perform a longest prefix match for name
Copyright (c) 2011-2015 Regents of the University of California.
MeasurementsAccessor & getMeasurements()
Interest is new (not a retransmission)
static const Name & getStrategyName()
NFD_REGISTER_STRATEGY(AccessStrategy)
void rejectPendingInterest(const shared_ptr< pit::Entry > &pitEntry)
schedule the PIT entry for immediate deletion
Represents an absolute name.
represents a forwarding strategy
void beforeSatisfyInterest(const shared_ptr< pit::Entry > &pitEntry, const Face &inFace, const Data &data) override
trigger before PIT entry is satisfied
This file contains common algorithms used by forwarding strategies.
const fib::Entry & lookupFib(const pit::Entry &pitEntry) const
performs a FIB lookup, considering Link object if present
EventId schedule(time::nanoseconds after, const EventCallback &event)
Schedule an event.
Entry * get(const Name &name)
find or insert a Measurements entry for name
static Name makeInstanceName(const Name &input, const Name &strategyName)
construct a strategy instance name
std::string to_string(const V &v)
RetxSuppressionResult decidePerPitEntry(pit::Entry &pitEntry) const
determines whether Interest is a retransmission, and if so, whether it shall be forwarded or suppress...
Access Router Strategy version 1.
uint64_t FaceId
identifies a face
#define NFD_LOG_INIT(name)
Represents a Data packet.
AccessStrategy(Forwarder &forwarder, const Name &name=getStrategyName())
void sendInterest(const shared_ptr< pit::Entry > &pitEntry, Face &outFace, const Interest &interest)
send Interest to outFace
bool wouldViolateScope(const Face &inFace, const Interest &interest, const Face &outFace)
determine whether forwarding the Interest in pitEntry to outFace would violate scope
const FaceId INVALID_FACEID
indicates an invalid FaceId