diff --git a/daemon/fw/asf-measurements.cpp b/daemon/fw/asf-measurements.cpp
new file mode 100644
index 0000000..1a2eca2
--- /dev/null
+++ b/daemon/fw/asf-measurements.cpp
@@ -0,0 +1,271 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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/>.
+ */
+
+#include "asf-measurements.hpp"
+
+namespace nfd {
+namespace fw {
+namespace asf {
+
+NFD_LOG_INIT("AsfMeasurements");
+
+const RttStats::Rtt RttStats::RTT_TIMEOUT(-1.0);
+const RttStats::Rtt RttStats::RTT_NO_MEASUREMENT(0.0);
+const double RttStats::ALPHA = 0.125;
+
+RttStats::RttStats()
+  : m_srtt(RTT_NO_MEASUREMENT)
+  , m_rtt(RTT_NO_MEASUREMENT)
+{
+}
+
+void
+RttStats::addRttMeasurement(RttEstimator::Duration& durationRtt)
+{
+  m_rtt = static_cast<RttStats::Rtt>(durationRtt.count());
+
+  m_rttEstimator.addMeasurement(durationRtt);
+
+  m_srtt = computeSrtt(m_srtt, m_rtt);
+}
+
+RttStats::Rtt
+RttStats::computeSrtt(Rtt previousSrtt, Rtt currentRtt)
+{
+  if (previousSrtt == RTT_NO_MEASUREMENT) {
+    return currentRtt;
+  }
+
+  return Rtt(ALPHA * currentRtt + (1 - ALPHA) * previousSrtt);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+FaceInfo::FaceInfo()
+  : m_isTimeoutScheduled(false)
+{
+}
+
+FaceInfo::~FaceInfo()
+{
+  cancelTimeoutEvent();
+  scheduler::cancel(m_measurementExpirationId);
+}
+
+void
+FaceInfo::setTimeoutEvent(const scheduler::EventId& id, const ndn::Name& interestName)
+{
+  if (!m_isTimeoutScheduled) {
+    m_timeoutEventId = id;
+    m_isTimeoutScheduled = true;
+    m_lastInterestName = interestName;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(FaceInfo::Error("Tried to schedule a timeout for a face that already has a timeout scheduled."));
+  }
+}
+
+void
+FaceInfo::cancelTimeoutEvent()
+{
+  scheduler::cancel(m_timeoutEventId);
+  m_isTimeoutScheduled = false;
+}
+
+void
+FaceInfo::cancelTimeoutEvent(const ndn::Name& prefix)
+{
+  if (isTimeoutScheduled() && doesNameMatchLastInterest(prefix)) {
+    cancelTimeoutEvent();
+  }
+}
+
+bool
+FaceInfo::doesNameMatchLastInterest(const ndn::Name& name)
+{
+  return m_lastInterestName.isPrefixOf(name);
+}
+
+void
+FaceInfo::recordRtt(const shared_ptr<pit::Entry> pitEntry, const Face& inFace)
+{
+  // Calculate RTT
+  pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(inFace);
+  time::steady_clock::Duration steadyRtt = time::steady_clock::now() - outRecord->getLastRenewed();
+  RttEstimator::Duration durationRtt = time::duration_cast<RttEstimator::Duration>(steadyRtt);
+
+  m_rttStats.addRttMeasurement(durationRtt);
+
+  NFD_LOG_TRACE("Recording RTT for FaceId: " << inFace.getId()
+                                             << " RTT: "    << m_rttStats.getRtt()
+                                             << " SRTT: "   << m_rttStats.getSrtt());
+}
+
+void
+FaceInfo::recordTimeout(const ndn::Name& interestName)
+{
+  m_rttStats.recordTimeout();
+  cancelTimeoutEvent(interestName);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+NamespaceInfo::NamespaceInfo()
+  : m_isProbingDue(false)
+  , m_hasFirstProbeBeenScheduled(false)
+{
+}
+
+FaceInfo*
+NamespaceInfo::getFaceInfo(const fib::Entry& fibEntry, const Face& face)
+{
+  FaceInfoTable::iterator it = m_fit.find(face.getId());
+
+  if (it != m_fit.end()) {
+    return &it->second;
+  }
+  else {
+    return nullptr;
+  }
+}
+
+FaceInfo&
+NamespaceInfo::getOrCreateFaceInfo(const fib::Entry& fibEntry, const Face& face)
+{
+  FaceInfoTable::iterator it = m_fit.find(face.getId());
+
+  FaceInfo* info = nullptr;
+
+  if (it == m_fit.end()) {
+    const auto& pair = m_fit.insert(std::make_pair(face.getId(), FaceInfo()));
+    info = &pair.first->second;
+
+    extendFaceInfoLifetime(*info, face);
+  }
+  else {
+    info = &it->second;
+  }
+
+  return *info;
+}
+
+void
+NamespaceInfo::expireFaceInfo(nfd::face::FaceId faceId)
+{
+  m_fit.erase(faceId);
+}
+
+void
+NamespaceInfo::extendFaceInfoLifetime(FaceInfo& info, const Face& face)
+{
+  // Cancel previous expiration
+  scheduler::cancel(info.getMeasurementExpirationEventId());
+
+  // Refresh measurement
+  scheduler::EventId id = scheduler::schedule(AsfMeasurements::MEASUREMENTS_LIFETIME,
+    bind(&NamespaceInfo::expireFaceInfo, this, face.getId()));
+
+  info.setMeasurementExpirationEventId(id);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+constexpr time::microseconds AsfMeasurements::MEASUREMENTS_LIFETIME;
+
+AsfMeasurements::AsfMeasurements(MeasurementsAccessor& measurements)
+  : m_measurements(measurements)
+{
+}
+
+FaceInfo*
+AsfMeasurements::getFaceInfo(const fib::Entry& fibEntry, const ndn::Interest& interest, const Face& face)
+{
+  NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
+  return info.getFaceInfo(fibEntry, face);
+}
+
+FaceInfo&
+AsfMeasurements::getOrCreateFaceInfo(const fib::Entry& fibEntry, const ndn::Interest& interest, const Face& face)
+{
+  NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
+  return info.getOrCreateFaceInfo(fibEntry, face);
+}
+
+shared_ptr<NamespaceInfo>
+AsfMeasurements::getNamespaceInfo(const ndn::Name& prefix)
+{
+  shared_ptr<measurements::Entry> me = m_measurements.findLongestPrefixMatch(prefix);
+
+  if (me == nullptr) {
+    return nullptr;
+  }
+
+  // Set or update entry lifetime
+  extendLifetime(me);
+
+  shared_ptr<NamespaceInfo> info = me->getOrCreateStrategyInfo<NamespaceInfo>();
+  BOOST_ASSERT(info != nullptr);
+
+  return info;
+}
+
+NamespaceInfo&
+AsfMeasurements::getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const ndn::Interest& interest)
+{
+  shared_ptr<measurements::Entry> me = m_measurements.get(fibEntry);
+
+  // If the FIB entry is not under the strategy's namespace, find a part of the prefix
+  // that falls under the strategy's namespace
+  for (size_t prefixLen = fibEntry.getPrefix().size() + 1;
+       me == nullptr && prefixLen <= interest.getName().size(); ++prefixLen) {
+    me = m_measurements.get(interest.getName().getPrefix(prefixLen));
+  }
+
+  // Either the FIB entry or the Interest's name must be under this strategy's namespace
+  BOOST_ASSERT(me != nullptr);
+
+  // Set or update entry lifetime
+  extendLifetime(me);
+
+  shared_ptr<NamespaceInfo> info = me->getOrCreateStrategyInfo<NamespaceInfo>();
+  BOOST_ASSERT(info != nullptr);
+
+  return *info;
+}
+
+void
+AsfMeasurements::extendLifetime(shared_ptr<measurements::Entry> me)
+{
+  if (me != nullptr) {
+    m_measurements.extendLifetime(*me, MEASUREMENTS_LIFETIME);
+  }
+}
+
+} // namespace asf
+} // namespace fw
+} // namespace nfd
diff --git a/daemon/fw/asf-measurements.hpp b/daemon/fw/asf-measurements.hpp
new file mode 100644
index 0000000..8339d97
--- /dev/null
+++ b/daemon/fw/asf-measurements.hpp
@@ -0,0 +1,311 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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_ASF_MEASUREMENTS_HPP
+#define NFD_DAEMON_FW_ASF_MEASUREMENTS_HPP
+
+#include "fw/rtt-estimator.hpp"
+#include "fw/strategy-info.hpp"
+#include "table/measurements-accessor.hpp"
+
+namespace nfd {
+namespace fw {
+namespace asf {
+
+class RttStats
+{
+public:
+  typedef time::duration<double, boost::micro> Rtt;
+
+  RttStats();
+
+  void
+  addRttMeasurement(RttEstimator::Duration& durationRtt);
+
+  void
+  recordTimeout()
+  {
+    m_rtt = RTT_TIMEOUT;
+  }
+
+  Rtt
+  getRtt() const
+  {
+    return m_rtt;
+  }
+
+  Rtt
+  getSrtt() const
+  {
+    return m_srtt;
+  }
+
+  RttEstimator::Duration
+  computeRto() const
+  {
+    return m_rttEstimator.computeRto();
+  }
+
+private:
+  static Rtt
+  computeSrtt(Rtt previousSrtt, Rtt currentRtt);
+
+public:
+  static const Rtt RTT_TIMEOUT;
+  static const Rtt RTT_NO_MEASUREMENT;
+
+private:
+  Rtt m_srtt;
+  Rtt m_rtt;
+  RttEstimator m_rttEstimator;
+
+  static const double ALPHA;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+/** \brief Strategy information for each face in a namespace
+*/
+class FaceInfo
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  FaceInfo();
+
+  ~FaceInfo();
+
+  void
+  setTimeoutEvent(const scheduler::EventId& id, const ndn::Name& interestName);
+
+  void
+  setMeasurementExpirationEventId(const scheduler::EventId& id)
+  {
+    m_measurementExpirationId = id;
+  }
+
+  const scheduler::EventId&
+  getMeasurementExpirationEventId()
+  {
+    return m_measurementExpirationId;
+  }
+
+  void
+  cancelTimeoutEvent(const ndn::Name& prefix);
+
+  bool
+  isTimeoutScheduled() const
+  {
+    return m_isTimeoutScheduled;
+  }
+
+  void
+  recordRtt(const shared_ptr<pit::Entry> pitEntry, const Face& inFace);
+
+  void
+  recordTimeout(const ndn::Name& interestName);
+
+  bool
+  isTimeout() const
+  {
+    return getRtt() == RttStats::RTT_TIMEOUT;
+  }
+
+  RttEstimator::Duration
+  computeRto() const
+  {
+    return m_rttStats.computeRto();
+  }
+
+  RttStats::Rtt
+  getRtt() const
+  {
+    return m_rttStats.getRtt();
+  }
+
+  RttStats::Rtt
+  getSrtt() const
+  {
+    return m_rttStats.getSrtt();
+  }
+
+  bool
+  hasSrttMeasurement() const
+  {
+    return getSrtt() != RttStats::RTT_NO_MEASUREMENT;
+  }
+
+private:
+  void
+  cancelTimeoutEvent();
+
+  bool
+  doesNameMatchLastInterest(const ndn::Name& name);
+
+private:
+  RttStats m_rttStats;
+  ndn::Name m_lastInterestName;
+
+  // Timeout associated with measurement
+  scheduler::EventId m_measurementExpirationId;
+
+  // RTO associated with Interest
+  scheduler::EventId m_timeoutEventId;
+  bool m_isTimeoutScheduled;
+};
+
+typedef std::unordered_map<face::FaceId, FaceInfo> FaceInfoTable;
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+/** \brief stores stategy information about each face in this namespace
+ */
+class NamespaceInfo : public StrategyInfo
+{
+public:
+  NamespaceInfo();
+
+  static constexpr int
+  getTypeId()
+  {
+    return 1030;
+  }
+
+  FaceInfo&
+  getOrCreateFaceInfo(const fib::Entry& fibEntry, const Face& face);
+
+  FaceInfo*
+  getFaceInfo(const fib::Entry& fibEntry, const Face& face);
+
+  void
+  expireFaceInfo(nfd::face::FaceId faceId);
+
+  void
+  extendFaceInfoLifetime(FaceInfo& info, const Face& face);
+
+  FaceInfo&
+  get(nfd::face::FaceId faceId)
+  {
+    return m_fit.at(faceId);
+  }
+
+  FaceInfoTable::iterator
+  find(nfd::face::FaceId faceId)
+  {
+    return m_fit.find(faceId);
+  }
+
+  FaceInfoTable::iterator
+  end()
+  {
+    return m_fit.end();
+  }
+
+  const FaceInfoTable::iterator
+  insert(nfd::face::FaceId faceId)
+  {
+    const auto& pair = m_fit.insert(std::make_pair(faceId, FaceInfo()));
+    return pair.first;
+  }
+
+  bool
+  isProbingDue() const
+  {
+    return m_isProbingDue;
+  }
+
+  void
+  setIsProbingDue(bool isProbingDue)
+  {
+    m_isProbingDue = isProbingDue;
+  }
+
+  bool
+  isFirstProbeScheduled() const
+  {
+    return m_hasFirstProbeBeenScheduled;
+  }
+
+  void
+  setHasFirstProbeBeenScheduled(bool hasBeenScheduled)
+  {
+    m_hasFirstProbeBeenScheduled = hasBeenScheduled;
+  }
+
+private:
+  FaceInfoTable m_fit;
+
+  bool m_isProbingDue;
+  bool m_hasFirstProbeBeenScheduled;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+/** \brief Helper class to retrieve and create strategy measurements
+ */
+class AsfMeasurements : noncopyable
+{
+public:
+  explicit
+  AsfMeasurements(MeasurementsAccessor& measurements);
+
+  FaceInfo*
+  getFaceInfo(const fib::Entry& fibEntry, const ndn::Interest& interest, const Face& face);
+
+  FaceInfo&
+  getOrCreateFaceInfo(const fib::Entry& fibEntry, const ndn::Interest& interest, const Face& face);
+
+  shared_ptr<NamespaceInfo>
+  getNamespaceInfo(const ndn::Name& prefix);
+
+  NamespaceInfo&
+  getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const ndn::Interest& interest);
+
+  void
+  extendLifetime(shared_ptr<measurements::Entry> me);
+
+public:
+  static constexpr time::microseconds MEASUREMENTS_LIFETIME = time::seconds(300);
+
+private:
+  MeasurementsAccessor& m_measurements;
+};
+
+} // namespace asf
+} // namespace fw
+} // namespace nfd
+
+#endif // NFD_DAEMON_FW_ASF_MEASUREMENTS_HPP
diff --git a/daemon/fw/asf-probing-module.cpp b/daemon/fw/asf-probing-module.cpp
new file mode 100644
index 0000000..4be41f0
--- /dev/null
+++ b/daemon/fw/asf-probing-module.cpp
@@ -0,0 +1,195 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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/>.
+ */
+
+#include "asf-probing-module.hpp"
+
+#include "random.hpp"
+
+#include <boost/random/uniform_real_distribution.hpp>
+
+namespace nfd {
+namespace fw {
+namespace asf {
+
+constexpr time::seconds ProbingModule::DEFAULT_PROBING_INTERVAL;
+
+static_assert(ProbingModule::DEFAULT_PROBING_INTERVAL < AsfMeasurements::MEASUREMENTS_LIFETIME,
+              "ProbingModule::DEFAULT_PROBING_INTERVAL must be less than AsfMeasurements::MEASUREMENTS_LIFETIME");
+
+ProbingModule::ProbingModule(AsfMeasurements& measurements)
+  : m_probingInterval(DEFAULT_PROBING_INTERVAL)
+  , m_measurements(measurements)
+{
+}
+
+void
+ProbingModule::scheduleProbe(shared_ptr<fib::Entry> fibEntry, const time::milliseconds& interval)
+{
+  ndn::Name prefix = fibEntry->getPrefix();
+
+  // Set the probing flag for the namespace to true after passed interval of time
+  scheduler::schedule(interval, [this, prefix] {
+    shared_ptr<NamespaceInfo> info = m_measurements.getNamespaceInfo(prefix);
+
+    if (info == nullptr) {
+      // fib::Entry with the passed prefix has been removed or the fib::Entry has
+      // a name that is not controlled by the AsfStrategy
+      return;
+    }
+    else {
+      info->setIsProbingDue(true);
+    }
+  });
+}
+
+shared_ptr<Face>
+ProbingModule::getFaceToProbe(const Face& inFace,
+                              const Interest& interest,
+                              shared_ptr<fib::Entry> fibEntry,
+                              const Face& faceUsed)
+{
+  FaceInfoFacePairSet rankedFaces(
+    [] (FaceInfoFacePair pairLhs, FaceInfoFacePair pairRhs) -> bool {
+      // Sort by RTT
+      // If a face has timed-out, rank it behind non-timed-out faces
+      FaceInfo& lhs = *pairLhs.first;
+      FaceInfo& rhs = *pairRhs.first;
+
+      return (!lhs.isTimeout() && rhs.isTimeout()) ||
+             (lhs.isTimeout() == rhs.isTimeout() && lhs.getSrtt() < rhs.getSrtt());
+  });
+
+  // Put eligible faces into rankedFaces. If a face does not have an RTT measurement,
+  // immediately pick the face for probing
+  for (const fib::NextHop& hop : fibEntry->getNextHops()) {
+    const shared_ptr<Face>& hopFace = hop.getFace();
+
+    // Don't send probe Interest back to the incoming face or use the same face
+    // as the forwarded Interest
+    if (hopFace->getId() == inFace.getId() || hopFace->getId() == faceUsed.getId()) {
+      continue;
+    }
+
+    FaceInfo* info = m_measurements.getFaceInfo(*fibEntry, interest, *hopFace);
+
+    // If no RTT has been recorded, probe this face
+    if (info == nullptr || !info->hasSrttMeasurement()) {
+      return hopFace;
+    }
+
+    // Add FaceInfo to container sorted by RTT
+    rankedFaces.insert(std::make_pair(info, hopFace));
+  }
+
+  if (rankedFaces.empty()) {
+    // No Face to probe
+    return nullptr;
+  }
+
+  return getFaceBasedOnProbability(rankedFaces);
+}
+
+bool
+ProbingModule::isProbingNeeded(shared_ptr<fib::Entry> fibEntry, const ndn::Interest& interest)
+{
+  // Return the probing status flag for a namespace
+  NamespaceInfo& info = m_measurements.getOrCreateNamespaceInfo(*fibEntry, interest);
+
+  // If a first probe has not been scheduled for a namespace
+  if (!info.isFirstProbeScheduled()) {
+    // Schedule first probe between 0 and 5 seconds
+    uint64_t interval = getRandomNumber(0, 5000);
+    scheduleProbe(fibEntry, time::milliseconds(interval));
+
+    info.setHasFirstProbeBeenScheduled(true);
+  }
+
+  return info.isProbingDue();
+}
+
+void
+ProbingModule::afterForwardingProbe(shared_ptr<fib::Entry> fibEntry, const ndn::Interest& interest)
+{
+  // After probing is done, need to set probing flag to false and
+  // schedule another future probe
+  NamespaceInfo& info = m_measurements.getOrCreateNamespaceInfo(*fibEntry, interest);
+  info.setIsProbingDue(false);
+
+  scheduleProbe(fibEntry, m_probingInterval);
+}
+
+shared_ptr<Face>
+ProbingModule::getFaceBasedOnProbability(const FaceInfoFacePairSet& rankedFaces)
+{
+  double randomNumber = getRandomNumber(0, 1);
+  uint64_t rankSum = ((rankedFaces.size() + 1) * rankedFaces.size()) / 2;
+
+  uint64_t rank = 1;
+  double offset = 0.0;
+
+  for (const FaceInfoFacePair pair : rankedFaces) {
+    double probability = getProbingProbability(rank++, rankSum, rankedFaces.size());
+
+    // Is the random number within the bounds of this face's probability + the previous faces'
+    // probability?
+    //
+    // e.g. (FaceId: 1, p=0.5), (FaceId: 2, p=0.33), (FaceId: 3, p=0.17)
+    //      randomNumber = 0.92
+    //
+    //      The face with FaceId: 3 should be picked
+    //      (0.68 < 0.5 + 0.33 + 0.17) == true
+    //
+    if (randomNumber <= offset + probability) {
+      // Found face to probe
+      return pair.second;
+    }
+
+    offset += probability;
+  }
+
+  // Given a set of Faces, this method should always select a Face to probe
+  BOOST_ASSERT(false);
+  return nullptr;
+}
+
+double
+ProbingModule::getProbingProbability(uint64_t rank, uint64_t rankSum, uint64_t nFaces)
+{
+  // p = n + 1 - j ; n: # faces
+  //     ---------
+  //     sum(ranks)
+  return static_cast<double>(nFaces + 1 - rank) / rankSum;
+}
+
+double
+ProbingModule::getRandomNumber(double start, double end)
+{
+  boost::random::uniform_real_distribution<double> distribution(start, end);
+  return distribution(getGlobalRng());
+}
+
+} // namespace asf
+} // namespace fw
+} // namespace nfd
diff --git a/daemon/fw/asf-probing-module.hpp b/daemon/fw/asf-probing-module.hpp
new file mode 100644
index 0000000..a10b1f8
--- /dev/null
+++ b/daemon/fw/asf-probing-module.hpp
@@ -0,0 +1,85 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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_ASF_PROBING_MODULE_HPP
+#define NFD_DAEMON_FW_ASF_PROBING_MODULE_HPP
+
+#include "asf-measurements.hpp"
+
+namespace nfd {
+namespace fw {
+namespace asf {
+
+/** \brief ASF Probing Module
+ */
+class ProbingModule
+{
+public:
+  explicit
+  ProbingModule(AsfMeasurements& measurements);
+
+  void
+  scheduleProbe(shared_ptr<fib::Entry> fibEntry, const time::milliseconds& interval);
+
+  shared_ptr<Face>
+  getFaceToProbe(const Face& inFace,
+                 const Interest& interest,
+                 shared_ptr<fib::Entry> fibEntry,
+                 const Face& faceUsed);
+
+  bool
+  isProbingNeeded(shared_ptr<fib::Entry> fibEntry, const ndn::Interest& interest);
+
+  void
+  afterForwardingProbe(shared_ptr<fib::Entry> fibEntry, const ndn::Interest& interest);
+
+private:
+  // Used to associate FaceInfo with the face in a NextHop
+  typedef std::pair<FaceInfo*, shared_ptr<Face>> FaceInfoFacePair;
+  typedef std::function<bool(FaceInfoFacePair, FaceInfoFacePair)> FaceInfoPredicate;
+  typedef std::set<FaceInfoFacePair, FaceInfoPredicate> FaceInfoFacePairSet;
+
+  shared_ptr<Face>
+  getFaceBasedOnProbability(const FaceInfoFacePairSet& rankedFaces);
+
+  double
+  getProbingProbability(uint64_t rank, uint64_t rankSum, uint64_t nFaces);
+
+  double
+  getRandomNumber(double start, double end);
+
+public:
+  static constexpr time::seconds DEFAULT_PROBING_INTERVAL = time::seconds(60);
+
+private:
+  time::seconds m_probingInterval;
+  AsfMeasurements& m_measurements;
+};
+
+} // namespace asf
+} // namespace fw
+} // namespace nfd
+
+#endif // NFD_DAEMON_FW_ASF_PROBING_MODULE_HPP
diff --git a/daemon/fw/asf-strategy.cpp b/daemon/fw/asf-strategy.cpp
new file mode 100644
index 0000000..6a45c7e
--- /dev/null
+++ b/daemon/fw/asf-strategy.cpp
@@ -0,0 +1,293 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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/>.
+ */
+
+#include "asf-strategy.hpp"
+
+#include "core/logger.hpp"
+
+namespace nfd {
+namespace fw {
+namespace asf {
+
+NFD_LOG_INIT("AsfStrategy");
+
+const Name AsfStrategy::STRATEGY_NAME("ndn:/localhost/nfd/strategy/asf/%FD%01");
+const time::milliseconds AsfStrategy::RETX_SUPPRESSION_INITIAL(10);
+const time::milliseconds AsfStrategy::RETX_SUPPRESSION_MAX(250);
+
+NFD_REGISTER_STRATEGY(AsfStrategy);
+
+AsfStrategy::AsfStrategy(Forwarder& forwarder, const Name& name)
+  : Strategy(forwarder, name)
+  , m_measurements(getMeasurements())
+  , m_probing(m_measurements)
+  , m_retxSuppression(RETX_SUPPRESSION_INITIAL,
+                      RetxSuppressionExponential::DEFAULT_MULTIPLIER,
+                      RETX_SUPPRESSION_MAX)
+{
+}
+
+AsfStrategy::~AsfStrategy()
+{
+}
+
+void
+AsfStrategy::afterReceiveInterest(const Face& inFace,
+                                  const Interest& interest,
+                                  shared_ptr<fib::Entry> fibEntry,
+                                  shared_ptr<pit::Entry> pitEntry)
+{
+  // Should the Interest be suppressed?
+  RetxSuppression::Result suppressResult = m_retxSuppression.decide(inFace, interest, *pitEntry);
+
+  switch (suppressResult) {
+  case RetxSuppression::NEW:
+  case RetxSuppression::FORWARD:
+    break;
+  case RetxSuppression::SUPPRESS:
+    NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " suppressed");
+    return;
+  }
+
+  const fib::NextHopList& nexthops = fibEntry->getNextHops();
+
+  if (nexthops.size() == 0) {
+    sendNoRouteNack(inFace, interest, pitEntry);
+    this->rejectPendingInterest(pitEntry);
+    return;
+  }
+
+  const shared_ptr<Face> faceToUse = getBestFaceForForwarding(*fibEntry, interest, inFace);
+
+  if (faceToUse == nullptr) {
+    sendNoRouteNack(inFace, interest, pitEntry);
+    this->rejectPendingInterest(pitEntry);
+    return;
+  }
+
+  forwardInterest(interest, *fibEntry, pitEntry, faceToUse);
+
+  // If necessary, send probe
+  if (m_probing.isProbingNeeded(fibEntry, interest)) {
+    shared_ptr<Face> faceToProbe = m_probing.getFaceToProbe(inFace, interest, fibEntry, *faceToUse);
+
+    if (faceToProbe != nullptr) {
+      NFD_LOG_TRACE("Sending probe for " << fibEntry->getPrefix()
+                                         << " to FaceId: " << faceToProbe->getId());
+
+      bool wantNewNonce = true;
+      forwardInterest(interest, *fibEntry, pitEntry, faceToProbe, wantNewNonce);
+      m_probing.afterForwardingProbe(fibEntry, interest);
+    }
+  }
+}
+
+void
+AsfStrategy::beforeSatisfyInterest(shared_ptr<pit::Entry> pitEntry,
+                                   const Face& inFace,
+                                   const Data& data)
+{
+  shared_ptr<NamespaceInfo> namespaceInfo = m_measurements.getNamespaceInfo(pitEntry->getName());
+
+  if (namespaceInfo == nullptr) {
+    NFD_LOG_TRACE("Could not find measurements entry for " << pitEntry->getName());
+    return;
+  }
+
+  // Record the RTT between the Interest out to Data in
+  FaceInfo& faceInfo = namespaceInfo->get(inFace.getId());
+  faceInfo.recordRtt(pitEntry, inFace);
+
+  // Extend lifetime for measurements associated with Face
+  namespaceInfo->extendFaceInfoLifetime(faceInfo, inFace);
+
+  if (faceInfo.isTimeoutScheduled()) {
+    faceInfo.cancelTimeoutEvent(data.getName());
+  }
+}
+
+void
+AsfStrategy::afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+                              shared_ptr<fib::Entry> fibEntry,
+                              shared_ptr<pit::Entry> pitEntry)
+{
+  NFD_LOG_DEBUG("Nack for " << nack.getInterest() << " from=" << inFace.getId() << ": " << nack.getReason());
+  onTimeout(pitEntry->getName(), inFace.getId());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+void
+AsfStrategy::forwardInterest(const Interest& interest,
+                             const fib::Entry& fibEntry,
+                             shared_ptr<pit::Entry> pitEntry,
+                             shared_ptr<Face> outFace,
+                             bool wantNewNonce)
+{
+  this->sendInterest(pitEntry, outFace, wantNewNonce);
+
+  FaceInfo& faceInfo = m_measurements.getOrCreateFaceInfo(fibEntry, interest, *outFace);
+
+  // Refresh measurements since Face is being used for forwarding
+  NamespaceInfo& namespaceInfo = m_measurements.getOrCreateNamespaceInfo(fibEntry, interest);
+  namespaceInfo.extendFaceInfoLifetime(faceInfo, *outFace);
+
+  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");
+
+    scheduler::EventId id = scheduler::schedule(timeout,
+        bind(&AsfStrategy::onTimeout, this, interest.getName(), outFace->getId()));
+
+    faceInfo.setTimeoutEvent(id, interest.getName());
+  }
+}
+
+struct FaceStats
+{
+  shared_ptr<Face> face;
+  RttStats::Rtt rtt;
+  RttStats::Rtt srtt;
+  uint64_t cost;
+};
+
+double
+getValueForSorting(const FaceStats& stats)
+{
+  // These values allow faces with no measurements to be ranked better than timeouts
+  // srtt < RTT_NO_MEASUREMENT < RTT_TIMEOUT
+  static const RttStats::Rtt SORTING_RTT_TIMEOUT = time::microseconds::max();
+  static const RttStats::Rtt SORTING_RTT_NO_MEASUREMENT = SORTING_RTT_TIMEOUT / 2;
+
+  if (stats.rtt == RttStats::RTT_TIMEOUT) {
+    return SORTING_RTT_TIMEOUT.count();
+  }
+  else if (stats.rtt == RttStats::RTT_NO_MEASUREMENT) {
+    return SORTING_RTT_NO_MEASUREMENT.count();
+  }
+  else {
+    return stats.srtt.count();
+  }
+}
+
+const shared_ptr<Face>
+AsfStrategy::getBestFaceForForwarding(const fib::Entry& fibEntry, const ndn::Interest& interest, const Face& inFace)
+{
+  NFD_LOG_TRACE("Looking for best face for " << fibEntry.getPrefix());
+
+  typedef std::function<bool(const FaceStats&, const FaceStats&)> FaceStatsPredicate;
+  typedef std::set<FaceStats, FaceStatsPredicate> FaceStatsSet;
+
+  FaceStatsSet rankedFaces(
+    [] (const FaceStats& lhs, const FaceStats& rhs) -> bool {
+      // Sort by RTT and then by cost
+      double lhsValue = getValueForSorting(lhs);
+      double rhsValue = getValueForSorting(rhs);
+
+      if (lhsValue < rhsValue) {
+        return true;
+      }
+      else if (lhsValue == rhsValue) {
+        return lhs.cost < rhs.cost;
+      }
+      else {
+        return false;
+      }
+  });
+
+  for (const fib::NextHop& hop : fibEntry.getNextHops()) {
+
+    const shared_ptr<Face>& hopFace = hop.getFace();
+
+    if (hopFace->getId() == inFace.getId()) {
+      continue;
+    }
+
+    FaceInfo* info = m_measurements.getFaceInfo(fibEntry, interest, *hopFace);
+
+    if (info == nullptr) {
+      FaceStats stats = {hopFace,
+                         RttStats::RTT_NO_MEASUREMENT,
+                         RttStats::RTT_NO_MEASUREMENT,
+                         hop.getCost()};
+
+      rankedFaces.insert(stats);
+    }
+    else {
+      FaceStats stats = {hopFace, info->getRtt(), info->getSrtt(), hop.getCost()};
+      rankedFaces.insert(stats);
+    }
+  }
+
+  FaceStatsSet::iterator it = rankedFaces.begin();
+
+  if (it != rankedFaces.end()) {
+    return it->face;
+  }
+  else {
+    return nullptr;
+  }
+}
+
+void
+AsfStrategy::onTimeout(const ndn::Name& interestName, nfd::face::FaceId faceId)
+{
+  NFD_LOG_TRACE("FaceId: " << faceId << " for " << interestName << " has timed-out");
+
+  shared_ptr<NamespaceInfo> namespaceInfo = m_measurements.getNamespaceInfo(interestName);
+
+  if (namespaceInfo == nullptr) {
+    NFD_LOG_TRACE("FibEntry for " << interestName << " has been removed since timeout scheduling");
+    return;
+  }
+
+  FaceInfoTable::iterator it = namespaceInfo->find(faceId);
+
+  if (it == namespaceInfo->end()) {
+    it = namespaceInfo->insert(faceId);
+  }
+
+  FaceInfo& faceInfo = it->second;
+  faceInfo.recordTimeout(interestName);
+}
+
+void
+AsfStrategy::sendNoRouteNack(const Face& inFace, const Interest& interest, shared_ptr<pit::Entry> pitEntry)
+{
+  NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " noNextHop");
+
+  lp::NackHeader nackHeader;
+  nackHeader.setReason(lp::NackReason::NO_ROUTE);
+  this->sendNack(pitEntry, inFace, nackHeader);
+}
+
+} // namespace asf
+} // namespace fw
+} // namespace nfd
diff --git a/daemon/fw/asf-strategy.hpp b/daemon/fw/asf-strategy.hpp
new file mode 100644
index 0000000..1e028cc
--- /dev/null
+++ b/daemon/fw/asf-strategy.hpp
@@ -0,0 +1,107 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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_ASF_STRATEGY_HPP
+#define NFD_DAEMON_FW_ASF_STRATEGY_HPP
+
+#include "asf-measurements.hpp"
+#include "asf-probing-module.hpp"
+#include "fw/retx-suppression-exponential.hpp"
+#include "fw/strategy.hpp"
+
+namespace nfd {
+namespace fw {
+namespace asf {
+
+/** \brief Adaptive SRTT-based Forwarding Strategy
+ *
+ *  \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
+ */
+class AsfStrategy : public Strategy
+{
+public:
+  explicit
+  AsfStrategy(Forwarder& forwarder, const Name& name = STRATEGY_NAME);
+
+  virtual
+  ~AsfStrategy();
+
+public: // triggers
+  virtual void
+  afterReceiveInterest(const Face& inFace,
+                       const Interest& interest,
+                       shared_ptr<fib::Entry> fibEntry,
+                       shared_ptr<pit::Entry> pitEntry) override;
+
+  virtual void
+  beforeSatisfyInterest(shared_ptr<pit::Entry> pitEntry,
+                        const Face& inFace, const Data& data) override;
+
+  virtual void
+  afterReceiveNack(const Face& inFace, const lp::Nack& nack,
+                   shared_ptr<fib::Entry> fibEntry,
+                   shared_ptr<pit::Entry> pitEntry) override;
+
+private:
+  void
+  forwardInterest(const Interest& interest,
+                  const fib::Entry& fibEntry,
+                  shared_ptr<pit::Entry> pitEntry,
+                  shared_ptr<Face> outFace,
+                  bool wantNewNonce = false);
+
+  const shared_ptr<Face>
+  getBestFaceForForwarding(const fib::Entry& fibEntry, const ndn::Interest& interest, const Face& inFace);
+
+  void
+  onTimeout(const ndn::Name& interestName, nfd::face::FaceId faceId);
+
+  void
+  sendNoRouteNack(const Face& inFace, const Interest& interest, shared_ptr<pit::Entry> pitEntry);
+
+public:
+  static const Name STRATEGY_NAME;
+
+private:
+  AsfMeasurements m_measurements;
+  ProbingModule m_probing;
+
+private:
+  RetxSuppressionExponential m_retxSuppression;
+
+  static const time::milliseconds RETX_SUPPRESSION_INITIAL;
+  static const time::milliseconds RETX_SUPPRESSION_MAX;
+};
+
+} // namespace asf
+
+using asf::AsfStrategy;
+
+} // namespace fw
+} // namespace nfd
+
+#endif // NFD_DAEMON_FW_ASF_STRATEGY_HPP
diff --git a/tests/daemon/fw/asf-measurements.t.cpp b/tests/daemon/fw/asf-measurements.t.cpp
new file mode 100644
index 0000000..2b83004
--- /dev/null
+++ b/tests/daemon/fw/asf-measurements.t.cpp
@@ -0,0 +1,130 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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/>.
+ */
+
+#include "fw/asf-measurements.hpp"
+
+#include "tests/daemon/face/dummy-face.hpp"
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace fw {
+namespace asf {
+namespace tests {
+
+using namespace nfd::tests;
+
+BOOST_AUTO_TEST_SUITE(Fw)
+BOOST_AUTO_TEST_SUITE(TestAsfMeasurements)
+
+BOOST_AUTO_TEST_SUITE(TestRttStats)
+
+BOOST_FIXTURE_TEST_CASE(Basic, BaseFixture)
+{
+  RttStats stats;
+
+  BOOST_CHECK_EQUAL(stats.getRtt(), RttStats::RTT_NO_MEASUREMENT);
+  BOOST_CHECK_EQUAL(stats.getSrtt(), RttStats::RTT_NO_MEASUREMENT);
+
+  // Receive Data back in 50ms
+  RttEstimator::Duration rtt(time::milliseconds(50));
+  stats.addRttMeasurement(rtt);
+
+  BOOST_CHECK_EQUAL(stats.getRtt(), rtt);
+  BOOST_CHECK_EQUAL(stats.getSrtt(), rtt);
+
+  // Receive Data back in 50ms
+  stats.addRttMeasurement(rtt);
+
+  BOOST_CHECK_EQUAL(stats.getRtt(), rtt);
+  BOOST_CHECK_EQUAL(stats.getSrtt(), rtt);
+
+  // Receive Data back with a higher RTT
+  RttEstimator::Duration higherRtt(time::milliseconds(100));
+  stats.addRttMeasurement(higherRtt);
+
+  BOOST_CHECK_EQUAL(stats.getRtt(), higherRtt);
+  BOOST_CHECK_GT(stats.getSrtt(), rtt);
+  BOOST_CHECK_LT(stats.getSrtt(), higherRtt);
+
+  // Simulate timeout
+  RttStats::Rtt previousSrtt = stats.getSrtt();
+
+  stats.recordTimeout();
+
+  BOOST_CHECK_EQUAL(stats.getRtt(), RttStats::RTT_TIMEOUT);
+  BOOST_CHECK_EQUAL(stats.getSrtt(), previousSrtt);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestRttStats
+
+BOOST_AUTO_TEST_SUITE(TestFaceInfo)
+
+BOOST_FIXTURE_TEST_CASE(Basic, UnitTestTimeFixture)
+{
+  FaceInfo info;
+
+  scheduler::EventId id = scheduler::schedule(time::seconds(1), []{});
+  ndn::Name interestName("/ndn/interest");
+
+  // Receive Interest and forward to next hop; should update RTO information
+  info.setTimeoutEvent(id, interestName);
+  BOOST_CHECK_EQUAL(info.isTimeoutScheduled(), true);
+
+  // If the strategy tries to schedule an RTO when one is already scheduled, throw an exception
+  BOOST_CHECK_THROW(info.setTimeoutEvent(id, interestName), FaceInfo::Error);
+
+  // Receive Data
+  shared_ptr<Interest> interest = makeInterest(interestName);
+  shared_ptr<pit::Entry> pitEntry = make_shared<pit::Entry>(*interest);
+  std::shared_ptr<DummyFace> face = make_shared<DummyFace>();
+
+  pitEntry->insertOrUpdateOutRecord(face, *interest);
+
+  RttEstimator::Duration rtt(50);
+  this->advanceClocks(time::milliseconds(5), rtt);
+
+  info.recordRtt(pitEntry, *face);
+  info.cancelTimeoutEvent(interestName);
+
+  BOOST_CHECK_EQUAL(info.getRtt(), rtt);
+  BOOST_CHECK_EQUAL(info.getSrtt(), rtt);
+
+  // Send out another Interest which times out
+  info.setTimeoutEvent(id, interestName);
+
+  info.recordTimeout(interestName);
+  BOOST_CHECK_EQUAL(info.getRtt(), RttStats::RTT_TIMEOUT);
+  BOOST_CHECK_EQUAL(info.isTimeoutScheduled(), false);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestFaceInfo
+
+BOOST_AUTO_TEST_SUITE_END() // TestAsfStrategy
+BOOST_AUTO_TEST_SUITE_END() // Fw
+
+} // namespace tests
+} // namespace asf
+} // namespace fw
+} // namespace nfd
diff --git a/tests/daemon/fw/asf-strategy.t.cpp b/tests/daemon/fw/asf-strategy.t.cpp
new file mode 100644
index 0000000..687b0e2
--- /dev/null
+++ b/tests/daemon/fw/asf-strategy.t.cpp
@@ -0,0 +1,190 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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/>.
+ */
+
+#include "fw/asf-strategy.hpp"
+
+#include "tests/test-common.hpp"
+#include "topology-tester.hpp"
+
+namespace nfd {
+namespace fw {
+namespace asf {
+namespace tests {
+
+using namespace nfd::fw::tests;
+
+BOOST_AUTO_TEST_SUITE(Fw)
+BOOST_FIXTURE_TEST_SUITE(TestAsfStrategy, UnitTestTimeFixture)
+
+class AsfGridFixture : public UnitTestTimeFixture
+{
+protected:
+  AsfGridFixture()
+  {
+    /*
+     *                  +---------+
+     *           +----->|  nodeB  |<------+
+     *           |      +---------+       |
+     *      10ms |                        | 10ms
+     *           v                        v
+     *      +---------+              +---------+
+     *      |  nodeA  |              |  nodeC  |
+     *      +---------+              +---------+
+     *           ^                        ^
+     *     100ms |                        | 100ms
+     *           |      +---------+       |
+     *           +----->|  nodeD  |<------+
+     *                  +---------+
+     */
+
+    nodeA = topo.addForwarder("A");
+    nodeB = topo.addForwarder("B");
+    nodeC = topo.addForwarder("C");
+    nodeD = topo.addForwarder("D");
+
+    topo.setStrategy<fw::AsfStrategy>(nodeA);
+    topo.setStrategy<fw::AsfStrategy>(nodeB);
+    topo.setStrategy<fw::AsfStrategy>(nodeC);
+    topo.setStrategy<fw::AsfStrategy>(nodeD);
+
+    linkAB = topo.addLink("AB", time::milliseconds(10), {nodeA, nodeB});
+    linkAD = topo.addLink("AD", time::milliseconds(100), {nodeA, nodeD});
+    linkBC = topo.addLink("BC", time::milliseconds(10), {nodeB, nodeC});
+    linkCD = topo.addLink("CD", time::milliseconds(100), {nodeC, nodeD});
+
+    consumer = topo.addAppFace("c", nodeA);
+    producer = topo.addAppFace("p", nodeC, PRODUCER_PREFIX);
+    topo.addEchoProducer(producer->getClientFace());
+
+    // Register producer prefix on consumer node
+    topo.registerPrefix(nodeA, linkAB->getFace(nodeA), PRODUCER_PREFIX, 10);
+    topo.registerPrefix(nodeA, linkAD->getFace(nodeA), PRODUCER_PREFIX, 5);
+  }
+
+  void
+  runConsumer()
+  {
+    topo.addIntervalConsumer(consumer->getClientFace(), PRODUCER_PREFIX, time::seconds(1), 30);
+    this->advanceClocks(time::milliseconds(1), time::seconds(30));
+  }
+
+protected:
+  TopologyTester topo;
+
+  TopologyNode nodeA;
+  TopologyNode nodeB;
+  TopologyNode nodeC;
+  TopologyNode nodeD;
+
+  shared_ptr<TopologyLink> linkAB;
+  shared_ptr<TopologyLink> linkAD;
+  shared_ptr<TopologyLink> linkBC;
+  shared_ptr<TopologyLink> linkCD;
+
+  shared_ptr<TopologyAppLink> consumer;
+  shared_ptr<TopologyAppLink> producer;
+
+  static const Name PRODUCER_PREFIX;
+};
+
+const Name AsfGridFixture::PRODUCER_PREFIX = Name("ndn:/hr/C");
+
+BOOST_FIXTURE_TEST_CASE(Basic, AsfGridFixture)
+{
+  // Both nodeB and nodeD have FIB entries to reach the producer
+  topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
+  topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
+
+  runConsumer();
+
+  // ASF should use the Face to nodeD because it has lower routing cost.
+  // After 5 seconds, a probe Interest should be sent to the Face to nodeB,
+  // and the probe should return Data quicker. ASF should then use the Face
+  // to nodeB to forward the remaining Interests.
+  BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 30);
+  BOOST_CHECK_GE(linkAB->getFace(nodeA).getCounters().nOutInterests, 24);
+  BOOST_CHECK_LE(linkAD->getFace(nodeA).getCounters().nOutInterests, 6);
+
+  // If the link from nodeA to nodeB fails, ASF should start using the Face
+  // to nodeD again.
+  linkAB->fail();
+
+  runConsumer();
+
+  // Only 59 Data because the first Interest to nodeB after the failure should timeout
+  BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 59);
+  BOOST_CHECK_LE(linkAB->getFace(nodeA).getCounters().nOutInterests, 30);
+  BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 30);
+
+  // If the link from nodeA to nodeB recovers, ASF should probe the Face
+  // to nodeB and start using it again.
+  linkAB->recover();
+
+  // Advance time to ensure probing is due
+  this->advanceClocks(time::milliseconds(1), time::seconds(10));
+
+  runConsumer();
+
+  BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 89);
+  BOOST_CHECK_GE(linkAB->getFace(nodeA).getCounters().nOutInterests, 50);
+  BOOST_CHECK_LE(linkAD->getFace(nodeA).getCounters().nOutInterests, 40);
+
+  // If both links fail, nodeA should forward to the next hop with the lowest cost
+  linkAB->fail();
+  linkAD->fail();
+
+  runConsumer();
+
+  BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 89);
+  BOOST_CHECK_LE(linkAB->getFace(nodeA).getCounters().nOutInterests, 60);
+  BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 60);
+}
+
+BOOST_FIXTURE_TEST_CASE(Nack, AsfGridFixture)
+{
+  // nodeB has a FIB entry to reach the producer, but nodeD does not
+  topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
+
+  // The strategy should first try to send to nodeD. But since nodeD does not have a route for
+  // the producer's prefix, it should return a NO_ROUTE Nack. The strategy should then start using the Face to
+  // nodeB.
+  runConsumer();
+
+  BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nInNacks, 1);
+  BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 29);
+  BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nOutInterests, 29);
+
+  // nodeD should receive 2 Interests: one for the very first Interest and
+  // another from a probe
+  BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 2);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestAsfStrategy
+BOOST_AUTO_TEST_SUITE_END() // Fw
+
+} // namespace tests
+} // namespace asf
+} // namespace fw
+} // namespace nfd
