fw: add strategy parameters to configure exponential retx suppression

Supported by ASF, BestRoute, and Multicast strategies

Refs: #4924
Change-Id: I215d9212d90b93fa622cc65278703dc5198d0c9d
diff --git a/daemon/fw/strategy.cpp b/daemon/fw/strategy.cpp
index 7212c52..fa948ee 100644
--- a/daemon/fw/strategy.cpp
+++ b/daemon/fw/strategy.cpp
@@ -140,6 +140,29 @@
   return hasVersion ? input : Name(input).append(strategyName.at(-1));
 }
 
+StrategyParameters
+Strategy::parseParameters(const PartialName& params)
+{
+  StrategyParameters parsed;
+
+  for (const auto& component : params) {
+    auto sep = std::find(component.value_begin(), component.value_end(), '~');
+    if (sep == component.value_end()) {
+      NDN_THROW(std::invalid_argument("Strategy parameters format is (<parameter>~<value>)*"));
+    }
+
+    std::string p(component.value_begin(), sep);
+    std::advance(sep, 1);
+    std::string v(sep, component.value_end());
+    if (p.empty() || v.empty()) {
+      NDN_THROW(std::invalid_argument("Strategy parameter name and value cannot be empty"));
+    }
+    parsed[std::move(p)] = std::move(v);
+  }
+
+  return parsed;
+}
+
 Strategy::Strategy(Forwarder& forwarder)
   : afterAddFace(forwarder.m_faceTable.afterAdd)
   , beforeRemoveFace(forwarder.m_faceTable.beforeRemove)
@@ -299,7 +322,7 @@
   for (const auto& delegation : fh) {
     fibEntry = &fib.findLongestPrefixMatch(delegation);
     if (fibEntry->hasNextHops()) {
-      if (fibEntry->getPrefix().size() == 0) {
+      if (fibEntry->getPrefix().empty()) {
         // in consumer region, return the default route
         NFD_LOG_TRACE("lookupFib inConsumerRegion found=" << fibEntry->getPrefix());
       }
@@ -309,9 +332,9 @@
       }
       return *fibEntry;
     }
-    BOOST_ASSERT(fibEntry->getPrefix().size() == 0); // only ndn:/ FIB entry can have zero nexthop
+    BOOST_ASSERT(fibEntry->getPrefix().empty()); // only ndn:/ FIB entry can have zero nexthop
   }
-  BOOST_ASSERT(fibEntry != nullptr && fibEntry->getPrefix().size() == 0);
+  BOOST_ASSERT(fibEntry != nullptr && fibEntry->getPrefix().empty());
   return *fibEntry; // only occurs if no delegation finds a FIB nexthop
 }