fw: Nack in pipelines and best-route strategy
* in PIT out-record, add last incoming Nack field
* create incoming Nack pipeline
* create outgoing Nack pipeline
* modify Interest loop pipeline to send Nack upon duplicate Nonce
* in strategy API, add after receive Nack trigger and send Nack action
* in best-route strategy, send Nack-NoRoute before rejecting pending Interest
* in best-route strategy, process incoming Nack
Other changes include:
* Pit::find
* StrategyTester saved arguments structs
* TopologyTester transmit at Transport level
refs #3156
Change-Id: I7868561c0838231083d471261200aeb280cc6e9d
diff --git a/daemon/fw/strategy.hpp b/daemon/fw/strategy.hpp
index 8eca1db..ebbb361 100644
--- a/daemon/fw/strategy.hpp
+++ b/daemon/fw/strategy.hpp
@@ -70,7 +70,7 @@
* invoke this->rejectPendingInterest so that PIT entry will be deleted shortly
*
* \note The strategy is permitted to store a weak reference to fibEntry.
- * Do not store a shared reference, because PIT entry may be deleted at any moment.
+ * Do not store a shared reference, because FIB entry may be deleted at any moment.
* fibEntry is passed by value to allow obtaining a weak reference from it.
* \note The strategy is permitted to store a shared reference to pitEntry.
* pitEntry is passed by value to reflect this fact.
@@ -110,11 +110,33 @@
virtual void
beforeExpirePendingInterest(shared_ptr<pit::Entry> pitEntry);
+ /** \brief trigger after Nack is received
+ *
+ * This trigger is invoked when an incoming Nack is received in response to
+ * an forwarded Interest.
+ * The Nack has been confirmed to be a response to the last Interest forwarded
+ * to that upstream, i.e. the PIT out-record exists and has a matching Nonce.
+ * The NackHeader has been recorded in the PIT out-record.
+ *
+ * In this base class this method does nothing.
+ *
+ * \note The strategy is permitted to store a weak reference to fibEntry.
+ * Do not store a shared reference, because PIT entry may be deleted at any moment.
+ * fibEntry is passed by value to allow obtaining a weak reference from it.
+ * \note The strategy is permitted to store a shared reference to pitEntry.
+ * pitEntry is passed by value to reflect this fact.
+ */
+ virtual void
+ afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+ shared_ptr<fib::Entry> fibEntry, shared_ptr<pit::Entry> pitEntry);
+
protected: // actions
- /// send Interest to outFace
+ /** \brief send Interest to outFace
+ * \param wantNewNonce if true, a new Nonce will be generated,
+ * rather than reusing a Nonce from one of the PIT in-records
+ */
VIRTUAL_WITH_TESTS void
- sendInterest(shared_ptr<pit::Entry> pitEntry,
- shared_ptr<Face> outFace,
+ sendInterest(shared_ptr<pit::Entry> pitEntry, shared_ptr<Face> outFace,
bool wantNewNonce = false);
/** \brief decide that a pending Interest cannot be forwarded
@@ -125,6 +147,22 @@
VIRTUAL_WITH_TESTS void
rejectPendingInterest(shared_ptr<pit::Entry> pitEntry);
+ /** \brief send Nack to outFace
+ *
+ * The outFace must have a PIT in-record, otherwise this method has no effect.
+ */
+ VIRTUAL_WITH_TESTS void
+ sendNack(shared_ptr<pit::Entry> pitEntry, const Face& outFace,
+ const lp::NackHeader& header);
+
+ /** \brief send Nack to every face that has an in-record,
+ * except those in \p exceptFaces
+ * \note This is not an action, but a helper that invokes the sendNack action.
+ */
+ void
+ sendNacks(shared_ptr<pit::Entry> pitEntry, const lp::NackHeader& header,
+ std::initializer_list<const Face*> exceptFaces = std::initializer_list<const Face*>());
+
protected: // accessors
MeasurementsAccessor&
getMeasurements();
@@ -171,6 +209,13 @@
m_forwarder.onInterestReject(pitEntry);
}
+inline void
+Strategy::sendNack(shared_ptr<pit::Entry> pitEntry, const Face& outFace,
+ const lp::NackHeader& header)
+{
+ m_forwarder.onOutgoingNack(pitEntry, outFace, header);
+}
+
inline MeasurementsAccessor&
Strategy::getMeasurements()
{