fw: add FaceEndpoint parameter in Forwarding and Strategy API
refs: #4849
Change-Id: Ibe22557488fa83a555fd13d6eb8e03f8d81d0b2b
diff --git a/daemon/fw/access-strategy.cpp b/daemon/fw/access-strategy.cpp
index b07211b..e7e0904 100644
--- a/daemon/fw/access-strategy.cpp
+++ b/daemon/fw/access-strategy.cpp
@@ -56,19 +56,19 @@
}
void
-AccessStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest,
+AccessStrategy::afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry)
{
RetxSuppressionResult suppressResult = m_retxSuppression.decidePerPitEntry(*pitEntry);
switch (suppressResult) {
case RetxSuppressionResult::NEW:
- this->afterReceiveNewInterest(inFace, interest, pitEntry);
+ this->afterReceiveNewInterest(ingress.face, interest, pitEntry);
break;
case RetxSuppressionResult::FORWARD:
- this->afterReceiveRetxInterest(inFace, interest, pitEntry);
+ this->afterReceiveRetxInterest(ingress.face, interest, pitEntry);
break;
case RetxSuppressionResult::SUPPRESS:
- NFD_LOG_DEBUG(interest << " interestFrom " << inFace.getId() << " retx-suppress");
+ NFD_LOG_DEBUG(interest << " interestFrom " << ingress << " retx-suppress");
break;
default:
BOOST_ASSERT(false);
@@ -87,8 +87,7 @@
// has measurements for Interest Name?
if (mi != nullptr) {
- NFD_LOG_DEBUG(interest << " interestFrom " << inFace.getId() <<
- " new-interest mi=" << miName);
+ NFD_LOG_DEBUG(interest << " interestFrom " << inFace.getId() << " new-interest mi=" << miName);
// send to last working nexthop
bool isSentToLastNexthop = this->sendToLastNexthop(inFace, interest, pitEntry, *mi, fibEntry);
@@ -98,8 +97,7 @@
}
}
else {
- NFD_LOG_DEBUG(interest << " interestFrom " << inFace.getId() <<
- " new-interest no-mi");
+ NFD_LOG_DEBUG(interest << " interestFrom " << inFace.getId() << " new-interest no-mi");
}
// no measurements, or last working nexthop unavailable
@@ -148,10 +146,10 @@
}
RttEstimator::Duration rto = mi.rtt.computeRto();
- NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << mi.lastNexthop <<
- " last-nexthop rto=" << time::duration_cast<time::microseconds>(rto).count());
+ NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << mi.lastNexthop
+ << " last-nexthop rto=" << time::duration_cast<time::microseconds>(rto).count());
- this->sendInterest(pitEntry, *outFace, interest);
+ this->sendInterest(pitEntry, FaceEndpoint(*outFace, 0), interest);
// schedule RTO timeout
PitInfo* pi = pitEntry->insertStrategyInfo<PitInfo>().first;
@@ -171,8 +169,8 @@
Face* inFace = this->getFace(inFaceId);
if (inFace == nullptr) {
- NFD_LOG_DEBUG(pitEntry->getInterest() << " timeoutFrom " << firstOutFaceId <<
- " inFace-gone " << inFaceId);
+ NFD_LOG_DEBUG(pitEntry->getInterest() << " timeoutFrom " << firstOutFaceId
+ << " inFace-gone " << inFaceId);
return;
}
@@ -185,8 +183,8 @@
const Interest& interest = inRecord->getInterest();
const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
- NFD_LOG_DEBUG(pitEntry->getInterest() << " timeoutFrom " << firstOutFaceId <<
- " multicast-except " << firstOutFaceId);
+ NFD_LOG_DEBUG(pitEntry->getInterest() << " timeoutFrom " << firstOutFaceId
+ << " multicast-except " << firstOutFaceId);
this->multicast(*inFace, interest, pitEntry, fibEntry, firstOutFaceId);
}
@@ -202,9 +200,8 @@
wouldViolateScope(inFace, interest, outFace)) {
continue;
}
- NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << outFace.getId() <<
- " multicast");
- this->sendInterest(pitEntry, outFace, interest);
+ NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << outFace.getId() << " multicast");
+ this->sendInterest(pitEntry, FaceEndpoint(outFace, 0), interest);
++nSent;
}
return nSent;
@@ -212,7 +209,7 @@
void
AccessStrategy::beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data)
+ const FaceEndpoint& ingress, const Data& data)
{
PitInfo* pi = pitEntry->getStrategyInfo<PitInfo>();
if (pi != nullptr) {
@@ -220,22 +217,20 @@
}
if (!pitEntry->hasInRecords()) { // already satisfied by another upstream
- NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << inFace.getId() <<
- " not-fastest");
+ NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << ingress << " not-fastest");
return;
}
- auto outRecord = pitEntry->getOutRecord(inFace, 0);
+ auto outRecord = pitEntry->getOutRecord(ingress.face, 0);
if (outRecord == pitEntry->out_end()) { // no out-record
- NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << inFace.getId() <<
- " no-out-record");
+ NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << ingress << " no-out-record");
return;
}
auto rtt = time::steady_clock::now() - outRecord->getLastRenewed();
- NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << inFace.getId() <<
- " rtt=" << time::duration_cast<time::microseconds>(rtt).count());
- this->updateMeasurements(inFace, data, time::duration_cast<RttEstimator::Duration>(rtt));
+ NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << ingress
+ << " rtt=" << time::duration_cast<time::microseconds>(rtt).count());
+ this->updateMeasurements(ingress.face, data, time::duration_cast<RttEstimator::Duration>(rtt));
}
void
diff --git a/daemon/fw/access-strategy.hpp b/daemon/fw/access-strategy.hpp
index cdb55e2..2dc1530 100644
--- a/daemon/fw/access-strategy.hpp
+++ b/daemon/fw/access-strategy.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -43,6 +43,8 @@
* the granularity of this knowledge is the parent of Data Name.
* 3. Forward subsequent Interests to the last working nexthop.
* If it doesn't respond, multicast again.
+ *
+ * \note This strategy is not EndpointId-aware.
*/
class AccessStrategy : public Strategy
{
@@ -55,12 +57,12 @@
public: // triggers
void
- afterReceiveInterest(const Face& inFace, const Interest& interest,
+ afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry) override;
void
beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data) override;
+ const FaceEndpoint& ingress, const Data& data) override;
private: // StrategyInfo
/** \brief StrategyInfo on PIT entry
diff --git a/daemon/fw/asf-strategy.cpp b/daemon/fw/asf-strategy.cpp
index 67d6944..779daee 100644
--- a/daemon/fw/asf-strategy.cpp
+++ b/daemon/fw/asf-strategy.cpp
@@ -107,7 +107,7 @@
}
void
-AsfStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest,
+AsfStrategy::afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry)
{
// Should the Interest be suppressed?
@@ -118,7 +118,7 @@
case RetxSuppressionResult::FORWARD:
break;
case RetxSuppressionResult::SUPPRESS:
- NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " suppressed");
+ NFD_LOG_DEBUG(interest << " from=" << ingress << " suppressed");
return;
}
@@ -126,15 +126,15 @@
const fib::NextHopList& nexthops = fibEntry.getNextHops();
if (nexthops.size() == 0) {
- sendNoRouteNack(inFace, interest, pitEntry);
+ sendNoRouteNack(ingress, interest, pitEntry);
this->rejectPendingInterest(pitEntry);
return;
}
- Face* faceToUse = getBestFaceForForwarding(fibEntry, interest, inFace);
+ Face* faceToUse = getBestFaceForForwarding(fibEntry, interest, ingress.face);
if (faceToUse == nullptr) {
- sendNoRouteNack(inFace, interest, pitEntry);
+ sendNoRouteNack(ingress, interest, pitEntry);
this->rejectPendingInterest(pitEntry);
return;
}
@@ -145,7 +145,7 @@
// If necessary, send probe
if (m_probing.isProbingNeeded(fibEntry, interest)) {
- Face* faceToProbe = m_probing.getFaceToProbe(inFace, interest, fibEntry, *faceToUse);
+ Face* faceToProbe = m_probing.getFaceToProbe(ingress.face, interest, fibEntry, *faceToUse);
if (faceToProbe != nullptr) {
bool wantNewNonce = true;
@@ -157,7 +157,7 @@
void
AsfStrategy::beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data)
+ const FaceEndpoint& ingress, const Data& data)
{
NamespaceInfo* namespaceInfo = m_measurements.getNamespaceInfo(pitEntry->getName());
@@ -167,14 +167,14 @@
}
// Record the RTT between the Interest out to Data in
- FaceInfo* faceInfo = namespaceInfo->get(inFace.getId());
+ FaceInfo* faceInfo = namespaceInfo->get(ingress.face.getId());
if (faceInfo == nullptr) {
return;
}
- faceInfo->recordRtt(pitEntry, inFace);
+ faceInfo->recordRtt(pitEntry, ingress.face);
// Extend lifetime for measurements associated with Face
- namespaceInfo->extendFaceInfoLifetime(*faceInfo, inFace.getId());
+ namespaceInfo->extendFaceInfoLifetime(*faceInfo, ingress.face.getId());
if (faceInfo->isTimeoutScheduled()) {
faceInfo->cancelTimeoutEvent(data.getName());
@@ -182,11 +182,11 @@
}
void
-AsfStrategy::afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+AsfStrategy::afterReceiveNack(const FaceEndpoint& ingress, const lp::Nack& nack,
const shared_ptr<pit::Entry>& pitEntry)
{
- NFD_LOG_DEBUG("Nack for " << nack.getInterest() << " from=" << inFace.getId() << ": " << nack.getReason());
- onTimeout(pitEntry->getName(), inFace.getId());
+ NFD_LOG_DEBUG("Nack for " << nack.getInterest() << " from=" << ingress << ": reason=" << nack.getReason());
+ onTimeout(pitEntry->getName(), ingress.face.getId());
}
////////////////////////////////////////////////////////////////////////////////
@@ -199,34 +199,35 @@
Face& outFace,
bool wantNewNonce)
{
+ auto egress = FaceEndpoint(outFace, 0);
+
if (wantNewNonce) {
//Send probe: interest with new Nonce
Interest probeInterest(interest);
probeInterest.refreshNonce();
NFD_LOG_TRACE("Sending probe for " << probeInterest << probeInterest.getNonce()
- << " to FaceId: " << outFace.getId());
- this->sendInterest(pitEntry, outFace, probeInterest);
+ << " to: " << egress);
+ this->sendInterest(pitEntry, egress, probeInterest);
}
else {
- this->sendInterest(pitEntry, outFace, interest);
+ this->sendInterest(pitEntry, egress, interest);
}
- FaceInfo& faceInfo = m_measurements.getOrCreateFaceInfo(fibEntry, interest, outFace.getId());
+ FaceInfo& faceInfo = m_measurements.getOrCreateFaceInfo(fibEntry, interest, egress.face.getId());
// Refresh measurements since Face is being used for forwarding
NamespaceInfo& namespaceInfo = m_measurements.getOrCreateNamespaceInfo(fibEntry, interest);
- namespaceInfo.extendFaceInfoLifetime(faceInfo, outFace.getId());
+ namespaceInfo.extendFaceInfoLifetime(faceInfo, egress.face.getId());
if (!faceInfo.isTimeoutScheduled()) {
// Estimate and schedule timeout
RttEstimator::Duration timeout = faceInfo.computeRto();
- NFD_LOG_TRACE("Scheduling timeout for " << fibEntry.getPrefix()
- << " FaceId: " << outFace.getId()
- << " in " << time::duration_cast<time::milliseconds>(timeout) << " ms");
+ NFD_LOG_TRACE("Scheduling timeout for " << fibEntry.getPrefix() << " to: " << egress
+ << " in " << time::duration_cast<time::milliseconds>(timeout) << " ms");
scheduler::EventId id = scheduler::schedule(timeout,
- bind(&AsfStrategy::onTimeout, this, interest.getName(), outFace.getId()));
+ bind(&AsfStrategy::onTimeout, this, interest.getName(), egress.face.getId()));
faceInfo.setTimeoutEvent(id, interest.getName());
}
@@ -356,14 +357,14 @@
}
void
-AsfStrategy::sendNoRouteNack(const Face& inFace, const Interest& interest,
+AsfStrategy::sendNoRouteNack(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry)
{
- NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " noNextHop");
+ NFD_LOG_DEBUG(interest << " from=" << ingress << " noNextHop");
lp::NackHeader nackHeader;
nackHeader.setReason(lp::NackReason::NO_ROUTE);
- this->sendNack(pitEntry, inFace, nackHeader);
+ this->sendNack(pitEntry, ingress, nackHeader);
}
} // namespace asf
diff --git a/daemon/fw/asf-strategy.hpp b/daemon/fw/asf-strategy.hpp
index b58e656..2155d94 100644
--- a/daemon/fw/asf-strategy.hpp
+++ b/daemon/fw/asf-strategy.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -40,6 +40,8 @@
* \see Vince Lehman, Ashlesh Gawande, Rodrigo Aldecoa, Dmitri Krioukov, Beichuan Zhang, Lixia Zhang, and Lan Wang,
* "An Experimental Investigation of Hyperbolic Routing with a Smart Forwarding Plane in NDN,"
* NDN Technical Report NDN-0042, 2016. http://named-data.net/techreports.html
+ *
+ * \note This strategy is not EndpointId-aware.
*/
class AsfStrategy : public Strategy
{
@@ -52,15 +54,15 @@
public: // triggers
void
- afterReceiveInterest(const Face& inFace, const Interest& interest,
+ afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry) override;
void
beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data) override;
+ const FaceEndpoint& ingress, const Data& data) override;
void
- afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+ afterReceiveNack(const FaceEndpoint& ingress, const lp::Nack& nack,
const shared_ptr<pit::Entry>& pitEntry) override;
private:
@@ -78,7 +80,7 @@
onTimeout(const Name& interestName, const FaceId faceId);
void
- sendNoRouteNack(const Face& inFace, const Interest& interest, const shared_ptr<pit::Entry>& pitEntry);
+ sendNoRouteNack(const FaceEndpoint& ingress, const Interest& interest, const shared_ptr<pit::Entry>& pitEntry);
void
processParams(const PartialName& parsed);
diff --git a/daemon/fw/best-route-strategy.cpp b/daemon/fw/best-route-strategy.cpp
index dbf410b..658a17a 100644
--- a/daemon/fw/best-route-strategy.cpp
+++ b/daemon/fw/best-route-strategy.cpp
@@ -35,7 +35,7 @@
}
void
-BestRouteStrategyBase::afterReceiveInterest(const Face& inFace, const Interest& interest,
+BestRouteStrategyBase::afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry)
{
if (hasPendingOutRecords(*pitEntry)) {
@@ -46,9 +46,9 @@
const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
for (const auto& nexthop : fibEntry.getNextHops()) {
Face& outFace = nexthop.getFace();
- if (!wouldViolateScope(inFace, interest, outFace) &&
+ if (!wouldViolateScope(ingress.face, interest, outFace) &&
canForwardToLegacy(*pitEntry, outFace)) {
- this->sendInterest(pitEntry, outFace, interest);
+ this->sendInterest(pitEntry, FaceEndpoint(outFace, 0), interest);
return;
}
}
diff --git a/daemon/fw/best-route-strategy.hpp b/daemon/fw/best-route-strategy.hpp
index 3cef907..e3cc60c 100644
--- a/daemon/fw/best-route-strategy.hpp
+++ b/daemon/fw/best-route-strategy.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -35,7 +35,7 @@
{
public:
void
- afterReceiveInterest(const Face& inFace, const Interest& interest,
+ afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry) override;
protected:
@@ -52,6 +52,8 @@
* \note This strategy is superceded by Best Route strategy version 2,
* which allows consumer retransmissions. This version is kept for
* comparison purposes and is not recommended for general usage.
+ *
+ * \note This strategy is not EndpointId-aware.
*/
class BestRouteStrategy : public BestRouteStrategyBase
{
diff --git a/daemon/fw/best-route-strategy2.cpp b/daemon/fw/best-route-strategy2.cpp
index 7a1f063..ebab2ef 100644
--- a/daemon/fw/best-route-strategy2.cpp
+++ b/daemon/fw/best-route-strategy2.cpp
@@ -124,13 +124,12 @@
}
void
-BestRouteStrategy2::afterReceiveInterest(const Face& inFace, const Interest& interest,
+BestRouteStrategy2::afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry)
{
RetxSuppressionResult suppression = m_retxSuppression.decidePerPitEntry(*pitEntry);
if (suppression == RetxSuppressionResult::SUPPRESS) {
- NFD_LOG_DEBUG(interest << " from=" << inFace.getId()
- << " suppressed");
+ NFD_LOG_DEBUG(interest << " from=" << ingress << " suppressed");
return;
}
@@ -141,58 +140,55 @@
if (suppression == RetxSuppressionResult::NEW) {
// forward to nexthop with lowest cost except downstream
it = std::find_if(nexthops.begin(), nexthops.end(), [&] (const auto& nexthop) {
- return isNextHopEligible(inFace, interest, nexthop, pitEntry);
+ return isNextHopEligible(ingress.face, interest, nexthop, pitEntry);
});
if (it == nexthops.end()) {
- NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " noNextHop");
+ NFD_LOG_DEBUG(interest << " from=" << ingress << " noNextHop");
lp::NackHeader nackHeader;
nackHeader.setReason(lp::NackReason::NO_ROUTE);
- this->sendNack(pitEntry, inFace, nackHeader);
+ this->sendNack(pitEntry, ingress, nackHeader);
this->rejectPendingInterest(pitEntry);
return;
}
- Face& outFace = it->getFace();
- this->sendInterest(pitEntry, outFace, interest);
- NFD_LOG_DEBUG(interest << " from=" << inFace.getId()
- << " newPitEntry-to=" << outFace.getId());
+ auto egress = FaceEndpoint(it->getFace(), 0);
+ this->sendInterest(pitEntry, egress, interest);
+ NFD_LOG_DEBUG(interest << " from=" << ingress << " newPitEntry-to=" << egress);
return;
}
// find an unused upstream with lowest cost except downstream
it = std::find_if(nexthops.begin(), nexthops.end(), [&] (const auto& nexthop) {
- return isNextHopEligible(inFace, interest, nexthop, pitEntry, true, time::steady_clock::now());
+ return isNextHopEligible(ingress.face, interest, nexthop, pitEntry, true, time::steady_clock::now());
});
if (it != nexthops.end()) {
- Face& outFace = it->getFace();
- this->sendInterest(pitEntry, outFace, interest);
- NFD_LOG_DEBUG(interest << " from=" << inFace.getId()
- << " retransmit-unused-to=" << outFace.getId());
+ auto egress = FaceEndpoint(it->getFace(), 0);
+ this->sendInterest(pitEntry, egress, interest);
+ NFD_LOG_DEBUG(interest << " from=" << ingress << " retransmit-unused-to=" << egress);
return;
}
// find an eligible upstream that is used earliest
- it = findEligibleNextHopWithEarliestOutRecord(inFace, interest, nexthops, pitEntry);
+ it = findEligibleNextHopWithEarliestOutRecord(ingress.face, interest, nexthops, pitEntry);
if (it == nexthops.end()) {
- NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " retransmitNoNextHop");
+ NFD_LOG_DEBUG(interest << " from=" << ingress << " retransmitNoNextHop");
}
else {
- Face& outFace = it->getFace();
- this->sendInterest(pitEntry, outFace, interest);
- NFD_LOG_DEBUG(interest << " from=" << inFace.getId()
- << " retransmit-retry-to=" << outFace.getId());
+ auto egress = FaceEndpoint(it->getFace(), 0);
+ this->sendInterest(pitEntry, egress, interest);
+ NFD_LOG_DEBUG(interest << " from=" << ingress << " retransmit-retry-to=" << egress);
}
}
void
-BestRouteStrategy2::afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+BestRouteStrategy2::afterReceiveNack(const FaceEndpoint& ingress, const lp::Nack& nack,
const shared_ptr<pit::Entry>& pitEntry)
{
- this->processNack(inFace, nack, pitEntry);
+ this->processNack(ingress.face, nack, pitEntry);
}
} // namespace fw
diff --git a/daemon/fw/best-route-strategy2.hpp b/daemon/fw/best-route-strategy2.hpp
index 8d1f144..598469f 100644
--- a/daemon/fw/best-route-strategy2.hpp
+++ b/daemon/fw/best-route-strategy2.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -49,6 +49,8 @@
*
* This strategy returns Nack to all downstreams if all upstreams have returned Nacks.
* The reason of the sent Nack equals the least severe reason among received Nacks.
+ *
+ * \note This strategy is not EndpointId-aware.
*/
class BestRouteStrategy2 : public Strategy
, public ProcessNackTraits<BestRouteStrategy2>
@@ -61,11 +63,11 @@
getStrategyName();
void
- afterReceiveInterest(const Face& inFace, const Interest& interest,
+ afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry) override;
void
- afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+ afterReceiveNack(const FaceEndpoint& ingress, const lp::Nack& nack,
const shared_ptr<pit::Entry>& pitEntry) override;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
diff --git a/daemon/fw/face-endpoint.hpp b/daemon/fw/face-endpoint.hpp
new file mode 100644
index 0000000..acfbc2e
--- /dev/null
+++ b/daemon/fw/face-endpoint.hpp
@@ -0,0 +1,57 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_FW_FACE_ENDPOINT_HPP
+#define NFD_DAEMON_FW_FACE_ENDPOINT_HPP
+
+#include "face/face.hpp"
+
+namespace nfd {
+
+/** \brief Represents a face-endpoint pair in the forwarder
+ */
+class FaceEndpoint
+{
+public:
+ FaceEndpoint(const Face& face, EndpointId endpoint)
+ : face(const_cast<Face&>(face))
+ , endpoint(endpoint)
+ {
+ }
+
+public:
+ Face& face;
+ const EndpointId endpoint;
+};
+
+inline std::ostream&
+operator<<(std::ostream& os, const FaceEndpoint& fe)
+{
+ return os << "(" << fe.face.getId() << "," << fe.endpoint << ")";
+}
+
+} // namespace nfd
+
+#endif // NFD_DAEMON_FW_FACE_ENDPOINT_HPP
\ No newline at end of file
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index f4e5ac9..508a890 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -53,19 +53,19 @@
m_faceTable.afterAdd.connect([this] (Face& face) {
face.afterReceiveInterest.connect(
[this, &face] (const Interest& interest) {
- this->startProcessInterest(face, interest);
+ this->startProcessInterest(FaceEndpoint(face, 0), interest);
});
face.afterReceiveData.connect(
[this, &face] (const Data& data) {
- this->startProcessData(face, data);
+ this->startProcessData(FaceEndpoint(face, 0), data);
});
face.afterReceiveNack.connect(
[this, &face] (const lp::Nack& nack) {
- this->startProcessNack(face, nack);
+ this->startProcessNack(FaceEndpoint(face, 0), nack);
});
face.onDroppedInterest.connect(
[this, &face] (const Interest& interest) {
- this->onDroppedInterest(face, interest);
+ this->onDroppedInterest(FaceEndpoint(face, 0), interest);
});
});
@@ -79,20 +79,19 @@
Forwarder::~Forwarder() = default;
void
-Forwarder::onIncomingInterest(Face& inFace, const Interest& interest)
+Forwarder::onIncomingInterest(const FaceEndpoint& ingress, const Interest& interest)
{
// receive Interest
- NFD_LOG_DEBUG("onIncomingInterest face=" << inFace.getId() <<
- " interest=" << interest.getName());
- interest.setTag(make_shared<lp::IncomingFaceIdTag>(inFace.getId()));
+ NFD_LOG_DEBUG("onIncomingInterest in=" << ingress << " interest=" << interest.getName());
+ interest.setTag(make_shared<lp::IncomingFaceIdTag>(ingress.face.getId()));
++m_counters.nInInterests;
// /localhost scope control
- bool isViolatingLocalhost = inFace.getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL &&
+ bool isViolatingLocalhost = ingress.face.getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL &&
scope_prefix::LOCALHOST.isPrefixOf(interest.getName());
if (isViolatingLocalhost) {
- NFD_LOG_DEBUG("onIncomingInterest face=" << inFace.getId() <<
- " interest=" << interest.getName() << " violates /localhost");
+ NFD_LOG_DEBUG("onIncomingInterest in=" << ingress
+ << " interest=" << interest.getName() << " violates /localhost");
// (drop)
return;
}
@@ -101,15 +100,15 @@
bool hasDuplicateNonceInDnl = m_deadNonceList.has(interest.getName(), interest.getNonce());
if (hasDuplicateNonceInDnl) {
// goto Interest loop pipeline
- this->onInterestLoop(inFace, interest);
+ this->onInterestLoop(ingress, interest);
return;
}
// strip forwarding hint if Interest has reached producer region
if (!interest.getForwardingHint().empty() &&
m_networkRegionTable.isInProducerRegion(interest.getForwardingHint())) {
- NFD_LOG_DEBUG("onIncomingInterest face=" << inFace.getId() <<
- " interest=" << interest.getName() << " reaching-producer-region");
+ NFD_LOG_DEBUG("onIncomingInterest in=" << ingress
+ << " interest=" << interest.getName() << " reaching-producer-region");
const_cast<Interest&>(interest).setForwardingHint({});
}
@@ -117,49 +116,47 @@
shared_ptr<pit::Entry> pitEntry = m_pit.insert(interest).first;
// detect duplicate Nonce in PIT entry
- int dnw = fw::findDuplicateNonce(*pitEntry, interest.getNonce(), inFace);
+ int dnw = fw::findDuplicateNonce(*pitEntry, interest.getNonce(), ingress.face);
bool hasDuplicateNonceInPit = dnw != fw::DUPLICATE_NONCE_NONE;
- if (inFace.getLinkType() == ndn::nfd::LINK_TYPE_POINT_TO_POINT) {
+ if (ingress.face.getLinkType() == ndn::nfd::LINK_TYPE_POINT_TO_POINT) {
// for p2p face: duplicate Nonce from same incoming face is not loop
hasDuplicateNonceInPit = hasDuplicateNonceInPit && !(dnw & fw::DUPLICATE_NONCE_IN_SAME);
}
if (hasDuplicateNonceInPit) {
// goto Interest loop pipeline
- this->onInterestLoop(inFace, interest);
+ this->onInterestLoop(ingress, interest);
return;
}
// is pending?
if (!pitEntry->hasInRecords()) {
m_cs.find(interest,
- bind(&Forwarder::onContentStoreHit, this, std::ref(inFace), pitEntry, _1, _2),
- bind(&Forwarder::onContentStoreMiss, this, std::ref(inFace), pitEntry, _1));
+ bind(&Forwarder::onContentStoreHit, this, ingress, pitEntry, _1, _2),
+ bind(&Forwarder::onContentStoreMiss, this, ingress, pitEntry, _1));
}
else {
- this->onContentStoreMiss(inFace, pitEntry, interest);
+ this->onContentStoreMiss(ingress, pitEntry, interest);
}
}
void
-Forwarder::onInterestLoop(Face& inFace, const Interest& interest)
+Forwarder::onInterestLoop(const FaceEndpoint& ingress, const Interest& interest)
{
// if multi-access or ad hoc face, drop
- if (inFace.getLinkType() != ndn::nfd::LINK_TYPE_POINT_TO_POINT) {
- NFD_LOG_DEBUG("onInterestLoop face=" << inFace.getId() <<
- " interest=" << interest.getName() <<
- " drop");
+ if (ingress.face.getLinkType() != ndn::nfd::LINK_TYPE_POINT_TO_POINT) {
+ NFD_LOG_DEBUG("onInterestLoop in=" << ingress
+ << " interest=" << interest.getName() << " drop");
return;
}
- NFD_LOG_DEBUG("onInterestLoop face=" << inFace.getId() <<
- " interest=" << interest.getName() <<
- " send-Nack-duplicate");
+ NFD_LOG_DEBUG("onInterestLoop in=" << ingress << " interest=" << interest.getName()
+ << " send-Nack-duplicate");
// send Nack with reason=DUPLICATE
// note: Don't enter outgoing Nack pipeline because it needs an in-record.
lp::Nack nack(interest);
nack.setReason(lp::NackReason::DUPLICATE);
- inFace.sendNack(nack);
+ ingress.face.sendNack(nack);
}
static inline bool
@@ -169,14 +166,14 @@
}
void
-Forwarder::onContentStoreMiss(const Face& inFace, const shared_ptr<pit::Entry>& pitEntry,
- const Interest& interest)
+Forwarder::onContentStoreMiss(const FaceEndpoint& ingress,
+ const shared_ptr<pit::Entry>& pitEntry, const Interest& interest)
{
NFD_LOG_DEBUG("onContentStoreMiss interest=" << interest.getName());
++m_counters.nCsMisses;
// insert in-record
- pitEntry->insertOrUpdateInRecord(const_cast<Face&>(inFace), 0, interest);
+ pitEntry->insertOrUpdateInRecord(ingress.face, ingress.endpoint, interest);
// set PIT expiry timer to the time that the last PIT in-record expires
auto lastExpiring = std::max_element(pitEntry->in_begin(), pitEntry->in_end(), &compare_InRecord_expiry);
@@ -192,18 +189,18 @@
NFD_LOG_DEBUG("onContentStoreMiss interest=" << interest.getName() << " nexthop-faceid=" << nextHopFace->getId());
// go to outgoing Interest pipeline
// scope control is unnecessary, because privileged app explicitly wants to forward
- this->onOutgoingInterest(pitEntry, *nextHopFace, interest);
+ this->onOutgoingInterest(pitEntry, FaceEndpoint(*nextHopFace, 0), interest);
}
return;
}
// dispatch to strategy: after incoming Interest
this->dispatchToStrategy(*pitEntry,
- [&] (fw::Strategy& strategy) { strategy.afterReceiveInterest(inFace, interest, pitEntry); });
+ [&] (fw::Strategy& strategy) { strategy.afterReceiveInterest(ingress, interest, pitEntry); });
}
void
-Forwarder::onContentStoreHit(const Face& inFace, const shared_ptr<pit::Entry>& pitEntry,
+Forwarder::onContentStoreHit(const FaceEndpoint& ingress, const shared_ptr<pit::Entry>& pitEntry,
const Interest& interest, const Data& data)
{
NFD_LOG_DEBUG("onContentStoreHit interest=" << interest.getName());
@@ -220,28 +217,28 @@
// dispatch to strategy: after Content Store hit
this->dispatchToStrategy(*pitEntry,
- [&] (fw::Strategy& strategy) { strategy.afterContentStoreHit(pitEntry, inFace, data); });
+ [&] (fw::Strategy& strategy) { strategy.afterContentStoreHit(pitEntry, ingress, data); });
}
void
-Forwarder::onOutgoingInterest(const shared_ptr<pit::Entry>& pitEntry, Face& outFace, const Interest& interest)
+Forwarder::onOutgoingInterest(const shared_ptr<pit::Entry>& pitEntry,
+ const FaceEndpoint& egress, const Interest& interest)
{
- NFD_LOG_DEBUG("onOutgoingInterest face=" << outFace.getId() <<
- " interest=" << pitEntry->getName());
+ NFD_LOG_DEBUG("onOutgoingInterest out=" << egress << " interest=" << pitEntry->getName());
// insert out-record
- pitEntry->insertOrUpdateOutRecord(outFace, 0, interest);
+ pitEntry->insertOrUpdateOutRecord(egress.face, egress.endpoint, interest);
// send Interest
- outFace.sendInterest(interest);
+ egress.face.sendInterest(interest);
++m_counters.nOutInterests;
}
void
Forwarder::onInterestFinalize(const shared_ptr<pit::Entry>& pitEntry)
{
- NFD_LOG_DEBUG("onInterestFinalize interest=" << pitEntry->getName() <<
- (pitEntry->isSatisfied ? " satisfied" : " unsatisfied"));
+ NFD_LOG_DEBUG("onInterestFinalize interest=" << pitEntry->getName()
+ << (pitEntry->isSatisfied ? " satisfied" : " unsatisfied"));
// Dead Nonce List insert if necessary
this->insertDeadNonceList(*pitEntry, 0);
@@ -260,19 +257,18 @@
}
void
-Forwarder::onIncomingData(Face& inFace, const Data& data)
+Forwarder::onIncomingData(const FaceEndpoint& ingress, const Data& data)
{
// receive Data
- NFD_LOG_DEBUG("onIncomingData face=" << inFace.getId() << " data=" << data.getName());
- data.setTag(make_shared<lp::IncomingFaceIdTag>(inFace.getId()));
+ NFD_LOG_DEBUG("onIncomingData in=" << ingress << " data=" << data.getName());
+ data.setTag(make_shared<lp::IncomingFaceIdTag>(ingress.face.getId()));
++m_counters.nInData;
// /localhost scope control
- bool isViolatingLocalhost = inFace.getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL &&
+ bool isViolatingLocalhost = ingress.face.getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL &&
scope_prefix::LOCALHOST.isPrefixOf(data.getName());
if (isViolatingLocalhost) {
- NFD_LOG_DEBUG("onIncomingData face=" << inFace.getId() <<
- " data=" << data.getName() << " violates /localhost");
+ NFD_LOG_DEBUG("onIncomingData in=" << ingress << " data=" << data.getName() << " violates /localhost");
// (drop)
return;
}
@@ -281,7 +277,7 @@
pit::DataMatchResult pitMatches = m_pit.findAllDataMatches(data);
if (pitMatches.size() == 0) {
// goto Data unsolicited pipeline
- this->onDataUnsolicited(inFace, data);
+ this->onDataUnsolicited(ingress, data);
return;
}
@@ -299,22 +295,22 @@
// trigger strategy: after receive Data
this->dispatchToStrategy(*pitEntry,
- [&] (fw::Strategy& strategy) { strategy.afterReceiveData(pitEntry, inFace, data); });
+ [&] (fw::Strategy& strategy) { strategy.afterReceiveData(pitEntry, ingress, data); });
// mark PIT satisfied
pitEntry->isSatisfied = true;
pitEntry->dataFreshnessPeriod = data.getFreshnessPeriod();
// Dead Nonce List insert if necessary (for out-record of inFace)
- this->insertDeadNonceList(*pitEntry, &inFace);
+ this->insertDeadNonceList(*pitEntry, &ingress.face);
// delete PIT entry's out-record
- pitEntry->deleteOutRecord(inFace, 0);
+ pitEntry->deleteOutRecord(ingress.face, ingress.endpoint);
}
// when more than one PIT entry is matched, trigger strategy: before satisfy Interest,
// and send Data to all matched out faces
else {
- std::set<Face*> pendingDownstreams;
+ std::set<std::pair<Face*, EndpointId>> pendingDownstreams;
auto now = time::steady_clock::now();
for (const shared_ptr<pit::Entry>& pitEntry : pitMatches) {
@@ -323,7 +319,7 @@
// remember pending downstreams
for (const pit::InRecord& inRecord : pitEntry->getInRecords()) {
if (inRecord.getExpiry() > now) {
- pendingDownstreams.insert(&inRecord.getFace());
+ pendingDownstreams.emplace(&inRecord.getFace(), inRecord.getEndpointId());
}
}
@@ -332,62 +328,60 @@
// invoke PIT satisfy callback
this->dispatchToStrategy(*pitEntry,
- [&] (fw::Strategy& strategy) { strategy.beforeSatisfyInterest(pitEntry, inFace, data); });
+ [&] (fw::Strategy& strategy) { strategy.beforeSatisfyInterest(pitEntry, ingress, data); });
// mark PIT satisfied
pitEntry->isSatisfied = true;
pitEntry->dataFreshnessPeriod = data.getFreshnessPeriod();
// Dead Nonce List insert if necessary (for out-record of inFace)
- this->insertDeadNonceList(*pitEntry, &inFace);
+ this->insertDeadNonceList(*pitEntry, &ingress.face);
// clear PIT entry's in and out records
pitEntry->clearInRecords();
- pitEntry->deleteOutRecord(inFace, 0);
+ pitEntry->deleteOutRecord(ingress.face, ingress.endpoint);
}
// foreach pending downstream
- for (Face* pendingDownstream : pendingDownstreams) {
- if (pendingDownstream->getId() == inFace.getId() &&
- pendingDownstream->getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) {
+ for (const auto& pendingDownstream : pendingDownstreams) {
+ if (pendingDownstream.first->getId() == ingress.face.getId() &&
+ pendingDownstream.second == ingress.endpoint &&
+ pendingDownstream.first->getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) {
continue;
}
// goto outgoing Data pipeline
- this->onOutgoingData(data, *pendingDownstream);
+ this->onOutgoingData(data, FaceEndpoint(*pendingDownstream.first, pendingDownstream.second));
}
}
}
void
-Forwarder::onDataUnsolicited(Face& inFace, const Data& data)
+Forwarder::onDataUnsolicited(const FaceEndpoint& ingress, const Data& data)
{
// accept to cache?
- fw::UnsolicitedDataDecision decision = m_unsolicitedDataPolicy->decide(inFace, data);
+ fw::UnsolicitedDataDecision decision = m_unsolicitedDataPolicy->decide(ingress.face, data);
if (decision == fw::UnsolicitedDataDecision::CACHE) {
// CS insert
m_cs.insert(data, true);
}
- NFD_LOG_DEBUG("onDataUnsolicited face=" << inFace.getId() <<
- " data=" << data.getName() <<
- " decision=" << decision);
+ NFD_LOG_DEBUG("onDataUnsolicited in=" << ingress << " data=" << data.getName() << " decision=" << decision);
}
void
-Forwarder::onOutgoingData(const Data& data, Face& outFace)
+Forwarder::onOutgoingData(const Data& data, FaceEndpoint egress)
{
- if (outFace.getId() == face::INVALID_FACEID) {
- NFD_LOG_WARN("onOutgoingData face=invalid data=" << data.getName());
+ if (egress.face.getId() == face::INVALID_FACEID) {
+ NFD_LOG_WARN("onOutgoingData out=(invalid) data=" << data.getName());
return;
}
- NFD_LOG_DEBUG("onOutgoingData face=" << outFace.getId() << " data=" << data.getName());
+ NFD_LOG_DEBUG("onOutgoingData out=" << egress << " data=" << data.getName());
// /localhost scope control
- bool isViolatingLocalhost = outFace.getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL &&
+ bool isViolatingLocalhost = egress.face.getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL &&
scope_prefix::LOCALHOST.isPrefixOf(data.getName());
if (isViolatingLocalhost) {
- NFD_LOG_DEBUG("onOutgoingData face=" << outFace.getId() <<
- " data=" << data.getName() << " violates /localhost");
+ NFD_LOG_DEBUG("onOutgoingData out=" << egress << " data=" << data.getName() << " violates /localhost");
// (drop)
return;
}
@@ -395,22 +389,21 @@
// TODO traffic manager
// send Data
- outFace.sendData(data);
+ egress.face.sendData(data);
++m_counters.nOutData;
}
void
-Forwarder::onIncomingNack(Face& inFace, const lp::Nack& nack)
+Forwarder::onIncomingNack(const FaceEndpoint& ingress, const lp::Nack& nack)
{
// receive Nack
- nack.setTag(make_shared<lp::IncomingFaceIdTag>(inFace.getId()));
+ nack.setTag(make_shared<lp::IncomingFaceIdTag>(ingress.face.getId()));
++m_counters.nInNacks;
// if multi-access or ad hoc face, drop
- if (inFace.getLinkType() != ndn::nfd::LINK_TYPE_POINT_TO_POINT) {
- NFD_LOG_DEBUG("onIncomingNack face=" << inFace.getId() <<
- " nack=" << nack.getInterest().getName() <<
- "~" << nack.getReason() << " face-is-multi-access");
+ if (ingress.face.getLinkType() != ndn::nfd::LINK_TYPE_POINT_TO_POINT) {
+ NFD_LOG_DEBUG("onIncomingNack in=" << ingress << " nack=" << nack.getInterest().getName()
+ << "~" << nack.getReason() << " face-is-multi-access");
return;
}
@@ -418,34 +411,30 @@
shared_ptr<pit::Entry> pitEntry = m_pit.find(nack.getInterest());
// if no PIT entry found, drop
if (pitEntry == nullptr) {
- NFD_LOG_DEBUG("onIncomingNack face=" << inFace.getId() <<
- " nack=" << nack.getInterest().getName() <<
- "~" << nack.getReason() << " no-PIT-entry");
+ NFD_LOG_DEBUG("onIncomingNack in=" << ingress << " nack=" << nack.getInterest().getName()
+ << "~" << nack.getReason() << " no-PIT-entry");
return;
}
// has out-record?
- pit::OutRecordCollection::iterator outRecord = pitEntry->getOutRecord(inFace, 0);
+ pit::OutRecordCollection::iterator outRecord = pitEntry->getOutRecord(ingress.face, ingress.endpoint);
// if no out-record found, drop
if (outRecord == pitEntry->out_end()) {
- NFD_LOG_DEBUG("onIncomingNack face=" << inFace.getId() <<
- " nack=" << nack.getInterest().getName() <<
- "~" << nack.getReason() << " no-out-record");
+ NFD_LOG_DEBUG("onIncomingNack in=" << ingress << " nack=" << nack.getInterest().getName()
+ << "~" << nack.getReason() << " no-out-record");
return;
}
// if out-record has different Nonce, drop
if (nack.getInterest().getNonce() != outRecord->getLastNonce()) {
- NFD_LOG_DEBUG("onIncomingNack face=" << inFace.getId() <<
- " nack=" << nack.getInterest().getName() <<
- "~" << nack.getReason() << " wrong-Nonce " <<
- nack.getInterest().getNonce() << "!=" << outRecord->getLastNonce());
+ NFD_LOG_DEBUG("onIncomingNack in=" << ingress << " nack=" << nack.getInterest().getName()
+ << "~" << nack.getReason() << " wrong-Nonce " << nack.getInterest().getNonce()
+ << "!=" << outRecord->getLastNonce());
return;
}
- NFD_LOG_DEBUG("onIncomingNack face=" << inFace.getId() <<
- " nack=" << nack.getInterest().getName() <<
- "~" << nack.getReason() << " OK");
+ NFD_LOG_DEBUG("onIncomingNack in=" << ingress << " nack=" << nack.getInterest().getName()
+ << "~" << nack.getReason() << " OK");
// record Nack on out-record
outRecord->setIncomingNack(nack);
@@ -457,59 +446,59 @@
// trigger strategy: after receive NACK
this->dispatchToStrategy(*pitEntry,
- [&] (fw::Strategy& strategy) { strategy.afterReceiveNack(inFace, nack, pitEntry); });
+ [&] (fw::Strategy& strategy) { strategy.afterReceiveNack(ingress, nack, pitEntry); });
}
void
-Forwarder::onOutgoingNack(const shared_ptr<pit::Entry>& pitEntry, const Face& outFace,
- const lp::NackHeader& nack)
+Forwarder::onOutgoingNack(const shared_ptr<pit::Entry>& pitEntry,
+ const FaceEndpoint& egress, const lp::NackHeader& nack)
{
- if (outFace.getId() == face::INVALID_FACEID) {
- NFD_LOG_WARN("onOutgoingNack face=invalid" <<
- " nack=" << pitEntry->getInterest().getName() <<
- "~" << nack.getReason() << " no-in-record");
+ if (egress.face.getId() == face::INVALID_FACEID) {
+ NFD_LOG_WARN("onOutgoingNack out=(invalid)"
+ << " nack=" << pitEntry->getInterest().getName()
+ << "~" << nack.getReason() << " no-in-record");
return;
}
// has in-record?
- pit::InRecordCollection::iterator inRecord = pitEntry->getInRecord(outFace, 0);
+ pit::InRecordCollection::iterator inRecord = pitEntry->getInRecord(egress.face, egress.endpoint);
// if no in-record found, drop
if (inRecord == pitEntry->in_end()) {
- NFD_LOG_DEBUG("onOutgoingNack face=" << outFace.getId() <<
- " nack=" << pitEntry->getInterest().getName() <<
- "~" << nack.getReason() << " no-in-record");
+ NFD_LOG_DEBUG("onOutgoingNack out=" << egress
+ << " nack=" << pitEntry->getInterest().getName()
+ << "~" << nack.getReason() << " no-in-record");
return;
}
// if multi-access or ad hoc face, drop
- if (outFace.getLinkType() != ndn::nfd::LINK_TYPE_POINT_TO_POINT) {
- NFD_LOG_DEBUG("onOutgoingNack face=" << outFace.getId() <<
- " nack=" << pitEntry->getInterest().getName() <<
- "~" << nack.getReason() << " face-is-multi-access");
+ if (egress.face.getLinkType() != ndn::nfd::LINK_TYPE_POINT_TO_POINT) {
+ NFD_LOG_DEBUG("onOutgoingNack out=" << egress
+ << " nack=" << pitEntry->getInterest().getName()
+ << "~" << nack.getReason() << " face-is-multi-access");
return;
}
- NFD_LOG_DEBUG("onOutgoingNack face=" << outFace.getId() <<
- " nack=" << pitEntry->getInterest().getName() <<
- "~" << nack.getReason() << " OK");
+ NFD_LOG_DEBUG("onOutgoingNack out=" << egress
+ << " nack=" << pitEntry->getInterest().getName()
+ << "~" << nack.getReason() << " OK");
// create Nack packet with the Interest from in-record
lp::Nack nackPkt(inRecord->getInterest());
nackPkt.setHeader(nack);
// erase in-record
- pitEntry->deleteInRecord(outFace, 0);
+ pitEntry->deleteInRecord(egress.face, egress.endpoint);
// send Nack on face
- const_cast<Face&>(outFace).sendNack(nackPkt);
+ egress.face.sendNack(nackPkt);
++m_counters.nOutNacks;
}
void
-Forwarder::onDroppedInterest(Face& outFace, const Interest& interest)
+Forwarder::onDroppedInterest(const FaceEndpoint& egress, const Interest& interest)
{
- m_strategyChoice.findEffectiveStrategy(interest.getName()).onDroppedInterest(outFace, interest);
+ m_strategyChoice.findEffectiveStrategy(interest.getName()).onDroppedInterest(egress, interest);
}
void
diff --git a/daemon/fw/forwarder.hpp b/daemon/fw/forwarder.hpp
index bcb3caf..ecc4d72 100644
--- a/daemon/fw/forwarder.hpp
+++ b/daemon/fw/forwarder.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -30,6 +30,7 @@
#include "core/scheduler.hpp"
#include "forwarder-counters.hpp"
#include "face-table.hpp"
+#include "face-endpoint.hpp"
#include "unsolicited-data-policy.hpp"
#include "table/fib.hpp"
#include "table/pit.hpp"
@@ -105,33 +106,33 @@
public: // forwarding entrypoints and tables
/** \brief start incoming Interest processing
- * \param face face on which Interest is received
+ * \param ingress face on which Interest is received and endpoint of the sender
* \param interest the incoming Interest, must be well-formed and created with make_shared
*/
void
- startProcessInterest(Face& face, const Interest& interest)
+ startProcessInterest(const FaceEndpoint& ingress, const Interest& interest)
{
- this->onIncomingInterest(face, interest);
+ this->onIncomingInterest(ingress, interest);
}
/** \brief start incoming Data processing
- * \param face face on which Data is received
+ * \param ingress face on which Data is received and endpoint of the sender
* \param data the incoming Data, must be well-formed and created with make_shared
*/
void
- startProcessData(Face& face, const Data& data)
+ startProcessData(const FaceEndpoint& ingress, const Data& data)
{
- this->onIncomingData(face, data);
+ this->onIncomingData(ingress, data);
}
/** \brief start incoming Nack processing
- * \param face face on which Nack is received
+ * \param ingress face on which Nack is received and endpoint of the sender
* \param nack the incoming Nack, must be well-formed
*/
void
- startProcessNack(Face& face, const lp::Nack& nack)
+ startProcessNack(const FaceEndpoint& ingress, const lp::Nack& nack)
{
- this->onIncomingNack(face, nack);
+ this->onIncomingNack(ingress, nack);
}
NameTree&
@@ -186,28 +187,30 @@
/** \brief incoming Interest pipeline
*/
VIRTUAL_WITH_TESTS void
- onIncomingInterest(Face& inFace, const Interest& interest);
+ onIncomingInterest(const FaceEndpoint& ingress, const Interest& interest);
/** \brief Interest loop pipeline
*/
VIRTUAL_WITH_TESTS void
- onInterestLoop(Face& inFace, const Interest& interest);
+ onInterestLoop(const FaceEndpoint& ingress, const Interest& interest);
/** \brief Content Store miss pipeline
*/
VIRTUAL_WITH_TESTS void
- onContentStoreMiss(const Face& inFace, const shared_ptr<pit::Entry>& pitEntry, const Interest& interest);
+ onContentStoreMiss(const FaceEndpoint& ingress,
+ const shared_ptr<pit::Entry>& pitEntry, const Interest& interest);
/** \brief Content Store hit pipeline
*/
VIRTUAL_WITH_TESTS void
- onContentStoreHit(const Face& inFace, const shared_ptr<pit::Entry>& pitEntry,
+ onContentStoreHit(const FaceEndpoint& ingress, const shared_ptr<pit::Entry>& pitEntry,
const Interest& interest, const Data& data);
/** \brief outgoing Interest pipeline
*/
VIRTUAL_WITH_TESTS void
- onOutgoingInterest(const shared_ptr<pit::Entry>& pitEntry, Face& outFace, const Interest& interest);
+ onOutgoingInterest(const shared_ptr<pit::Entry>& pitEntry,
+ const FaceEndpoint& egress, const Interest& interest);
/** \brief Interest finalize pipeline
*/
@@ -217,30 +220,31 @@
/** \brief incoming Data pipeline
*/
VIRTUAL_WITH_TESTS void
- onIncomingData(Face& inFace, const Data& data);
+ onIncomingData(const FaceEndpoint& ingress, const Data& data);
/** \brief Data unsolicited pipeline
*/
VIRTUAL_WITH_TESTS void
- onDataUnsolicited(Face& inFace, const Data& data);
+ onDataUnsolicited(const FaceEndpoint& ingress, const Data& data);
/** \brief outgoing Data pipeline
*/
VIRTUAL_WITH_TESTS void
- onOutgoingData(const Data& data, Face& outFace);
+ onOutgoingData(const Data& data, FaceEndpoint egress);
/** \brief incoming Nack pipeline
*/
VIRTUAL_WITH_TESTS void
- onIncomingNack(Face& inFace, const lp::Nack& nack);
+ onIncomingNack(const FaceEndpoint& ingress, const lp::Nack& nack);
/** \brief outgoing Nack pipeline
*/
VIRTUAL_WITH_TESTS void
- onOutgoingNack(const shared_ptr<pit::Entry>& pitEntry, const Face& outFace, const lp::NackHeader& nack);
+ onOutgoingNack(const shared_ptr<pit::Entry>& pitEntry,
+ const FaceEndpoint& egress, const lp::NackHeader& nack);
VIRTUAL_WITH_TESTS void
- onDroppedInterest(Face& outFace, const Interest& interest);
+ onDroppedInterest(const FaceEndpoint& egress, const Interest& interest);
PROTECTED_WITH_TESTS_ELSE_PRIVATE:
/** \brief set a new expiry timer (now + \p duration) on a PIT entry
diff --git a/daemon/fw/multicast-strategy.cpp b/daemon/fw/multicast-strategy.cpp
index 7732e09..f22514a 100644
--- a/daemon/fw/multicast-strategy.cpp
+++ b/daemon/fw/multicast-strategy.cpp
@@ -63,7 +63,7 @@
}
void
-MulticastStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest,
+MulticastStrategy::afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry)
{
const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
@@ -79,20 +79,18 @@
RetxSuppressionResult suppressResult = m_retxSuppression.decidePerUpstream(*pitEntry, outFace);
if (suppressResult == RetxSuppressionResult::SUPPRESS) {
- NFD_LOG_DEBUG(interest << " from=" << inFace.getId()
- << "to=" << outFace.getId() << " suppressed");
+ NFD_LOG_DEBUG(interest << " from=" << ingress << " to=" << outFace.getId() << " suppressed");
isSuppressed = true;
continue;
}
- if ((outFace.getId() == inFace.getId() && outFace.getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) ||
- wouldViolateScope(inFace, interest, outFace)) {
+ if ((outFace.getId() == ingress.face.getId() && outFace.getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) ||
+ wouldViolateScope(ingress.face, interest, outFace)) {
continue;
}
- this->sendInterest(pitEntry, outFace, interest);
- NFD_LOG_DEBUG(interest << " from=" << inFace.getId()
- << " pitEntry-to=" << outFace.getId());
+ this->sendInterest(pitEntry, FaceEndpoint(outFace, 0), interest);
+ NFD_LOG_DEBUG(interest << " from=" << ingress << " pitEntry-to=" << outFace.getId());
if (suppressResult == RetxSuppressionResult::FORWARD) {
m_retxSuppression.incrementIntervalForOutRecord(*pitEntry->getOutRecord(outFace, 0));
@@ -101,21 +99,21 @@
}
if (nEligibleNextHops == 0 && !isSuppressed) {
- NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " noNextHop");
+ NFD_LOG_DEBUG(interest << " from=" << ingress << " noNextHop");
lp::NackHeader nackHeader;
nackHeader.setReason(lp::NackReason::NO_ROUTE);
- this->sendNack(pitEntry, inFace, nackHeader);
+ this->sendNack(pitEntry, ingress, nackHeader);
this->rejectPendingInterest(pitEntry);
}
}
void
-MulticastStrategy::afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+MulticastStrategy::afterReceiveNack(const FaceEndpoint& ingress, const lp::Nack& nack,
const shared_ptr<pit::Entry>& pitEntry)
{
- this->processNack(inFace, nack, pitEntry);
+ this->processNack(ingress.face, nack, pitEntry);
}
} // namespace fw
diff --git a/daemon/fw/multicast-strategy.hpp b/daemon/fw/multicast-strategy.hpp
index d75e3a1..15f0d0c 100644
--- a/daemon/fw/multicast-strategy.hpp
+++ b/daemon/fw/multicast-strategy.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -34,6 +34,8 @@
namespace fw {
/** \brief a forwarding strategy that forwards Interest to all FIB nexthops
+ *
+ * \note This strategy is not EndpointId-aware.
*/
class MulticastStrategy : public Strategy
, public ProcessNackTraits<MulticastStrategy>
@@ -46,11 +48,11 @@
getStrategyName();
void
- afterReceiveInterest(const Face& inFace, const Interest& interest,
+ afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry) override;
void
- afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+ afterReceiveNack(const FaceEndpoint& ingress, const lp::Nack& nack,
const shared_ptr<pit::Entry>& pitEntry) override;
private:
diff --git a/daemon/fw/ncc-strategy.cpp b/daemon/fw/ncc-strategy.cpp
index 778ed2b..a6c1e99 100644
--- a/daemon/fw/ncc-strategy.cpp
+++ b/daemon/fw/ncc-strategy.cpp
@@ -59,7 +59,7 @@
}
void
-NccStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest,
+NccStrategy::afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry)
{
const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
@@ -83,13 +83,13 @@
shared_ptr<Face> bestFace = meInfo.getBestFace();
if (bestFace != nullptr && fibEntry.hasNextHop(*bestFace, 0) &&
- !wouldViolateScope(inFace, interest, *bestFace) &&
+ !wouldViolateScope(ingress.face, interest, *bestFace) &&
canForwardToLegacy(*pitEntry, *bestFace)) {
// TODO Should we use `randlow = 100 + nrand48(h->seed) % 4096U;` ?
deferFirst = meInfo.prediction;
deferRange = time::microseconds((deferFirst.count() + 1) / 2);
--nUpstreams;
- this->sendInterest(pitEntry, *bestFace, interest);
+ this->sendInterest(pitEntry, FaceEndpoint(*bestFace, 0), interest);
pitEntryInfo->bestFaceTimeout = scheduler::schedule(
meInfo.prediction,
bind(&NccStrategy::timeoutOnBestFace, this, weak_ptr<pit::Entry>(pitEntry)));
@@ -99,11 +99,11 @@
auto firstEligibleNexthop = std::find_if(nexthops.begin(), nexthops.end(),
[&] (const fib::NextHop& nexthop) {
Face& outFace = nexthop.getFace();
- return !wouldViolateScope(inFace, interest, outFace) &&
+ return !wouldViolateScope(ingress.face, interest, outFace) &&
canForwardToLegacy(*pitEntry, outFace);
});
if (firstEligibleNexthop != nexthops.end()) {
- this->sendInterest(pitEntry, firstEligibleNexthop->getFace(), interest);
+ this->sendInterest(pitEntry, FaceEndpoint(firstEligibleNexthop->getFace(), 0), interest);
}
else {
this->rejectPendingInterest(pitEntry);
@@ -113,7 +113,7 @@
shared_ptr<Face> previousFace = meInfo.previousFace.lock();
if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace, 0) &&
- !wouldViolateScope(inFace, interest, *previousFace) &&
+ !wouldViolateScope(ingress.face, interest, *previousFace) &&
canForwardToLegacy(*pitEntry, *previousFace)) {
--nUpstreams;
}
@@ -129,7 +129,7 @@
pitEntryInfo->maxInterval = deferFirst;
}
pitEntryInfo->propagateTimer = scheduler::schedule(deferFirst,
- bind(&NccStrategy::doPropagate, this, inFace.getId(), weak_ptr<pit::Entry>(pitEntry)));
+ bind(&NccStrategy::doPropagate, this, ingress.face.getId(), weak_ptr<pit::Entry>(pitEntry)));
}
void
@@ -161,7 +161,7 @@
if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace, 0) &&
!wouldViolateScope(*inFace, interest, *previousFace) &&
canForwardToLegacy(*pitEntry, *previousFace)) {
- this->sendInterest(pitEntry, *previousFace, interest);
+ this->sendInterest(pitEntry, FaceEndpoint(*previousFace, 0), interest);
}
bool isForwarded = false;
@@ -170,7 +170,7 @@
if (!wouldViolateScope(*inFace, interest, face) &&
canForwardToLegacy(*pitEntry, face)) {
isForwarded = true;
- this->sendInterest(pitEntry, face, interest);
+ this->sendInterest(pitEntry, FaceEndpoint(face, 0), interest);
break;
}
}
@@ -208,7 +208,7 @@
void
NccStrategy::beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data)
+ const FaceEndpoint& ingress, const Data& data)
{
if (!pitEntry->hasInRecords()) {
// PIT entry has already been satisfied (and is now waiting for straggler timer to expire)
@@ -226,7 +226,7 @@
this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(measurementsEntry);
- meInfo.updateBestFace(inFace);
+ meInfo.updateBestFace(ingress.face);
measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
}
@@ -239,7 +239,7 @@
MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
shared_ptr<Face> bestFace = meInfo.getBestFace();
- if (bestFace.get() == &inFace)
+ if (bestFace.get() == &ingress.face)
scheduler::cancel(pitEntryInfo->bestFaceTimeout);
}
}
diff --git a/daemon/fw/ncc-strategy.hpp b/daemon/fw/ncc-strategy.hpp
index 7e63333..473a87d 100644
--- a/daemon/fw/ncc-strategy.hpp
+++ b/daemon/fw/ncc-strategy.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -32,6 +32,8 @@
namespace fw {
/** \brief a forwarding strategy similar to CCNx 0.7.2
+ *
+ * \note This strategy is not EndpointId-aware.
*/
class NccStrategy : public Strategy
{
@@ -42,13 +44,13 @@
static const Name&
getStrategyName();
- virtual void
- afterReceiveInterest(const Face& inFace, const Interest& interest,
+ void
+ afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry) override;
- virtual void
+ void
beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data) override;
+ const FaceEndpoint& ingress, const Data& data) override;
PUBLIC_WITH_TESTS_ELSE_PROTECTED:
/// StrategyInfo on measurements::Entry
@@ -104,7 +106,6 @@
return 1001;
}
- virtual
~PitEntryInfo() override;
public:
diff --git a/daemon/fw/process-nack-traits.hpp b/daemon/fw/process-nack-traits.hpp
index fe70183..86e31e1 100644
--- a/daemon/fw/process-nack-traits.hpp
+++ b/daemon/fw/process-nack-traits.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -81,7 +81,7 @@
sendNackForProcessNackTraits(const shared_ptr<pit::Entry>& pitEntry, const Face& outFace,
const lp::NackHeader& header) override
{
- m_strategy->sendNack(pitEntry, outFace, header);
+ m_strategy->sendNack(pitEntry, FaceEndpoint(outFace, 0), header);
}
void
diff --git a/daemon/fw/self-learning-strategy.cpp b/daemon/fw/self-learning-strategy.cpp
index 92f9ae3..12e6176 100644
--- a/daemon/fw/self-learning-strategy.cpp
+++ b/daemon/fw/self-learning-strategy.cpp
@@ -66,73 +66,74 @@
}
void
-SelfLearningStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest,
+SelfLearningStrategy::afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry)
{
const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
const fib::NextHopList& nexthops = fibEntry.getNextHops();
bool isNonDiscovery = interest.getTag<lp::NonDiscoveryTag>() != nullptr;
- auto inRecordInfo = pitEntry->getInRecord(inFace, 0)->insertStrategyInfo<InRecordInfo>().first;
+ auto inRecordInfo = pitEntry->getInRecord(ingress.face, ingress.endpoint)->insertStrategyInfo<InRecordInfo>().first;
if (isNonDiscovery) { // "non-discovery" Interest
inRecordInfo->isNonDiscoveryInterest = true;
if (nexthops.empty()) { // return NACK if no matching FIB entry exists
- NFD_LOG_DEBUG("NACK non-discovery Interest=" << interest << " from=" << inFace.getId() << " noNextHop");
+ NFD_LOG_DEBUG("NACK non-discovery Interest=" << interest << " from=" << ingress << " noNextHop");
lp::NackHeader nackHeader;
nackHeader.setReason(lp::NackReason::NO_ROUTE);
- this->sendNack(pitEntry, inFace, nackHeader);
+ this->sendNack(pitEntry, ingress, nackHeader);
this->rejectPendingInterest(pitEntry);
}
else { // multicast it if matching FIB entry exists
- multicastInterest(interest, inFace, pitEntry, nexthops);
+ multicastInterest(interest, ingress.face, pitEntry, nexthops);
}
}
else { // "discovery" Interest
inRecordInfo->isNonDiscoveryInterest = false;
if (nexthops.empty()) { // broadcast it if no matching FIB entry exists
- broadcastInterest(interest, inFace, pitEntry);
+ broadcastInterest(interest, ingress.face, pitEntry);
}
else { // multicast it with "non-discovery" mark if matching FIB entry exists
interest.setTag(make_shared<lp::NonDiscoveryTag>(lp::EmptyValue{}));
- multicastInterest(interest, inFace, pitEntry, nexthops);
+ multicastInterest(interest, ingress.face, pitEntry, nexthops);
}
}
}
void
SelfLearningStrategy::afterReceiveData(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data)
+ const FaceEndpoint& ingress, const Data& data)
{
- OutRecordInfo* outRecordInfo = pitEntry->getOutRecord(inFace, 0)->getStrategyInfo<OutRecordInfo>();
+ OutRecordInfo* outRecordInfo = pitEntry->getOutRecord(ingress.face, ingress.endpoint)->getStrategyInfo<OutRecordInfo>();
if (outRecordInfo && outRecordInfo->isNonDiscoveryInterest) { // outgoing Interest was non-discovery
if (!needPrefixAnn(pitEntry)) { // no need to attach a PA (common cases)
- sendDataToAll(pitEntry, inFace, data);
+ sendDataToAll(pitEntry, ingress, data);
}
else { // needs a PA (to respond discovery Interest)
- asyncProcessData(pitEntry, inFace, data);
+ asyncProcessData(pitEntry, ingress.face, data);
}
}
else { // outgoing Interest was discovery
auto paTag = data.getTag<lp::PrefixAnnouncementTag>();
if (paTag != nullptr) {
- addRoute(pitEntry, inFace, data, *paTag->get().getPrefixAnn());
+ addRoute(pitEntry, ingress.face, data, *paTag->get().getPrefixAnn());
}
else { // Data contains no PrefixAnnouncement, upstreams do not support self-learning
}
- sendDataToAll(pitEntry, inFace, data);
+ sendDataToAll(pitEntry, ingress, data);
}
}
void
-SelfLearningStrategy::afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+SelfLearningStrategy::afterReceiveNack(const FaceEndpoint& ingress, const lp::Nack& nack,
const shared_ptr<pit::Entry>& pitEntry)
{
- NFD_LOG_DEBUG("Nack for " << nack.getInterest() << " from=" << inFace.getId() << ": " << nack.getReason());
+ NFD_LOG_DEBUG("Nack for " << nack.getInterest() << " from=" << ingress
+ << " reason=" << nack.getReason());
if (nack.getReason() == lp::NackReason::NO_ROUTE) { // remove FIB entries
BOOST_ASSERT(this->lookupFib(*pitEntry).hasNextHops());
NFD_LOG_DEBUG("Send NACK to all downstreams");
this->sendNacks(pitEntry, nack.getHeader());
- renewRoute(nack.getInterest().getName(), inFace.getId(), 0_ms);
+ renewRoute(nack.getInterest().getName(), ingress.face.getId(), 0_ms);
}
}
@@ -145,7 +146,7 @@
wouldViolateScope(inFace, interest, outFace) || outFace.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
continue;
}
- this->sendInterest(pitEntry, outFace, interest);
+ this->sendInterest(pitEntry, FaceEndpoint(outFace, 0), interest);
pitEntry->getOutRecord(outFace, 0)->insertStrategyInfo<OutRecordInfo>().first->isNonDiscoveryInterest = false;
NFD_LOG_DEBUG("send discovery Interest=" << interest << " from="
<< inFace.getId() << " to=" << outFace.getId());
@@ -163,7 +164,7 @@
wouldViolateScope(inFace, interest, outFace)) {
continue;
}
- this->sendInterest(pitEntry, outFace, interest);
+ this->sendInterest(pitEntry, FaceEndpoint(outFace, 0), interest);
pitEntry->getOutRecord(outFace, 0)->insertStrategyInfo<OutRecordInfo>().first->isNonDiscoveryInterest = true;
NFD_LOG_DEBUG("send non-discovery Interest=" << interest << " from="
<< inFace.getId() << " to=" << outFace.getId());
@@ -188,7 +189,7 @@
if (pitEntry && inFace) {
NFD_LOG_DEBUG("found PrefixAnnouncement=" << pa.getAnnouncedName());
data.setTag(make_shared<lp::PrefixAnnouncementTag>(lp::PrefixAnnouncementHeader(pa)));
- this->sendDataToAll(pitEntry, *inFace, data);
+ this->sendDataToAll(pitEntry, FaceEndpoint(*inFace, 0), data);
this->setExpiryTimer(pitEntry, 0_ms);
}
else {
diff --git a/daemon/fw/self-learning-strategy.hpp b/daemon/fw/self-learning-strategy.hpp
index e0c3962..7265a9e 100644
--- a/daemon/fw/self-learning-strategy.hpp
+++ b/daemon/fw/self-learning-strategy.hpp
@@ -39,6 +39,8 @@
* then unicasts subsequent Interests along the learned path
*
* \see https://redmine.named-data.net/attachments/864/Self-learning-strategy-v1.pdf
+ *
+ * \note This strategy is not EndpointId-aware
*/
class SelfLearningStrategy : public Strategy
{
@@ -79,15 +81,15 @@
public: // triggers
void
- afterReceiveInterest(const Face& inFace, const Interest& interest,
+ afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry) override;
void
afterReceiveData(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data) override;
+ const FaceEndpoint& ingress, const Data& data) override;
void
- afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+ afterReceiveNack(const FaceEndpoint& ingress, const lp::Nack& nack,
const shared_ptr<pit::Entry>& pitEntry) override;
private: // operations
diff --git a/daemon/fw/strategy.cpp b/daemon/fw/strategy.cpp
index 378e554..54574d7 100644
--- a/daemon/fw/strategy.cpp
+++ b/daemon/fw/strategy.cpp
@@ -96,8 +96,8 @@
}
unique_ptr<Strategy> instance = found->second(forwarder, instanceName);
- NFD_LOG_DEBUG("create " << instanceName << " found=" << found->first <<
- " created=" << instance->getInstanceName());
+ NFD_LOG_DEBUG("create " << instanceName << " found=" << found->first
+ << " created=" << instance->getInstanceName());
BOOST_ASSERT(!instance->getInstanceName().empty());
return instance;
}
@@ -150,100 +150,103 @@
void
Strategy::beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data)
+ const FaceEndpoint& ingress, const Data& data)
{
- NFD_LOG_DEBUG("beforeSatisfyInterest pitEntry=" << pitEntry->getName() <<
- " inFace=" << inFace.getId() << " data=" << data.getName());
+ NFD_LOG_DEBUG("beforeSatisfyInterest pitEntry=" << pitEntry->getName()
+ << " in=" << ingress << " data=" << data.getName());
}
void
Strategy::afterContentStoreHit(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data)
+ const FaceEndpoint& ingress, const Data& data)
{
- NFD_LOG_DEBUG("afterContentStoreHit pitEntry=" << pitEntry->getName() <<
- " inFace=" << inFace.getId() << " data=" << data.getName());
+ NFD_LOG_DEBUG("afterContentStoreHit pitEntry=" << pitEntry->getName()
+ << " in=" << ingress << " data=" << data.getName());
- this->sendData(pitEntry, data, inFace);
+ this->sendData(pitEntry, data, ingress);
}
void
Strategy::afterReceiveData(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data)
+ const FaceEndpoint& ingress, const Data& data)
{
- NFD_LOG_DEBUG("afterReceiveData pitEntry=" << pitEntry->getName() <<
- " inFace=" << inFace.getId() << " data=" << data.getName());
+ NFD_LOG_DEBUG("afterReceiveData pitEntry=" << pitEntry->getName()
+ << " in=" << ingress << " data=" << data.getName());
- this->beforeSatisfyInterest(pitEntry, inFace, data);
+ this->beforeSatisfyInterest(pitEntry, ingress, data);
- this->sendDataToAll(pitEntry, inFace, data);
+ this->sendDataToAll(pitEntry, ingress, data);
}
void
-Strategy::afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+Strategy::afterReceiveNack(const FaceEndpoint& ingress, const lp::Nack& nack,
const shared_ptr<pit::Entry>& pitEntry)
{
- NFD_LOG_DEBUG("afterReceiveNack inFace=" << inFace.getId() <<
- " pitEntry=" << pitEntry->getName());
+ NFD_LOG_DEBUG("afterReceiveNack in=" << ingress << " pitEntry=" << pitEntry->getName());
}
void
-Strategy::onDroppedInterest(const Face& outFace, const Interest& interest)
+Strategy::onDroppedInterest(const FaceEndpoint& egress, const Interest& interest)
{
- NFD_LOG_DEBUG("onDroppedInterest outFace=" << outFace.getId() << " name=" << interest.getName());
+ NFD_LOG_DEBUG("onDroppedInterest out=" << egress << " name=" << interest.getName());
}
void
-Strategy::sendData(const shared_ptr<pit::Entry>& pitEntry, const Data& data, const Face& outFace)
+Strategy::sendData(const shared_ptr<pit::Entry>& pitEntry, const Data& data,
+ const FaceEndpoint& egress)
{
BOOST_ASSERT(pitEntry->getInterest().matchesData(data));
- // delete the PIT entry's in-record based on outFace,
- // since Data is sent to outFace from which the Interest was received
- pitEntry->deleteInRecord(outFace, 0);
+ // delete the PIT entry's in-record based on egress,
+ // since Data is sent to face and endpoint from which the Interest was received
+ pitEntry->deleteInRecord(egress.face, egress.endpoint);
- m_forwarder.onOutgoingData(data, *const_pointer_cast<Face>(outFace.shared_from_this()));
+ m_forwarder.onOutgoingData(data, egress);
}
void
-Strategy::sendDataToAll(const shared_ptr<pit::Entry>& pitEntry, const Face& inFace, const Data& data)
+Strategy::sendDataToAll(const shared_ptr<pit::Entry>& pitEntry,
+ const FaceEndpoint& ingress, const Data& data)
{
- std::set<Face*> pendingDownstreams;
+ std::set<std::pair<Face*, EndpointId>> pendingDownstreams;
auto now = time::steady_clock::now();
// remember pending downstreams
for (const pit::InRecord& inRecord : pitEntry->getInRecords()) {
if (inRecord.getExpiry() > now) {
- if (inRecord.getFace().getId() == inFace.getId() &&
+ if (inRecord.getFace().getId() == ingress.face.getId() &&
+ inRecord.getEndpointId() == ingress.endpoint &&
inRecord.getFace().getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) {
continue;
}
- pendingDownstreams.insert(&inRecord.getFace());
+ pendingDownstreams.emplace(&inRecord.getFace(), inRecord.getEndpointId());
}
}
- for (const Face* pendingDownstream : pendingDownstreams) {
- this->sendData(pitEntry, data, *pendingDownstream);
+ for (const auto& pendingDownstream : pendingDownstreams) {
+ this->sendData(pitEntry, data, FaceEndpoint(*pendingDownstream.first, pendingDownstream.second));
}
}
void
Strategy::sendNacks(const shared_ptr<pit::Entry>& pitEntry, const lp::NackHeader& header,
- std::initializer_list<const Face*> exceptFaces)
+ std::initializer_list<FaceEndpoint> exceptFaceEndpoints)
{
// populate downstreams with all downstreams faces
- std::unordered_set<const Face*> downstreams;
+ std::set<std::pair<Face*, EndpointId>> downstreams;
std::transform(pitEntry->in_begin(), pitEntry->in_end(), std::inserter(downstreams, downstreams.end()),
- [] (const pit::InRecord& inR) { return &inR.getFace(); });
+ [] (const pit::InRecord& inR) {
+ return std::make_pair(&inR.getFace(), inR.getEndpointId());
+ });
// delete excluded faces
- // .erase in a loop is more efficient than std::set_difference because that requires sorted range
- for (const Face* exceptFace : exceptFaces) {
- downstreams.erase(exceptFace);
+ for (const auto& exceptFaceEndpoint : exceptFaceEndpoints) {
+ downstreams.erase({&exceptFaceEndpoint.face, exceptFaceEndpoint.endpoint});
}
// send Nacks
- for (const Face* downstream : downstreams) {
- this->sendNack(pitEntry, *downstream, header);
+ for (const auto& downstream : downstreams) {
+ this->sendNack(pitEntry, FaceEndpoint(*downstream.first, downstream.second), header);
}
// warning: don't loop on pitEntry->getInRecords(), because in-record is deleted when sending Nack
}
diff --git a/daemon/fw/strategy.hpp b/daemon/fw/strategy.hpp
index 0df65b9..bb50556 100644
--- a/daemon/fw/strategy.hpp
+++ b/daemon/fw/strategy.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -138,7 +138,7 @@
* may occur. However, the strategy is allowed to store weak_ptr<pit::Entry>.
*/
virtual void
- afterReceiveInterest(const Face& inFace, const Interest& interest,
+ afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry) = 0;
/** \brief trigger before PIT entry is satisfied
@@ -162,15 +162,15 @@
*/
virtual void
beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data);
+ const FaceEndpoint& ingress, const Data& data);
/** \brief trigger after a Data is matched in CS
*
- * In the base class this method sends \p data to \p inFace
+ * In the base class this method sends \p data to \p ingress
*/
virtual void
afterContentStoreHit(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data);
+ const FaceEndpoint& ingress, const Data& data);
/** \brief trigger after Data is received
*
@@ -197,7 +197,7 @@
*/
virtual void
afterReceiveData(const shared_ptr<pit::Entry>& pitEntry,
- const Face& inFace, const Data& data);
+ const FaceEndpoint& ingress, const Data& data);
/** \brief trigger after Nack is received
*
@@ -221,7 +221,7 @@
* may occur. However, the strategy is allowed to store weak_ptr<pit::Entry>.
*/
virtual void
- afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+ afterReceiveNack(const FaceEndpoint& ingress, const lp::Nack& nack,
const shared_ptr<pit::Entry>& pitEntry);
/** \brief trigger after Interest dropped for exceeding allowed retransmissions
@@ -229,39 +229,40 @@
* In the base class this method does nothing.
*/
virtual void
- onDroppedInterest(const Face& outFace, const Interest& interest);
+ onDroppedInterest(const FaceEndpoint& egress, const Interest& interest);
protected: // actions
- /** \brief send Interest to outFace
+ /** \brief send Interest to egress
* \param pitEntry PIT entry
- * \param outFace face through which to send out the Interest
+ * \param egress face through which to send out the Interest and destination endpoint
* \param interest the Interest packet
*/
VIRTUAL_WITH_TESTS void
- sendInterest(const shared_ptr<pit::Entry>& pitEntry, Face& outFace,
- const Interest& interest)
+ sendInterest(const shared_ptr<pit::Entry>& pitEntry,
+ const FaceEndpoint& egress, const Interest& interest)
{
- m_forwarder.onOutgoingInterest(pitEntry, outFace, interest);
+ m_forwarder.onOutgoingInterest(pitEntry, egress, interest);
}
- /** \brief send \p data to \p outFace
+ /** \brief send \p data to \p egress
* \param pitEntry PIT entry
* \param data the Data packet
- * \param outFace face through which to send out the Data
+ * \param egress face through which to send out the Data and destination endpoint
*/
VIRTUAL_WITH_TESTS void
- sendData(const shared_ptr<pit::Entry>& pitEntry, const Data& data, const Face& outFace);
+ sendData(const shared_ptr<pit::Entry>& pitEntry, const Data& data, const FaceEndpoint& egress);
- /** \brief send \p data to all matched and qualified faces
+ /** \brief send \p data to all matched and qualified face-endpoint pairs
*
- * A matched face is qualified if it is ad-hoc or it is NOT \p inFace
+ * A matched face is qualified if it is ad-hoc or it is NOT \p ingress
*
* \param pitEntry PIT entry
- * \param inFace face through which the Data comes from
+ * \param ingress face through which the Data comes from and endpoint of the sender
* \param data the Data packet
*/
VIRTUAL_WITH_TESTS void
- sendDataToAll(const shared_ptr<pit::Entry>& pitEntry, const Face& inFace, const Data& data);
+ sendDataToAll(const shared_ptr<pit::Entry>& pitEntry,
+ const FaceEndpoint& ingress, const Data& data);
/** \brief schedule the PIT entry for immediate deletion
*
@@ -275,30 +276,29 @@
this->setExpiryTimer(pitEntry, 0_ms);
}
- /** \brief send Nack to outFace
+ /** \brief send Nack to egress
* \param pitEntry PIT entry
- * \param outFace face through which to send out the Nack
+ * \param egress face through which to send out the Nack and destination endpoint
* \param header Nack header
*
- * The outFace must have a PIT in-record, otherwise this method has no effect.
+ * The egress must have a PIT in-record, otherwise this method has no effect.
*/
VIRTUAL_WITH_TESTS void
- sendNack(const shared_ptr<pit::Entry>& pitEntry, const Face& outFace,
- const lp::NackHeader& header)
+ sendNack(const shared_ptr<pit::Entry>& pitEntry,
+ const FaceEndpoint& egress, const lp::NackHeader& header)
{
- m_forwarder.onOutgoingNack(pitEntry, outFace, header);
+ m_forwarder.onOutgoingNack(pitEntry, egress, header);
}
- /** \brief send Nack to every face that has an in-record,
- * except those in \p exceptFaces
+ /** \brief send Nack to every face-endpoint pair that has an in-record, except those in \p exceptFaceEndpoints
* \param pitEntry PIT entry
* \param header NACK header
- * \param exceptFaces list of faces that should be excluded from sending Nacks
+ * \param exceptFaceEndpoints list of face-endpoint pairs that should be excluded from sending Nacks
* \note This is not an action, but a helper that invokes the sendNack action.
*/
void
sendNacks(const shared_ptr<pit::Entry>& pitEntry, const lp::NackHeader& header,
- std::initializer_list<const Face*> exceptFaces = std::initializer_list<const Face*>());
+ std::initializer_list<FaceEndpoint> exceptFaceEndpoints = {});
/** \brief Schedule the PIT entry to be erased after \p duration
*/