fw: Forwarder processes Link for mobility
This commit also adds NetworkRegionTable to store producer region names,
and checks packets are well-formed before entering forwarding pipelines.
refs #3034, #3155
Change-Id: I8de4c482e8a289b922be70139675bc4661f9a301
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index 7e5d883..27bfa38 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -49,7 +49,34 @@
Forwarder::~Forwarder()
{
+}
+void
+Forwarder::startProcessInterest(Face& face, const Interest& interest)
+{
+ // check fields used by forwarding are well-formed
+ try {
+ if (interest.hasLink()) {
+ interest.getLink();
+ }
+ }
+ catch (tlv::Error&) {
+ NFD_LOG_DEBUG("startProcessInterest face=" << face.getId() <<
+ " interest=" << interest.getName() << " malformed");
+ // It's safe to call interest.getName() because Name has been fully parsed
+ return;
+ }
+
+ this->onIncomingInterest(face, interest);
+}
+
+void
+Forwarder::startProcessData(Face& face, const Data& data)
+{
+ // check fields used by forwarding are well-formed
+ // (none needed)
+
+ this->onIncomingData(face, data);
}
void
@@ -101,6 +128,16 @@
}
void
+Forwarder::onInterestLoop(Face& inFace, const Interest& interest,
+ shared_ptr<pit::Entry> pitEntry)
+{
+ NFD_LOG_DEBUG("onInterestLoop face=" << inFace.getId() <<
+ " interest=" << interest.getName());
+
+ // (drop)
+}
+
+void
Forwarder::onContentStoreMiss(const Face& inFace,
shared_ptr<pit::Entry> pitEntry,
const Interest& interest)
@@ -114,10 +151,55 @@
// set PIT unsatisfy timer
this->setUnsatisfyTimer(pitEntry);
- // FIB lookup
- shared_ptr<fib::Entry> fibEntry = m_fib.findLongestPrefixMatch(*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));
}
@@ -140,16 +222,6 @@
this->onOutgoingData(data, *const_pointer_cast<Face>(inFace.shared_from_this()));
}
-void
-Forwarder::onInterestLoop(Face& inFace, const Interest& interest,
- shared_ptr<pit::Entry> pitEntry)
-{
- NFD_LOG_DEBUG("onInterestLoop face=" << inFace.getId() <<
- " interest=" << interest.getName());
-
- // (drop)
-}
-
/** \brief compare two InRecords for picking outgoing Interest
* \return true if b is preferred over a
*