40 , m_removeFaceInfoConn(this->beforeRemoveFace.connect(
47 const shared_ptr<pit::Entry>& pitEntry)
50 switch (suppressResult) {
52 this->afterReceiveNewInterest(inFace, interest, pitEntry);
55 this->afterReceiveRetxInterest(inFace, interest, pitEntry);
58 NFD_LOG_DEBUG(interest <<
" interestFrom " << inFace.getId() <<
" retx-suppress");
67 AccessStrategy::afterReceiveNewInterest(
const Face& inFace,
const Interest& interest,
68 const shared_ptr<pit::Entry>& pitEntry)
73 std::tie(miName, mi) = this->findPrefixMeasurements(*pitEntry);
77 NFD_LOG_DEBUG(interest <<
" interestFrom " << inFace.getId() <<
78 " new-interest mi=" << miName);
81 bool isSentToLastNexthop = this->sendToLastNexthop(inFace, pitEntry, *mi, fibEntry);
83 if (isSentToLastNexthop) {
88 NFD_LOG_DEBUG(interest <<
" interestFrom " << inFace.getId() <<
89 " new-interest no-mi");
95 this->multicast(pitEntry, fibEntry, {inFace.getId()});
99 AccessStrategy::afterReceiveRetxInterest(
const Face& inFace,
const Interest& interest,
100 const shared_ptr<pit::Entry>& pitEntry)
102 const fib::Entry& fibEntry = this->
lookupFib(*pitEntry);
103 NFD_LOG_DEBUG(interest <<
" interestFrom " << inFace.getId() <<
" retx-forward");
104 this->multicast(pitEntry, fibEntry, {inFace.getId()});
108 AccessStrategy::sendToLastNexthop(
const Face& inFace,
const shared_ptr<pit::Entry>& pitEntry,
109 MtInfo& mi,
const fib::Entry& fibEntry)
112 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" no-last-nexthop");
116 if (mi.lastNexthop == inFace.getId()) {
117 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-is-downstream");
121 Face* face = this->
getFace(mi.lastNexthop);
122 if (face ==
nullptr || !fibEntry.hasNextHop(*face)) {
123 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-gone");
128 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" last-nexthop-violates-scope");
133 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" interestTo " << mi.lastNexthop <<
134 " last-nexthop rto=" << time::duration_cast<time::microseconds>(rto).count());
139 PitInfo* pi = pitEntry->insertStrategyInfo<PitInfo>().first;
141 bind(&AccessStrategy::afterRtoTimeout,
this, weak_ptr<pit::Entry>(pitEntry),
142 inFace.getId(), mi.lastNexthop));
148 AccessStrategy::afterRtoTimeout(weak_ptr<pit::Entry> pitWeak,
FaceId inFace,
FaceId firstOutFace)
150 shared_ptr<pit::Entry> pitEntry = pitWeak.lock();
151 BOOST_ASSERT(pitEntry !=
nullptr);
154 const fib::Entry& fibEntry = this->
lookupFib(*pitEntry);
156 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" timeoutFrom " << firstOutFace <<
157 " multicast-except " << inFace <<
',' << firstOutFace);
158 this->multicast(pitEntry, fibEntry, {inFace, firstOutFace});
162 AccessStrategy::multicast(
const shared_ptr<pit::Entry>& pitEntry,
const fib::Entry& fibEntry,
163 std::unordered_set<FaceId> exceptFaces)
165 for (
const fib::NextHop& nexthop : fibEntry.getNextHops()) {
166 Face& face = nexthop.getFace();
167 if (exceptFaces.count(face.getId()) > 0) {
170 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" interestTo " << face.getId() <<
178 const Face& inFace,
const Data& data)
180 PitInfo* pi = pitEntry->getStrategyInfo<PitInfo>();
182 pi->rtoTimer.cancel();
185 if (!pitEntry->hasInRecords()) {
186 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << inFace.getId() <<
192 if (outRecord == pitEntry->out_end()) {
193 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << inFace.getId() <<
198 time::steady_clock::Duration rtt = time::steady_clock::now() - outRecord->getLastRenewed();
199 NFD_LOG_DEBUG(pitEntry->getInterest() <<
" dataFrom " << inFace.getId() <<
200 " rtt=" << time::duration_cast<time::microseconds>(rtt).count());
201 this->updateMeasurements(inFace, data, time::duration_cast<RttEstimator::Duration>(rtt));
205 AccessStrategy::updateMeasurements(
const Face& inFace,
const Data& data,
208 FaceInfo& fi = m_fit[inFace.getId()];
209 fi.rtt.addMeasurement(rtt);
211 MtInfo* mi = this->addPrefixMeasurements(data);
212 if (mi->lastNexthop != inFace.getId()) {
213 mi->lastNexthop = inFace.getId();
217 mi->rtt.addMeasurement(rtt);
221 AccessStrategy::MtInfo::MtInfo()
223 , rtt(1, time::milliseconds(1), 0.1)
227 std::tuple<Name, AccessStrategy::MtInfo*>
228 AccessStrategy::findPrefixMeasurements(
const pit::Entry& pitEntry)
230 measurements::Entry* me = this->
getMeasurements().findLongestPrefixMatch(pitEntry);
232 return std::make_tuple(Name(),
nullptr);
235 MtInfo* mi = me->getStrategyInfo<MtInfo>();
236 BOOST_ASSERT(mi !=
nullptr);
239 return std::make_tuple(me->getName(), mi);
242 AccessStrategy::MtInfo*
243 AccessStrategy::addPrefixMeasurements(
const Data& data)
245 measurements::Entry* me =
nullptr;
246 if (!data.getName().empty()) {
252 BOOST_ASSERT(me !=
nullptr);
255 static const time::nanoseconds ME_LIFETIME = time::seconds(8);
258 return me->insertStrategyInfo<MtInfo>().first;
261 AccessStrategy::FaceInfo::FaceInfo()
262 : rtt(1, time::milliseconds(1), 0.1)
267 AccessStrategy::removeFaceInfo(
const Face& face)
269 m_fit.erase(face.getId());
#define NFD_REGISTER_STRATEGY(StrategyType)
registers a built-in strategy
Copyright (c) 2014-2016, Regents of the University of California, Arizona Board of Regents...
#define NFD_LOG_DEBUG(expression)
time::microseconds Duration
Interest is retransmission and should be suppressed.
virtual void beforeSatisfyInterest(const shared_ptr< pit::Entry > &pitEntry, const Face &inFace, const Data &data) override
trigger before PIT entry is satisfied
MeasurementsAccessor & getMeasurements()
virtual Result decide(const Face &inFace, const Interest &interest, pit::Entry &pitEntry) const override
determines whether Interest is a retransmission, and if so, whether it shall be forwarded or suppress...
Table::const_iterator iterator
AccessStrategy(Forwarder &forwarder, const Name &name=STRATEGY_NAME)
Access Router Strategy version 1.
bool violatesScope(const pit::Entry &pitEntry, const Face &outFace)
determine whether forwarding the Interest in pitEntry to outFace would violate scope ...
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
virtual void afterReceiveInterest(const Face &inFace, const Interest &interest, const shared_ptr< pit::Entry > &pitEntry) override
trigger after Interest is received
Interest is retransmission and should be forwarded.
represents a forwarding strategy
Interest is new (not a retransmission)
#define NFD_LOG_INIT(name)
EventId schedule(const time::nanoseconds &after, const Scheduler::Event &event)
schedule an event
uint64_t FaceId
identifies a face
static const Name STRATEGY_NAME
void sendInterest(const shared_ptr< pit::Entry > &pitEntry, Face &outFace, bool wantNewNonce=false)
send Interest to outFace
const FaceId INVALID_FACEID
indicates an invalid FaceId
Face * getFace(FaceId id) const
const fib::Entry & lookupFib(const pit::Entry &pitEntry) const
performs a FIB lookup, considering Link object if present