fw: Forwarder::lookupFib
refs #3664
Change-Id: I0e0cc3de997653c93db9b7c89e81ea73b4fb12ac
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index 3578bb7..adcb134 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -186,57 +186,13 @@
// set PIT unsatisfy timer
this->setUnsatisfyTimer(pitEntry);
- shared_ptr<fib::Entry> fibEntry;
- // has Link object?
- if (!interest.hasLink()) {
- // FIB lookup with Interest name
- fibEntry = m_fib.findLongestPrefixMatch(*pitEntry);
- NFD_LOG_TRACE("onContentStoreMiss noLinkObject");
- }
- else {
- const Link& link = interest.getLink();
-
- // in producer region?
- if (m_networkRegionTable.isInProducerRegion(link)) {
- // FIB lookup with Interest name
- fibEntry = m_fib.findLongestPrefixMatch(*pitEntry);
- NFD_LOG_TRACE("onContentStoreMiss inProducerRegion");
- }
- // has SelectedDelegation?
- else if (interest.hasSelectedDelegation()) {
- // FIB lookup with SelectedDelegation
- fibEntry = m_fib.findLongestPrefixMatch(interest.getSelectedDelegation());
- NFD_LOG_TRACE("onContentStoreMiss hasSelectedDelegation=" << interest.getSelectedDelegation());
- }
- else {
- // FIB lookup with first delegation Name
- fibEntry = m_fib.findLongestPrefixMatch(link.getDelegations().begin()->second);
-
- // in default-free zone?
- bool isDefaultFreeZone = !(fibEntry->getPrefix().size() == 0 && fibEntry->hasNextHops());
- if (isDefaultFreeZone) {
- // choose and set SelectedDelegation
- for (const std::pair<uint32_t, Name>& delegation : link.getDelegations()) {
- const Name& delegationName = delegation.second;
- fibEntry = m_fib.findLongestPrefixMatch(delegationName);
- if (fibEntry->hasNextHops()) {
- const_cast<Interest&>(interest).setSelectedDelegation(delegationName);
- NFD_LOG_TRACE("onContentStoreMiss enterDefaultFreeZone"
- << " setSelectedDelegation=" << delegationName);
- break;
- }
- }
- }
- else {
- NFD_LOG_TRACE("onContentStoreMiss inConsumerRegion");
- }
- }
- }
-
- // dispatch to strategy
- BOOST_ASSERT(fibEntry != nullptr);
- this->dispatchToStrategy(pitEntry, bind(&Strategy::afterReceiveInterest, _1,
- cref(inFace), cref(interest), fibEntry, pitEntry));
+ // dispatch to strategy: after incoming Interest
+ const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
+ shared_ptr<fib::Entry> fibEntryP = const_cast<fib::Entry&>(fibEntry).shared_from_this();
+ this->dispatchToStrategy(pitEntry,
+ [&] (fw::Strategy* strategy) {
+ strategy->afterReceiveInterest(inFace, interest, fibEntryP, pitEntry);
+ });
}
void
@@ -328,8 +284,8 @@
NFD_LOG_DEBUG("onInterestUnsatisfied interest=" << pitEntry->getName());
// invoke PIT unsatisfied callback
- this->dispatchToStrategy(pitEntry, bind(&Strategy::beforeExpirePendingInterest, _1,
- pitEntry));
+ this->dispatchToStrategy(pitEntry,
+ [&] (fw::Strategy* strategy) { strategy->beforeExpirePendingInterest(pitEntry); });
// goto Interest Finalize pipeline
this->onInterestFinalize(pitEntry, false);
@@ -396,8 +352,8 @@
}
// invoke PIT satisfy callback
- this->dispatchToStrategy(pitEntry, bind(&Strategy::beforeSatisfyInterest, _1,
- pitEntry, cref(inFace), cref(data)));
+ this->dispatchToStrategy(pitEntry,
+ [&] (fw::Strategy* strategy) { strategy->beforeSatisfyInterest(pitEntry, inFace, data); });
// Dead Nonce List insert if necessary (for out-record of inFace)
this->insertDeadNonceList(*pitEntry, true, data.getFreshnessPeriod(), &inFace);
@@ -513,9 +469,12 @@
outRecord->setIncomingNack(nack);
// trigger strategy: after receive NACK
- shared_ptr<fib::Entry> fibEntry = m_fib.findLongestPrefixMatch(*pitEntry);
- this->dispatchToStrategy(pitEntry, bind(&Strategy::afterReceiveNack, _1,
- cref(inFace), cref(nack), fibEntry, pitEntry));
+ const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
+ shared_ptr<fib::Entry> fibEntryP = const_cast<fib::Entry&>(fibEntry).shared_from_this();
+ this->dispatchToStrategy(pitEntry,
+ [&] (fw::Strategy* strategy) {
+ strategy->afterReceiveNack(inFace, nack, fibEntryP, pitEntry);
+ });
}
void
@@ -564,6 +523,66 @@
++m_counters.nOutNacks;
}
+const fib::Entry&
+Forwarder::lookupFib(const pit::Entry& pitEntry) const
+{
+ const Interest& interest = pitEntry.getInterest();
+ // has Link object?
+ if (!interest.hasLink()) {
+ // FIB lookup with Interest name
+ const fib::Entry& fibEntry = *m_fib.findLongestPrefixMatch(pitEntry);
+ NFD_LOG_TRACE("lookupFib noLinkObject found=" << fibEntry.getPrefix());
+ return fibEntry;
+ }
+
+ const Link& link = interest.getLink();
+
+ // in producer region?
+ if (m_networkRegionTable.isInProducerRegion(link)) {
+ // FIB lookup with Interest name
+ const fib::Entry& fibEntry = *m_fib.findLongestPrefixMatch(pitEntry);
+ NFD_LOG_TRACE("lookupFib inProducerRegion found=" << fibEntry.getPrefix());
+ return fibEntry;
+ }
+
+ // has SelectedDelegation?
+ if (interest.hasSelectedDelegation()) {
+ // FIB lookup with SelectedDelegation
+ Name selectedDelegation = interest.getSelectedDelegation();
+ const fib::Entry& fibEntry = *m_fib.findLongestPrefixMatch(selectedDelegation);
+ NFD_LOG_TRACE("lookupFib hasSelectedDelegation=" << selectedDelegation << " found=" << fibEntry.getPrefix());
+ return fibEntry;
+ }
+
+ // FIB lookup with first delegation Name
+ const fib::Entry& fibEntry0 = *m_fib.findLongestPrefixMatch(link.getDelegations().begin()->second);
+ // in default-free zone?
+ bool isDefaultFreeZone = !(fibEntry0.getPrefix().size() == 0 && fibEntry0.hasNextHops());
+ if (!isDefaultFreeZone) {
+ NFD_LOG_TRACE("onContentStoreMiss inConsumerRegion found=" << fibEntry0.getPrefix());
+ return fibEntry0;
+ }
+
+ // choose and set SelectedDelegation
+ for (const std::pair<uint32_t, Name>& delegation : link.getDelegations()) {
+ const Name& delegationName = delegation.second;
+ const fib::Entry& fibEntry = *m_fib.findLongestPrefixMatch(delegationName);
+ if (fibEntry.hasNextHops()) {
+ /// \todo Don't modify in-record Interests.
+ /// Set SelectedDelegation in outgoing Interest pipeline.
+ std::for_each(pitEntry.in_begin(), pitEntry.in_end(),
+ [&delegationName] (const pit::InRecord& inR) {
+ const_cast<Interest&>(inR.getInterest()).setSelectedDelegation(delegationName);
+ });
+ NFD_LOG_TRACE("onContentStoreMiss enterDefaultFreeZone"
+ << " setSelectedDelegation=" << delegationName);
+ return fibEntry;
+ }
+ }
+ BOOST_ASSERT(false);
+ return fibEntry0;
+}
+
static inline bool
compare_InRecord_expiry(const pit::InRecord& a, const pit::InRecord& b)
{
diff --git a/daemon/fw/forwarder.hpp b/daemon/fw/forwarder.hpp
index 99838bb..bf95d98 100644
--- a/daemon/fw/forwarder.hpp
+++ b/daemon/fw/forwarder.hpp
@@ -123,6 +123,11 @@
NetworkRegionTable&
getNetworkRegionTable();
+ /** \brief performs a FIB lookup, considering Link object if present
+ */
+ const fib::Entry&
+ lookupFib(const pit::Entry& pitEntry) const;
+
PUBLIC_WITH_TESTS_ELSE_PRIVATE: // pipelines
/** \brief incoming Interest pipeline
*/
diff --git a/daemon/table/fib-entry.hpp b/daemon/table/fib-entry.hpp
index 9106d9f..0536fc5 100644
--- a/daemon/table/fib-entry.hpp
+++ b/daemon/table/fib-entry.hpp
@@ -50,7 +50,7 @@
/** \class Entry
* \brief represents a FIB entry
*/
-class Entry : noncopyable
+class Entry : public enable_shared_from_this<Entry>, noncopyable
{
public:
explicit
diff --git a/tests/daemon/fw/forwarder.t.cpp b/tests/daemon/fw/forwarder.t.cpp
index d716988..1a4de92 100644
--- a/tests/daemon/fw/forwarder.t.cpp
+++ b/tests/daemon/fw/forwarder.t.cpp
@@ -749,22 +749,10 @@
forwarder.addFace(face1);
forwarder.addFace(face2);
- StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
- auto strategyP = make_shared<DummyStrategy>(ref(forwarder), "ndn:/strategyP");
- strategyP->wantAfterReceiveInterestCalls = true;
- strategyChoice.install(strategyP);
- strategyChoice.insert("ndn:/" , strategyP->getName());
-
Fib& fib = forwarder.getFib();
Pit& pit = forwarder.getPit();
NetworkRegionTable& nrt = forwarder.getNetworkRegionTable();
- // returns prefix of FIB entry during last afterReceiveInterest trigger
- auto getLastFibPrefix = [strategyP] () -> Name {
- BOOST_REQUIRE(!strategyP->afterReceiveInterestCalls.empty());
- return std::get<2>(strategyP->afterReceiveInterestCalls.back())->getPrefix();
- };
-
shared_ptr<Link> link = makeLink("/net/ndnsim", {{10, "/telia/terabits"}, {20, "/ucla/cs"}});
// consumer region
@@ -778,8 +766,7 @@
shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
pit1->insertOrUpdateInRecord(face1, *interest1);
- forwarder.onContentStoreMiss(*face1, pit1, *interest1);
- BOOST_CHECK_EQUAL(getLastFibPrefix(), "/");
+ BOOST_CHECK_EQUAL(forwarder.lookupFib(*pit1).getPrefix(), "/");
BOOST_CHECK_EQUAL(interest1->hasSelectedDelegation(), false);
fibRoot->removeNextHop(face2);
@@ -797,8 +784,7 @@
shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
pit2->insertOrUpdateInRecord(face1, *interest2);
- forwarder.onContentStoreMiss(*face1, pit2, *interest2);
- BOOST_CHECK_EQUAL(getLastFibPrefix(), "/telia");
+ BOOST_CHECK_EQUAL(forwarder.lookupFib(*pit2).getPrefix(), "/telia");
BOOST_REQUIRE_EQUAL(interest2->hasSelectedDelegation(), true);
BOOST_CHECK_EQUAL(interest2->getSelectedDelegation(), "/telia/terabits");
@@ -816,8 +802,7 @@
shared_ptr<pit::Entry> pit3 = pit.insert(*interest3).first;
pit3->insertOrUpdateInRecord(face1, *interest3);
- forwarder.onContentStoreMiss(*face1, pit3, *interest3);
- BOOST_CHECK_EQUAL(getLastFibPrefix(), "/ucla");
+ BOOST_CHECK_EQUAL(forwarder.lookupFib(*pit3).getPrefix(), "/ucla");
BOOST_REQUIRE_EQUAL(interest3->hasSelectedDelegation(), true);
BOOST_CHECK_EQUAL(interest3->getSelectedDelegation(), "/ucla/cs");
@@ -837,8 +822,7 @@
shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
pit4->insertOrUpdateInRecord(face1, *interest4);
- forwarder.onContentStoreMiss(*face1, pit4, *interest4);
- BOOST_CHECK_EQUAL(getLastFibPrefix(), "/ucla");
+ BOOST_CHECK_EQUAL(forwarder.lookupFib(*pit4).getPrefix(), "/ucla");
BOOST_REQUIRE_EQUAL(interest4->hasSelectedDelegation(), true);
BOOST_CHECK_EQUAL(interest4->getSelectedDelegation(), "/ucla/cs");
@@ -860,8 +844,7 @@
shared_ptr<pit::Entry> pit5 = pit.insert(*interest5).first;
pit5->insertOrUpdateInRecord(face1, *interest5);
- forwarder.onContentStoreMiss(*face1, pit5, *interest5);
- BOOST_CHECK_EQUAL(getLastFibPrefix(), "/net/ndnsim");
+ BOOST_CHECK_EQUAL(forwarder.lookupFib(*pit1).getPrefix(), "/net/ndnsim");
BOOST_REQUIRE_EQUAL(interest5->hasSelectedDelegation(), true);
BOOST_CHECK_EQUAL(interest5->getSelectedDelegation(), "/ucla/cs");