39 , m_removeFaceInfoConn(beforeRemoveFace.connect([this] (const Face& face) { removeFaceInfo(face); }))
43 NDN_THROW(std::invalid_argument(
"AccessStrategy does not accept parameters"));
46 NDN_THROW(std::invalid_argument(
"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 return afterReceiveNewInterest(ingress, interest, pitEntry);
67 return afterReceiveRetxInterest(ingress, interest, pitEntry);
69 NFD_LOG_DEBUG(interest <<
" interestFrom " << ingress <<
" retx-suppress");
75 AccessStrategy::afterReceiveNewInterest(
const FaceEndpoint& ingress,
const Interest& interest,
76 const shared_ptr<pit::Entry>& pitEntry)
78 const auto& fibEntry = this->
lookupFib(*pitEntry);
81 std::tie(miName, mi) = this->findPrefixMeasurements(*pitEntry);
85 NFD_LOG_DEBUG(interest <<
" interestFrom " << ingress <<
" new-interest mi=" << miName);
88 bool isSentToLastNexthop = this->sendToLastNexthop(ingress, interest, pitEntry, *mi, fibEntry);
89 if (isSentToLastNexthop) {
94 NFD_LOG_DEBUG(interest <<
" interestFrom " << ingress <<
" new-interest no-mi");
100 size_t nMulticastSent = this->multicast(ingress.
face, interest, pitEntry, fibEntry);
102 if (nMulticastSent == 0) {
108 AccessStrategy::afterReceiveRetxInterest(
const FaceEndpoint& ingress,
const Interest& interest,
109 const shared_ptr<pit::Entry>& pitEntry)
111 const auto& fibEntry = this->
lookupFib(*pitEntry);
112 NFD_LOG_DEBUG(interest <<
" interestFrom " << ingress <<
" retx-forward");
113 this->multicast(ingress.
face, interest, pitEntry, fibEntry);
117 AccessStrategy::sendToLastNexthop(
const FaceEndpoint& ingress,
const Interest& interest,
118 const shared_ptr<pit::Entry>& pitEntry, MtInfo& mi,
122 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" no-last-nexthop");
126 if (mi.lastNexthop == ingress.
face.getId()) {
127 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-is-downstream");
131 Face* outFace = this->
getFace(mi.lastNexthop);
132 if (outFace ==
nullptr || !fibEntry.
hasNextHop(*outFace, 0)) {
133 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-gone");
138 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-violates-scope");
142 auto rto = mi.rtt.computeRto();
143 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" interestTo " << mi.lastNexthop
144 <<
" last-nexthop rto=" << time::duration_cast<time::microseconds>(rto).count());
149 PitInfo* pi = pitEntry->insertStrategyInfo<PitInfo>().first;
151 afterRtoTimeout(weak_ptr<pit::Entry>(pitEntry),
152 ingress.
face.getId(), ingress.
endpoint, mi.lastNexthop);
159 AccessStrategy::afterRtoTimeout(
const weak_ptr<pit::Entry>& pitWeak,
162 shared_ptr<pit::Entry> pitEntry = pitWeak.lock();
164 BOOST_ASSERT(pitEntry !=
nullptr);
166 Face* inFace = this->
getFace(inFaceId);
167 if (inFace ==
nullptr) {
168 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" timeoutFrom " << firstOutFaceId
169 <<
" inFace-gone " << inFaceId);
173 auto inRecord = pitEntry->getInRecord(*inFace, inEndpointId);
177 BOOST_ASSERT(inRecord != pitEntry->in_end());
179 const Interest& interest = inRecord->getInterest();
182 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" timeoutFrom " << firstOutFaceId
183 <<
" multicast-except " << firstOutFaceId);
184 this->multicast(*inFace, interest, pitEntry, fibEntry, firstOutFaceId);
188 AccessStrategy::multicast(
const Face& inFace,
const Interest& interest,
189 const shared_ptr<pit::Entry>& pitEntry,
const fib::Entry& fibEntry,
193 for (
const auto& nexthop : fibEntry.
getNextHops()) {
194 Face& outFace = nexthop.getFace();
195 if (&outFace == &inFace || outFace.getId() == exceptFace ||
199 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" interestTo " << outFace.getId() <<
" multicast");
210 PitInfo* pi = pitEntry->getStrategyInfo<PitInfo>();
212 pi->rtoTimer.cancel();
215 if (!pitEntry->hasInRecords()) {
216 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << ingress <<
" not-fastest");
220 auto outRecord = pitEntry->getOutRecord(ingress.
face, 0);
221 if (outRecord == pitEntry->out_end()) {
222 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << ingress <<
" no-out-record");
226 auto rtt = time::steady_clock::now() - outRecord->getLastRenewed();
227 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << ingress
228 <<
" rtt=" << time::duration_cast<time::microseconds>(rtt).count());
229 this->updateMeasurements(ingress.
face, data, time::duration_cast<RttEstimator::Duration>(rtt));
233 AccessStrategy::updateMeasurements(
const Face& inFace,
const Data& data,
237 FaceInfo& fi = m_fit[inFace.getId()];
238 fi.rtt.addMeasurement(rtt);
240 MtInfo* mi = this->addPrefixMeasurements(data);
241 if (mi->lastNexthop != inFace.getId()) {
242 mi->lastNexthop = inFace.getId();
246 mi->rtt.addMeasurement(rtt);
250 std::tuple<Name, AccessStrategy::MtInfo*>
251 AccessStrategy::findPrefixMeasurements(
const pit::Entry& pitEntry)
255 return std::make_tuple(Name(),
nullptr);
259 BOOST_ASSERT(mi !=
nullptr);
262 return std::make_tuple(me->
getName(), mi);
265 AccessStrategy::MtInfo*
266 AccessStrategy::addPrefixMeasurements(
const Data& data)
269 if (!data.getName().empty()) {
275 BOOST_ASSERT(me !=
nullptr);
284 AccessStrategy::removeFaceInfo(
const Face& face)
286 m_fit.erase(face.getId());
const EndpointId endpoint
Main class of NFD forwarding engine.
Interest is retransmission and should be forwarded.
void setInstanceName(const Name &name)
set strategy instance name
const Name & getName() const
Represents a Measurements entry.
RetxSuppressionResult decidePerPitEntry(pit::Entry &pitEntry) const
determines whether Interest is a retransmission, and if so, whether it shall be forwarded or suppress...
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())
time::microseconds Duration
MeasurementsAccessor & getMeasurements()
Scheduler & getScheduler()
Returns the global Scheduler instance for the calling thread.
void sendInterest(const shared_ptr< pit::Entry > &pitEntry, const FaceEndpoint &egress, const Interest &interest)
send Interest to egress
Access Router Strategy version 1.
Represents a face-endpoint pair in the forwarder.
uint64_t EndpointId
identifies an endpoint on the link
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
Interest is new (not a retransmission)
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.
#define NFD_LOG_INIT(name)
static ParsedInstanceName parseInstanceName(const Name &input)
parse a strategy instance name
T * getStrategyInfo() const
Get a StrategyInfo item.
static const Name & getStrategyName()
uint64_t FaceId
identifies a face
bool hasNextHop(const Face &face, EndpointId endpointId) const
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 ...
const NextHopList & getNextHops() const
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
const fib::Entry & lookupFib(const pit::Entry &pitEntry) const
performs a FIB lookup, considering Link object if present
optional< uint64_t > version
whether strategyName contains a version component