fw: handle dropped packets in strategies
refs #5128
Change-Id: Ic7f7e61b2dde66004d0291bb41e008961fc7b252
diff --git a/daemon/fw/access-strategy.cpp b/daemon/fw/access-strategy.cpp
index ee2a7a2..c40b12e 100644
--- a/daemon/fw/access-strategy.cpp
+++ b/daemon/fw/access-strategy.cpp
@@ -144,7 +144,9 @@
NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << mi.lastNexthop
<< " last-nexthop rto=" << time::duration_cast<time::microseconds>(rto).count());
- this->sendInterest(pitEntry, *outFace, interest);
+ if (!this->sendInterest(pitEntry, *outFace, interest)) {
+ return false;
+ }
// schedule RTO timeout
PitInfo* pi = pitEntry->insertStrategyInfo<PitInfo>().first;
@@ -198,8 +200,9 @@
continue;
}
NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << outFace.getId() << " multicast");
- this->sendInterest(pitEntry, outFace, interest);
- ++nSent;
+ if (this->sendInterest(pitEntry, outFace, interest)) {
+ ++nSent;
+ }
}
return nSent;
}
diff --git a/daemon/fw/algorithm.hpp b/daemon/fw/algorithm.hpp
index 68d9f14..8a6b849 100644
--- a/daemon/fw/algorithm.hpp
+++ b/daemon/fw/algorithm.hpp
@@ -23,8 +23,8 @@
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NFD_DAEMON_FW_PIT_ALGORITHM_HPP
-#define NFD_DAEMON_FW_PIT_ALGORITHM_HPP
+#ifndef NFD_DAEMON_FW_ALGORITHM_HPP
+#define NFD_DAEMON_FW_ALGORITHM_HPP
#include "fw/scope-prefix.hpp"
#include "table/fib.hpp"
@@ -110,4 +110,4 @@
} // namespace fw
} // namespace nfd
-#endif // NFD_DAEMON_FW_PIT_ALGORITHM_HPP
+#endif // NFD_DAEMON_FW_ALGORITHM_HPP
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index bd4d692..671c536 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -240,7 +240,7 @@
[&] (fw::Strategy& strategy) { strategy.afterContentStoreHit(pitEntry, ingress, data); });
}
-void
+pit::OutRecord*
Forwarder::onOutgoingInterest(const shared_ptr<pit::Entry>& pitEntry,
Face& egress, const Interest& interest)
{
@@ -249,17 +249,19 @@
NFD_LOG_DEBUG("onOutgoingInterest out=" << egress.getId() << " interest=" << pitEntry->getName()
<< " non-local hop-limit=0");
++const_cast<PacketCounter&>(egress.getCounters().nOutHopLimitZero);
- return;
+ return nullptr;
}
NFD_LOG_DEBUG("onOutgoingInterest out=" << egress.getId() << " interest=" << pitEntry->getName());
// insert out-record
- pitEntry->insertOrUpdateOutRecord(egress, interest);
+ auto it = pitEntry->insertOrUpdateOutRecord(egress, interest);
+ BOOST_ASSERT(it != pitEntry->out_end());
// send Interest
egress.sendInterest(interest);
++m_counters.nOutInterests;
+ return &*it;
}
void
@@ -397,12 +399,12 @@
++m_counters.nUnsolicitedData;
}
-void
+bool
Forwarder::onOutgoingData(const Data& data, Face& egress)
{
if (egress.getId() == face::INVALID_FACEID) {
NFD_LOG_WARN("onOutgoingData out=(invalid) data=" << data.getName());
- return;
+ return false;
}
NFD_LOG_DEBUG("onOutgoingData out=" << egress.getId() << " data=" << data.getName());
@@ -413,7 +415,7 @@
NFD_LOG_DEBUG("onOutgoingData out=" << egress.getId() << " data=" << data.getName()
<< " violates /localhost");
// (drop)
- return;
+ return false;
}
// TODO traffic manager
@@ -421,6 +423,8 @@
// send Data
egress.sendData(data);
++m_counters.nOutData;
+
+ return true;
}
void
@@ -480,14 +484,14 @@
[&] (fw::Strategy& strategy) { strategy.afterReceiveNack(ingress, nack, pitEntry); });
}
-void
+bool
Forwarder::onOutgoingNack(const shared_ptr<pit::Entry>& pitEntry,
Face& egress, const lp::NackHeader& nack)
{
if (egress.getId() == face::INVALID_FACEID) {
NFD_LOG_WARN("onOutgoingNack out=(invalid)"
<< " nack=" << pitEntry->getInterest().getName() << "~" << nack.getReason());
- return;
+ return false;
}
// has in-record?
@@ -498,7 +502,7 @@
NFD_LOG_DEBUG("onOutgoingNack out=" << egress.getId()
<< " nack=" << pitEntry->getInterest().getName()
<< "~" << nack.getReason() << " no-in-record");
- return;
+ return false;
}
// if multi-access or ad hoc face, drop
@@ -506,7 +510,7 @@
NFD_LOG_DEBUG("onOutgoingNack out=" << egress.getId()
<< " nack=" << pitEntry->getInterest().getName() << "~" << nack.getReason()
<< " link-type=" << egress.getLinkType());
- return;
+ return false;
}
NFD_LOG_DEBUG("onOutgoingNack out=" << egress.getId()
@@ -523,6 +527,8 @@
// send Nack on face
egress.sendNack(nackPkt);
++m_counters.nOutNacks;
+
+ return true;
}
void
diff --git a/daemon/fw/forwarder.hpp b/daemon/fw/forwarder.hpp
index a3d4771..f736e0f 100644
--- a/daemon/fw/forwarder.hpp
+++ b/daemon/fw/forwarder.hpp
@@ -189,8 +189,9 @@
const Interest& interest, const Data& data);
/** \brief outgoing Interest pipeline
+ * \return A pointer to the out-record created or nullptr if the Interest was dropped
*/
- VIRTUAL_WITH_TESTS void
+ VIRTUAL_WITH_TESTS pit::OutRecord*
onOutgoingInterest(const shared_ptr<pit::Entry>& pitEntry,
Face& egress, const Interest& interest);
@@ -210,8 +211,9 @@
onDataUnsolicited(const FaceEndpoint& ingress, const Data& data);
/** \brief outgoing Data pipeline
+ * \return Whether the Data was transmitted (true) or dropped (false)
*/
- VIRTUAL_WITH_TESTS void
+ VIRTUAL_WITH_TESTS bool
onOutgoingData(const Data& data, Face& egress);
/** \brief incoming Nack pipeline
@@ -220,8 +222,9 @@
onIncomingNack(const FaceEndpoint& ingress, const lp::Nack& nack);
/** \brief outgoing Nack pipeline
+ * \return Whether the Nack was transmitted (true) or dropped (false)
*/
- VIRTUAL_WITH_TESTS void
+ VIRTUAL_WITH_TESTS bool
onOutgoingNack(const shared_ptr<pit::Entry>& pitEntry,
Face& egress, const lp::NackHeader& nack);
diff --git a/daemon/fw/multicast-strategy.cpp b/daemon/fw/multicast-strategy.cpp
index ee921c3..3cb351c 100644
--- a/daemon/fw/multicast-strategy.cpp
+++ b/daemon/fw/multicast-strategy.cpp
@@ -83,10 +83,9 @@
continue;
}
- this->sendInterest(pitEntry, outFace, interest);
NFD_LOG_DEBUG(interest << " from=" << ingress << " pitEntry-to=" << outFace.getId());
-
- if (suppressResult == RetxSuppressionResult::FORWARD) {
+ bool wasSent = this->sendInterest(pitEntry, outFace, interest) != nullptr;
+ if (wasSent && suppressResult == RetxSuppressionResult::FORWARD) {
m_retxSuppression.incrementIntervalForOutRecord(*pitEntry->getOutRecord(outFace));
}
}
diff --git a/daemon/fw/self-learning-strategy.cpp b/daemon/fw/self-learning-strategy.cpp
index ea32709..59a3f8f 100644
--- a/daemon/fw/self-learning-strategy.cpp
+++ b/daemon/fw/self-learning-strategy.cpp
@@ -149,13 +149,17 @@
{
for (auto& outFace : this->getFaceTable() | boost::adaptors::reversed) {
if ((outFace.getId() == inFace.getId() && outFace.getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) ||
- wouldViolateScope(inFace, interest, outFace) || outFace.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
+ wouldViolateScope(inFace, interest, outFace) ||
+ outFace.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
continue;
}
- this->sendInterest(pitEntry, outFace, interest);
- pitEntry->getOutRecord(outFace)->insertStrategyInfo<OutRecordInfo>().first->isNonDiscoveryInterest = false;
- NFD_LOG_DEBUG("send discovery Interest=" << interest << " from="
- << inFace.getId() << " to=" << outFace.getId());
+
+ NFD_LOG_DEBUG("send discovery Interest=" << interest << " from=" << inFace.getId() <<
+ " to=" << outFace.getId());
+ auto outRecord = this->sendInterest(pitEntry, outFace, interest);
+ if (outRecord != nullptr) {
+ outRecord->insertStrategyInfo<OutRecordInfo>().first->isNonDiscoveryInterest = false;
+ }
}
}
@@ -165,15 +169,17 @@
const fib::NextHopList& nexthops)
{
for (const auto& nexthop : nexthops) {
- Face& outFace = nexthop.getFace();
- if ((outFace.getId() == inFace.getId() && outFace.getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) ||
- wouldViolateScope(inFace, interest, outFace)) {
+ if (!isNextHopEligible(inFace, interest, nexthop, pitEntry)) {
continue;
}
- this->sendInterest(pitEntry, outFace, interest);
- pitEntry->getOutRecord(outFace)->insertStrategyInfo<OutRecordInfo>().first->isNonDiscoveryInterest = true;
- NFD_LOG_DEBUG("send non-discovery Interest=" << interest << " from="
- << inFace.getId() << " to=" << outFace.getId());
+
+ Face& outFace = nexthop.getFace();
+ NFD_LOG_DEBUG("send non-discovery Interest=" << interest << " from=" << inFace.getId() <<
+ " to=" << outFace.getId());
+ auto outRecord = this->sendInterest(pitEntry, outFace, interest);
+ if (outRecord != nullptr) {
+ outRecord->insertStrategyInfo<OutRecordInfo>().first->isNonDiscoveryInterest = true;
+ }
}
}
diff --git a/daemon/fw/strategy.cpp b/daemon/fw/strategy.cpp
index 785cc8b..3dc9abd 100644
--- a/daemon/fw/strategy.cpp
+++ b/daemon/fw/strategy.cpp
@@ -193,16 +193,15 @@
NFD_LOG_DEBUG("onDroppedInterest out=" << egress.getId() << " name=" << interest.getName());
}
-void
+pit::OutRecord*
Strategy::sendInterest(const shared_ptr<pit::Entry>& pitEntry, Face& egress, const Interest& interest)
{
if (interest.getTag<lp::PitToken>() != nullptr) {
Interest interest2 = interest; // make a copy to preserve tag on original packet
interest2.removeTag<lp::PitToken>();
- m_forwarder.onOutgoingInterest(pitEntry, egress, interest2);
- return;
+ return m_forwarder.onOutgoingInterest(pitEntry, egress, interest2);
}
- m_forwarder.onOutgoingInterest(pitEntry, egress, interest);
+ return m_forwarder.onOutgoingInterest(pitEntry, egress, interest);
}
void
@@ -212,7 +211,7 @@
<< " nexthop=" << nextHop.getFace().getId());
}
-void
+bool
Strategy::sendData(const shared_ptr<pit::Entry>& pitEntry, const Data& data, Face& egress)
{
BOOST_ASSERT(pitEntry->getInterest().matchesData(data));
@@ -230,10 +229,9 @@
if (pitToken != nullptr) {
Data data2 = data; // make a copy so each downstream can get a different PIT token
data2.setTag(pitToken);
- m_forwarder.onOutgoingData(data2, egress);
- return;
+ return m_forwarder.onOutgoingData(data2, egress);
}
- m_forwarder.onOutgoingData(data, egress);
+ return m_forwarder.onOutgoingData(data, egress);
}
void
diff --git a/daemon/fw/strategy.hpp b/daemon/fw/strategy.hpp
index 7c93327..37b1553 100644
--- a/daemon/fw/strategy.hpp
+++ b/daemon/fw/strategy.hpp
@@ -255,8 +255,9 @@
* \param pitEntry the PIT entry
* \param egress face through which to send out the Interest
* \param interest the Interest packet
+ * \return A pointer to the out-record created or nullptr if the Interest was dropped
*/
- VIRTUAL_WITH_TESTS void
+ VIRTUAL_WITH_TESTS pit::OutRecord*
sendInterest(const shared_ptr<pit::Entry>& pitEntry, Face& egress,
const Interest& interest);
@@ -264,8 +265,9 @@
* \param pitEntry the PIT entry
* \param data the Data packet
* \param egress face through which to send out the Data
+ * \return Whether the Data was sent (true) or dropped (false)
*/
- VIRTUAL_WITH_TESTS void
+ VIRTUAL_WITH_TESTS bool
sendData(const shared_ptr<pit::Entry>& pitEntry, const Data& data, Face& egress);
/** \brief Send a Data packet to all matched and qualified faces.
@@ -298,12 +300,13 @@
* \param pitEntry the PIT entry
* \param egress face through which to send out the Nack
* \param header the Nack header
+ * \return Whether the Nack was sent (true) or dropped (false)
*/
- VIRTUAL_WITH_TESTS void
+ VIRTUAL_WITH_TESTS bool
sendNack(const shared_ptr<pit::Entry>& pitEntry, Face& egress,
const lp::NackHeader& header)
{
- m_forwarder.onOutgoingNack(pitEntry, egress, header);
+ return m_forwarder.onOutgoingNack(pitEntry, egress, header);
}
/** \brief Send Nack to every face that has an in-record, except those in \p exceptFaces