39 , m_rttEstimatorOpts(make_shared<RttEstimator::Options>())
40 , m_removeFaceConn(beforeRemoveFace.connect([this] (const
Face& face) { m_fit.erase(face.getId()); }))
44 NDN_THROW(std::invalid_argument(
"AccessStrategy does not accept parameters"));
47 NDN_THROW(std::invalid_argument(
"AccessStrategy does not support version " + 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 return afterReceiveNewInterest(ingress, interest, pitEntry);
68 return afterReceiveRetxInterest(ingress, interest, pitEntry);
70 NFD_LOG_DEBUG(interest <<
" interestFrom " << ingress <<
" retx-suppress");
76 AccessStrategy::afterReceiveNewInterest(
const FaceEndpoint& ingress,
const Interest& interest,
77 const shared_ptr<pit::Entry>& pitEntry)
79 const auto& fibEntry = this->
lookupFib(*pitEntry);
82 std::tie(miName, mi) = this->findPrefixMeasurements(*pitEntry);
86 NFD_LOG_DEBUG(interest <<
" interestFrom " << ingress <<
" new-interest mi=" << miName);
89 bool isSentToLastNexthop = this->sendToLastNexthop(ingress, interest, pitEntry, *mi, fibEntry);
90 if (isSentToLastNexthop) {
95 NFD_LOG_DEBUG(interest <<
" interestFrom " << ingress <<
" new-interest no-mi");
101 size_t nMulticastSent = this->multicast(ingress.
face, interest, pitEntry, fibEntry);
103 if (nMulticastSent == 0) {
109 AccessStrategy::afterReceiveRetxInterest(
const FaceEndpoint& ingress,
const Interest& interest,
110 const shared_ptr<pit::Entry>& pitEntry)
112 const auto& fibEntry = this->
lookupFib(*pitEntry);
113 NFD_LOG_DEBUG(interest <<
" interestFrom " << ingress <<
" retx-forward");
114 this->multicast(ingress.
face, interest, pitEntry, fibEntry);
118 AccessStrategy::sendToLastNexthop(
const FaceEndpoint& ingress,
const Interest& interest,
119 const shared_ptr<pit::Entry>& pitEntry, MtInfo& mi,
123 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" no-last-nexthop");
127 if (mi.lastNexthop == ingress.
face.
getId()) {
128 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-is-downstream");
133 if (outFace ==
nullptr || !fibEntry.
hasNextHop(*outFace)) {
134 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-gone");
139 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-violates-scope");
143 auto rto = mi.rtt.getEstimatedRto();
144 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" interestTo " << mi.lastNexthop
145 <<
" last-nexthop rto=" << time::duration_cast<time::microseconds>(rto).count());
147 if (!this->
sendInterest(pitEntry, *outFace, interest)) {
152 PitInfo* pi = pitEntry->insertStrategyInfo<PitInfo>().first;
154 [
this, pitWeak = weak_ptr<pit::Entry>(pitEntry), face = ingress.
face.
getId(), nh = mi.lastNexthop] {
155 afterRtoTimeout(pitWeak, face, nh);
162 AccessStrategy::afterRtoTimeout(
const weak_ptr<pit::Entry>& pitWeak,
165 shared_ptr<pit::Entry> pitEntry = pitWeak.lock();
167 BOOST_ASSERT(pitEntry !=
nullptr);
170 if (inFace ==
nullptr) {
171 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" timeoutFrom " << firstOutFaceId
172 <<
" inFace-gone " << inFaceId);
176 auto inRecord = pitEntry->getInRecord(*inFace);
180 BOOST_ASSERT(inRecord != pitEntry->in_end());
182 const Interest& interest = inRecord->getInterest();
185 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" timeoutFrom " << firstOutFaceId
186 <<
" multicast-except " << firstOutFaceId);
187 this->multicast(*inFace, interest, pitEntry, fibEntry, firstOutFaceId);
191 AccessStrategy::multicast(
const Face& inFace,
const Interest& interest,
192 const shared_ptr<pit::Entry>& pitEntry,
const fib::Entry& fibEntry,
196 for (
const auto& nexthop : fibEntry.
getNextHops()) {
197 Face& outFace = nexthop.getFace();
198 if (&outFace == &inFace || outFace.
getId() == exceptFace ||
202 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" interestTo " << outFace.
getId() <<
" multicast");
214 PitInfo* pi = pitEntry->getStrategyInfo<PitInfo>();
216 pi->rtoTimer.cancel();
219 if (!pitEntry->hasInRecords()) {
220 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << ingress <<
" not-fastest");
224 auto outRecord = pitEntry->getOutRecord(ingress.
face);
225 if (outRecord == pitEntry->out_end()) {
226 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << ingress <<
" no-out-record");
230 auto rtt = time::steady_clock::now() - outRecord->getLastRenewed();
231 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << ingress
232 <<
" rtt=" << time::duration_cast<time::microseconds>(rtt).count());
233 this->updateMeasurements(ingress.
face, data, rtt);
237 AccessStrategy::updateMeasurements(
const Face& inFace,
const Data& data, time::nanoseconds rtt)
239 auto ret = m_fit.emplace(std::piecewise_construct,
240 std::forward_as_tuple(inFace.
getId()),
241 std::forward_as_tuple(m_rttEstimatorOpts));
242 FaceInfo& fi = ret.first->second;
243 fi.rtt.addMeasurement(rtt);
245 MtInfo* mi = this->addPrefixMeasurements(data);
246 if (mi->lastNexthop != inFace.
getId()) {
247 mi->lastNexthop = inFace.
getId();
251 mi->rtt.addMeasurement(rtt);
255 std::tuple<Name, AccessStrategy::MtInfo*>
256 AccessStrategy::findPrefixMeasurements(
const pit::Entry& pitEntry)
260 return std::make_tuple(Name(),
nullptr);
263 auto mi = me->getStrategyInfo<MtInfo>();
267 return std::make_tuple(me->getName(), mi);
270 AccessStrategy::MtInfo*
271 AccessStrategy::addPrefixMeasurements(
const Data& data)
274 if (!data.getName().empty()) {
280 BOOST_ASSERT(me !=
nullptr);
Main class of NFD's forwarding engine.
Interest is retransmission and should be forwarded.
void setInstanceName(const Name &name)
Set strategy instance name.
void extendLifetime(Entry &entry, const time::nanoseconds &lifetime)
extend lifetime of an entry
std::pair< T *, bool > insertStrategyInfo(A &&... args)
Insert a StrategyInfo item.
Represents a Measurements entry.
Interest is retransmission and should be suppressed.
static Name makeInstanceName(const Name &input, const Name &strategyName)
Construct a strategy instance name.
AccessStrategy(Forwarder &forwarder, const Name &name=getStrategyName())
const fib::Entry & lookupFib(const pit::Entry &pitEntry) const
Performs a FIB lookup, considering Link object if present.
MeasurementsAccessor & getMeasurements()
Scheduler & getScheduler()
Returns the global Scheduler instance for the calling thread.
bool hasNextHop(const Face &face) const
Entry * findLongestPrefixMatch(const Name &name, const EntryPredicate &pred=AnyEntry()) const
perform a longest prefix match for name
Access Router Strategy version 1.
Represents a face-endpoint pair in the forwarder.
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
Interest is new (not a retransmission)
generalization of a network interface
PartialName parameters
parameter components
void afterReceiveInterest(const FaceEndpoint &ingress, const Interest &interest, const shared_ptr< pit::Entry > &pitEntry) override
Trigger after Interest is received.
Represents a forwarding strategy.
This file contains common algorithms used by forwarding strategies.
const NextHopList & getNextHops() const
#define NFD_LOG_INIT(name)
static ParsedInstanceName parseInstanceName(const Name &input)
Parse a strategy instance name.
RetxSuppressionResult decidePerPitEntry(pit::Entry &pitEntry) const
determines whether Interest is a retransmission, and if so, whether it shall be forwarded or suppress...
static const Name & getStrategyName()
NFD_REGISTER_STRATEGY(SelfLearningStrategy)
bool wouldViolateScope(const Face &inFace, const Interest &interest, const Face &outFace)
determine whether forwarding the Interest in pitEntry to outFace would violate scope ...
uint64_t FaceId
Identifies a face.
const FaceId INVALID_FACEID
indicates an invalid FaceId
Face * getFace(FaceId id) const
void beforeSatisfyInterest(const shared_ptr< pit::Entry > &pitEntry, const FaceEndpoint &ingress, const Data &data) override
Trigger before PIT entry is satisfied.
void rejectPendingInterest(const shared_ptr< pit::Entry > &pitEntry)
Schedule the PIT entry for immediate deletion.
pit::OutRecord * sendInterest(const shared_ptr< pit::Entry > &pitEntry, Face &egress, const Interest &interest)
Send an Interest packet.
Entry * get(const Name &name)
find or insert a Measurements entry for name
optional< uint64_t > version
whether strategyName contains a version component