fw: Add ASF strategy parameters n-silent-timeouts & probing-interval
refs: #4193
Change-Id: I9572425a2fdcbf67b9886c2a5b6b50a10a0856e2
diff --git a/daemon/fw/asf-strategy.cpp b/daemon/fw/asf-strategy.cpp
index 5e14e37..ab629f9 100644
--- a/daemon/fw/asf-strategy.cpp
+++ b/daemon/fw/asf-strategy.cpp
@@ -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-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -42,29 +42,72 @@
: Strategy(forwarder)
, m_measurements(getMeasurements())
, m_probing(m_measurements)
+ , m_maxSilentTimeouts(0)
, m_retxSuppression(RETX_SUPPRESSION_INITIAL,
RetxSuppressionExponential::DEFAULT_MULTIPLIER,
RETX_SUPPRESSION_MAX)
{
ParsedInstanceName parsed = parseInstanceName(name);
if (!parsed.parameters.empty()) {
- BOOST_THROW_EXCEPTION(std::invalid_argument("AsfStrategy does not accept parameters"));
+ processParams(parsed.parameters);
}
+
if (parsed.version && *parsed.version != getStrategyName()[-1].toVersion()) {
BOOST_THROW_EXCEPTION(std::invalid_argument(
"AsfStrategy does not support version " + to_string(*parsed.version)));
}
this->setInstanceName(makeInstanceName(name, getStrategyName()));
+
+ NFD_LOG_DEBUG("Probing interval=" << m_probing.getProbingInterval()
+ << ", Num silent timeouts=" << m_maxSilentTimeouts);
}
const Name&
AsfStrategy::getStrategyName()
{
- static Name strategyName("/localhost/nfd/strategy/asf/%FD%02");
+ static Name strategyName("/localhost/nfd/strategy/asf/%FD%03");
return strategyName;
}
void
+AsfStrategy::processParams(const PartialName& parsed)
+{
+ for (const auto& component : parsed) {
+ std::string parsedStr(reinterpret_cast<const char*>(component.value()), component.value_size());
+ auto n = parsedStr.find("~");
+ if (n == std::string::npos) {
+ BOOST_THROW_EXCEPTION(std::invalid_argument("Format is <parameter>~<value>"));
+ }
+
+ auto f = parsedStr.substr(0, n);
+ auto s = parsedStr.substr(n + 1);
+ if (f == "probing-interval") {
+ m_probing.setProbingInterval(getParamValue(f, s));
+ }
+ else if (f == "n-silent-timeouts") {
+ m_maxSilentTimeouts = getParamValue(f, s);
+ }
+ else {
+ BOOST_THROW_EXCEPTION(std::invalid_argument("Parameter should be probing-interval or n-silent-timeouts"));
+ }
+ }
+}
+
+uint64_t
+AsfStrategy::getParamValue(const std::string& param, const std::string& value)
+{
+ try {
+ if (!value.empty() && value[0] == '-')
+ BOOST_THROW_EXCEPTION(boost::bad_lexical_cast());
+
+ return boost::lexical_cast<uint64_t>(value);
+ }
+ catch (const boost::bad_lexical_cast&) {
+ BOOST_THROW_EXCEPTION(std::invalid_argument("Value of " + param + " must be a non-negative integer"));
+ }
+}
+
+void
AsfStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest,
const shared_ptr<pit::Entry>& pitEntry)
{
@@ -132,7 +175,7 @@
faceInfo->recordRtt(pitEntry, inFace);
// Extend lifetime for measurements associated with Face
- namespaceInfo->extendFaceInfoLifetime(*faceInfo, inFace);
+ namespaceInfo->extendFaceInfoLifetime(*faceInfo, inFace.getId());
if (faceInfo->isTimeoutScheduled()) {
faceInfo->cancelTimeoutEvent(data.getName());
@@ -169,11 +212,11 @@
this->sendInterest(pitEntry, outFace, interest);
}
- FaceInfo& faceInfo = m_measurements.getOrCreateFaceInfo(fibEntry, interest, outFace);
+ FaceInfo& faceInfo = m_measurements.getOrCreateFaceInfo(fibEntry, interest, outFace.getId());
// Refresh measurements since Face is being used for forwarding
NamespaceInfo& namespaceInfo = m_measurements.getOrCreateNamespaceInfo(fibEntry, interest);
- namespaceInfo.extendFaceInfoLifetime(faceInfo, outFace);
+ namespaceInfo.extendFaceInfoLifetime(faceInfo, outFace.getId());
if (!faceInfo.isTimeoutScheduled()) {
// Estimate and schedule timeout
@@ -251,7 +294,7 @@
continue;
}
- FaceInfo* info = m_measurements.getFaceInfo(fibEntry, interest, hopFace);
+ FaceInfo* info = m_measurements.getFaceInfo(fibEntry, interest, hopFace.getId());
if (info == nullptr) {
FaceStats stats = {&hopFace,
@@ -278,10 +321,8 @@
}
void
-AsfStrategy::onTimeout(const Name& interestName, face::FaceId faceId)
+AsfStrategy::onTimeout(const Name& interestName, const face::FaceId faceId)
{
- NFD_LOG_TRACE("FaceId: " << faceId << " for " << interestName << " has timed-out");
-
NamespaceInfo* namespaceInfo = m_measurements.getNamespaceInfo(interestName);
if (namespaceInfo == nullptr) {
@@ -296,7 +337,23 @@
}
FaceInfo& faceInfo = it->second;
- faceInfo.recordTimeout(interestName);
+
+ faceInfo.setNSilentTimeouts(faceInfo.getNSilentTimeouts() + 1);
+
+ if (faceInfo.getNSilentTimeouts() <= m_maxSilentTimeouts) {
+ NFD_LOG_TRACE("FaceId " << faceId << " for " << interestName << " has timed-out "
+ << faceInfo.getNSilentTimeouts() << " time(s), ignoring");
+ // Extend lifetime for measurements associated with Face
+ namespaceInfo->extendFaceInfoLifetime(faceInfo, faceId);
+
+ if (faceInfo.isTimeoutScheduled()) {
+ faceInfo.cancelTimeoutEvent(interestName);
+ }
+ }
+ else {
+ NFD_LOG_TRACE("FaceId " << faceId << " for " << interestName << " has timed-out");
+ faceInfo.recordTimeout(interestName);
+ }
}
void