fw: AccessStrategy: fix PIT in-record lookup with EndpointId

Refs: #4849
Change-Id: Ia3e2d033be507cb782b8d6c234a0e53c18590528
diff --git a/daemon/fw/access-strategy.cpp b/daemon/fw/access-strategy.cpp
index eec5a63..3b28246 100644
--- a/daemon/fw/access-strategy.cpp
+++ b/daemon/fw/access-strategy.cpp
@@ -59,68 +59,62 @@
 AccessStrategy::afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
                                      const shared_ptr<pit::Entry>& pitEntry)
 {
-  RetxSuppressionResult suppressResult = m_retxSuppression.decidePerPitEntry(*pitEntry);
+  auto suppressResult = m_retxSuppression.decidePerPitEntry(*pitEntry);
   switch (suppressResult) {
   case RetxSuppressionResult::NEW:
-    this->afterReceiveNewInterest(ingress.face, interest, pitEntry);
-    break;
+    return afterReceiveNewInterest(ingress, interest, pitEntry);
   case RetxSuppressionResult::FORWARD:
-    this->afterReceiveRetxInterest(ingress.face, interest, pitEntry);
-    break;
+    return afterReceiveRetxInterest(ingress, interest, pitEntry);
   case RetxSuppressionResult::SUPPRESS:
     NFD_LOG_DEBUG(interest << " interestFrom " << ingress << " retx-suppress");
-    break;
-  default:
-    BOOST_ASSERT(false);
-    break;
+    return;
   }
 }
 
 void
-AccessStrategy::afterReceiveNewInterest(const Face& inFace, const Interest& interest,
+AccessStrategy::afterReceiveNewInterest(const FaceEndpoint& ingress, const Interest& interest,
                                         const shared_ptr<pit::Entry>& pitEntry)
 {
-  const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
+  const auto& fibEntry = this->lookupFib(*pitEntry);
   Name miName;
   MtInfo* mi = nullptr;
   std::tie(miName, mi) = this->findPrefixMeasurements(*pitEntry);
 
   // has measurements for Interest Name?
   if (mi != nullptr) {
-    NFD_LOG_DEBUG(interest << " interestFrom " << inFace.getId() << " new-interest mi=" << miName);
+    NFD_LOG_DEBUG(interest << " interestFrom " << ingress << " new-interest mi=" << miName);
 
     // send to last working nexthop
-    bool isSentToLastNexthop = this->sendToLastNexthop(inFace, interest, pitEntry, *mi, fibEntry);
-
+    bool isSentToLastNexthop = this->sendToLastNexthop(ingress, interest, pitEntry, *mi, fibEntry);
     if (isSentToLastNexthop) {
       return;
     }
   }
   else {
-    NFD_LOG_DEBUG(interest << " interestFrom " << inFace.getId() << " new-interest no-mi");
+    NFD_LOG_DEBUG(interest << " interestFrom " << ingress << " new-interest no-mi");
   }
 
   // no measurements, or last working nexthop unavailable
 
   // multicast to all nexthops except incoming face
-  int nMulticastSent = this->multicast(inFace, interest, pitEntry, fibEntry);
+  size_t nMulticastSent = this->multicast(ingress.face, interest, pitEntry, fibEntry);
 
-  if (nMulticastSent < 1) {
+  if (nMulticastSent == 0) {
     this->rejectPendingInterest(pitEntry);
   }
 }
 
 void
-AccessStrategy::afterReceiveRetxInterest(const Face& inFace, const Interest& interest,
+AccessStrategy::afterReceiveRetxInterest(const FaceEndpoint& ingress, const Interest& interest,
                                          const shared_ptr<pit::Entry>& pitEntry)
 {
-  const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
-  NFD_LOG_DEBUG(interest << " interestFrom " << inFace.getId() << " retx-forward");
-  this->multicast(inFace, interest, pitEntry, fibEntry);
+  const auto& fibEntry = this->lookupFib(*pitEntry);
+  NFD_LOG_DEBUG(interest << " interestFrom " << ingress << " retx-forward");
+  this->multicast(ingress.face, interest, pitEntry, fibEntry);
 }
 
 bool
-AccessStrategy::sendToLastNexthop(const Face& inFace, const Interest& interest,
+AccessStrategy::sendToLastNexthop(const FaceEndpoint& ingress, const Interest& interest,
                                   const shared_ptr<pit::Entry>& pitEntry, MtInfo& mi,
                                   const fib::Entry& fibEntry)
 {
@@ -129,7 +123,7 @@
     return false;
   }
 
-  if (mi.lastNexthop == inFace.getId()) {
+  if (mi.lastNexthop == ingress.face.getId()) {
     NFD_LOG_DEBUG(pitEntry->getInterest() << " last-nexthop-is-downstream");
     return false;
   }
@@ -140,12 +134,12 @@
     return false;
   }
 
-  if (wouldViolateScope(inFace, interest, *outFace)) {
+  if (wouldViolateScope(ingress.face, interest, *outFace)) {
     NFD_LOG_DEBUG(pitEntry->getInterest() << " last-nexthop-violates-scope");
     return false;
   }
 
-  RttEstimator::Duration rto = mi.rtt.computeRto();
+  auto rto = mi.rtt.computeRto();
   NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << mi.lastNexthop
                 << " last-nexthop rto=" << time::duration_cast<time::microseconds>(rto).count());
 
@@ -153,19 +147,21 @@
 
   // schedule RTO timeout
   PitInfo* pi = pitEntry->insertStrategyInfo<PitInfo>().first;
-  pi->rtoTimer = getScheduler().schedule(rto,
-      bind(&AccessStrategy::afterRtoTimeout, this, weak_ptr<pit::Entry>(pitEntry),
-           inFace.getId(), mi.lastNexthop));
+  pi->rtoTimer = getScheduler().schedule(rto, [=] {
+    afterRtoTimeout(weak_ptr<pit::Entry>(pitEntry),
+                    ingress.face.getId(), ingress.endpoint, mi.lastNexthop);
+  });
 
   return true;
 }
 
 void
-AccessStrategy::afterRtoTimeout(weak_ptr<pit::Entry> pitWeak, FaceId inFaceId, FaceId firstOutFaceId)
+AccessStrategy::afterRtoTimeout(const weak_ptr<pit::Entry>& pitWeak,
+                                FaceId inFaceId, EndpointId inEndpointId, FaceId firstOutFaceId)
 {
   shared_ptr<pit::Entry> pitEntry = pitWeak.lock();
+  // if PIT entry is gone, RTO timer should have been cancelled
   BOOST_ASSERT(pitEntry != nullptr);
-  // if pitEntry is gone, RTO timer should have been cancelled
 
   Face* inFace = this->getFace(inFaceId);
   if (inFace == nullptr) {
@@ -174,11 +170,11 @@
     return;
   }
 
-  auto inRecord = pitEntry->getInRecord(*inFace, 0);
-  BOOST_ASSERT(inRecord != pitEntry->in_end());
+  auto inRecord = pitEntry->getInRecord(*inFace, inEndpointId);
   // in-record is erased only if Interest is satisfied, and RTO timer should have been cancelled
-  // note: if this strategy is extended to send Nacks, that would also erase in-record,
-  //       and RTO timer should be cancelled in that case as well
+  // note: if this strategy is extended to send Nacks, that would also erase the in-record,
+  //       and the RTO timer should be cancelled in that case as well
+  BOOST_ASSERT(inRecord != pitEntry->in_end());
 
   const Interest& interest = inRecord->getInterest();
   const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
@@ -188,13 +184,13 @@
   this->multicast(*inFace, interest, pitEntry, fibEntry, firstOutFaceId);
 }
 
-int
+size_t
 AccessStrategy::multicast(const Face& inFace, const Interest& interest,
                           const shared_ptr<pit::Entry>& pitEntry, const fib::Entry& fibEntry,
                           FaceId exceptFace)
 {
-  int nSent = 0;
-  for (const fib::NextHop& nexthop : fibEntry.getNextHops()) {
+  size_t nSent = 0;
+  for (const auto& nexthop : fibEntry.getNextHops()) {
     Face& outFace = nexthop.getFace();
     if (&outFace == &inFace || outFace.getId() == exceptFace ||
         wouldViolateScope(inFace, interest, outFace)) {
@@ -251,12 +247,6 @@
   }
 }
 
-AccessStrategy::MtInfo::MtInfo()
-  : lastNexthop(face::INVALID_FACEID)
-  , rtt(1, 1_ms, 0.1)
-{
-}
-
 std::tuple<Name, AccessStrategy::MtInfo*>
 AccessStrategy::findPrefixMeasurements(const pit::Entry& pitEntry)
 {
@@ -290,11 +280,6 @@
   return me->insertStrategyInfo<MtInfo>().first;
 }
 
-AccessStrategy::FaceInfo::FaceInfo()
-  : rtt(1, 1_ms, 0.1)
-{
-}
-
 void
 AccessStrategy::removeFaceInfo(const Face& face)
 {
diff --git a/daemon/fw/access-strategy.hpp b/daemon/fw/access-strategy.hpp
index 2dc1530..857592b 100644
--- a/daemon/fw/access-strategy.hpp
+++ b/daemon/fw/access-strategy.hpp
@@ -91,11 +91,9 @@
       return 1011;
     }
 
-    MtInfo();
-
   public:
-    FaceId lastNexthop;
-    RttEstimator rtt;
+    FaceId lastNexthop = face::INVALID_FACEID;
+    RttEstimator rtt{1, 1_ms, 0.1};
   };
 
   /** \brief find per-prefix measurements for Interest
@@ -111,13 +109,9 @@
 
   /** \brief global per-face StrategyInfo
    */
-  class FaceInfo
+  struct FaceInfo
   {
-  public:
-    FaceInfo();
-
-  public:
-    RttEstimator rtt;
+    RttEstimator rtt{1, 1_ms, 0.1};
   };
 
   typedef std::unordered_map<FaceId, FaceInfo> FaceInfoTable;
@@ -127,29 +121,30 @@
 
 private: // forwarding procedures
   void
-  afterReceiveNewInterest(const Face& inFace, const Interest& interest,
+  afterReceiveNewInterest(const FaceEndpoint& ingress, const Interest& interest,
                           const shared_ptr<pit::Entry>& pitEntry);
 
   void
-  afterReceiveRetxInterest(const Face& inFace, const Interest& interest,
+  afterReceiveRetxInterest(const FaceEndpoint& ingress, const Interest& interest,
                            const shared_ptr<pit::Entry>& pitEntry);
 
   /** \brief send to last working nexthop
    *  \return whether an Interest is sent
    */
   bool
-  sendToLastNexthop(const Face& inFace, const Interest& interest,
+  sendToLastNexthop(const FaceEndpoint& ingress, const Interest& interest,
                     const shared_ptr<pit::Entry>& pitEntry, MtInfo& mi,
                     const fib::Entry& fibEntry);
 
   void
-  afterRtoTimeout(weak_ptr<pit::Entry> pitWeak, FaceId inFaceId, FaceId firstOutFaceId);
+  afterRtoTimeout(const weak_ptr<pit::Entry>& pitWeak,
+                  FaceId inFaceId, EndpointId inEndpointId, FaceId firstOutFaceId);
 
   /** \brief multicast to all nexthops
    *  \param exceptFace don't forward to this face; also, inFace is always excluded
    *  \return how many Interests are sent
    */
-  int
+  size_t
   multicast(const Face& inFace, const Interest& interest,
             const shared_ptr<pit::Entry>& pitEntry, const fib::Entry& fibEntry,
             FaceId exceptFace = face::INVALID_FACEID);