mgmt: improved interest filter matching and bug fixes

tests/mgmt: added test fixtures to simplify unit testing

Added control response Data signing
Fixed control response payload parsing
Simplified fib-manager unit test assumptions
Expanded internal-face unit tests

refs: #1138

Change-Id: Ibe5d95ab9c42f890c0691c9040e4ae792e598974
diff --git a/daemon/mgmt/fib-manager.hpp b/daemon/mgmt/fib-manager.hpp
index 59a242b..a0de2fc 100644
--- a/daemon/mgmt/fib-manager.hpp
+++ b/daemon/mgmt/fib-manager.hpp
@@ -9,13 +9,12 @@
 
 #include "common.hpp"
 #include "face/face.hpp"
+#include "mgmt/app-face.hpp"
+#include "fw/strategy.hpp"
 #include "mgmt/manager-base.hpp"
 
 namespace nfd {
 
-class AppFace;
-class Face;
-class Strategy;
 class Forwarder;
 class Fib;
 
@@ -30,9 +29,6 @@
   void
   onFibRequest(const Interest& request);
 
-  const Name&
-  getRequestPrefix() const { return FIB_MANAGER_REQUEST_PREFIX; }
-
 private:
 
   void
@@ -57,7 +53,7 @@
 
   Fib& m_managedFib;
   function<shared_ptr<Face>(FaceId)> m_getFace;
-  std::map<Name, shared_ptr<Strategy> > m_namespaceToStrategyMap;
+  std::map<Name, shared_ptr<fw::Strategy> > m_namespaceToStrategyMap;
 
 
 
diff --git a/daemon/mgmt/internal-face.cpp b/daemon/mgmt/internal-face.cpp
index 0c3fe3b..ec1baab 100644
--- a/daemon/mgmt/internal-face.cpp
+++ b/daemon/mgmt/internal-face.cpp
@@ -18,26 +18,72 @@
 void
 InternalFace::sendInterest(const Interest& interest)
 {
+  if (m_interestFilters.size() == 0)
+    {
+      NFD_LOG_DEBUG("no Interest filters to match against");
+      return;
+    }
+
   const Name& interestName(interest.getName());
   NFD_LOG_DEBUG("received Interest: " << interestName);
 
-  size_t nComps = interestName.size();
-  for (size_t i = 0; i < nComps; i++)
-    {
-      Name prefix(interestName.getPrefix(nComps - i));
-      std::map<Name, OnInterest>::const_iterator filter =
-        m_interestFilters.find(prefix);
+  std::map<Name, OnInterest>::const_iterator filter =
+    m_interestFilters.lower_bound(interestName);
 
-      if (filter != m_interestFilters.end())
+  // lower_bound gives us the first Name that is
+  // an exact match OR ordered after interestName.
+  //
+  // If we reach the end of the map, then we need
+  // only check if the before-end element is a match.
+  //
+  // If we match an element, then the current
+  // position or the previous element are potential
+  // matches.
+  //
+  // If we hit begin, the element is either an exact
+  // match or there is no matching prefix in the map.
+
+
+  if (filter == m_interestFilters.end())
+    {
+      // We hit the end, check if the previous element
+      // is a match
+      --filter;
+      if (filter->first.isPrefixOf(interestName))
         {
-          NFD_LOG_DEBUG("found Interest filter for " << prefix);
+          NFD_LOG_DEBUG("found Interest filter for " << filter->first << " (before end match)");
           filter->second(interestName, interest);
         }
       else
         {
-          NFD_LOG_DEBUG("no Interest filter found for " << prefix);
+          NFD_LOG_DEBUG("no Interest filter found for " << interestName << " (before end)");
         }
     }
+  else if (filter->first.isPrefixOf(interestName))
+    {
+      NFD_LOG_DEBUG("found Interest filter for " << filter->first << " (exact match)");
+      filter->second(interestName, interest);
+    }
+  else if (filter != m_interestFilters.begin())
+    {
+      // the element we found is canonically
+      // ordered after interestName.
+      // Check the previous element.
+      --filter;
+      if (filter->first.isPrefixOf(interestName))
+        {
+          NFD_LOG_DEBUG("found Interest filter for " << filter->first << " (previous match)");
+          filter->second(interestName, interest);
+        }
+      else
+        {
+          NFD_LOG_DEBUG("no Interest filter found for " << interestName << " (previous)");
+        }
+    }
+  else
+    {
+      NFD_LOG_DEBUG("no Interest filter found for " << interestName << " (begin)");
+    }
   //Drop Interest
 }
 
diff --git a/daemon/mgmt/internal-face.hpp b/daemon/mgmt/internal-face.hpp
index 217d631..9539a9e 100644
--- a/daemon/mgmt/internal-face.hpp
+++ b/daemon/mgmt/internal-face.hpp
@@ -12,8 +12,6 @@
 
 namespace nfd {
 
-class FibManager;
-
 class InternalFace : public Face, public AppFace
 {
 public:
diff --git a/daemon/mgmt/manager-base.cpp b/daemon/mgmt/manager-base.cpp
index 5e561ff..2b27f85 100644
--- a/daemon/mgmt/manager-base.cpp
+++ b/daemon/mgmt/manager-base.cpp
@@ -29,47 +29,19 @@
                             uint32_t code,
                             const std::string& text)
 {
-  // Path 1 - runtime exception on receive's wireDecode.
-  // Set Data response's content payload to the
-  // encoded Block.
-  {
-    ndn::ControlResponse control(code, text);
-    const Block& encodedControl = control.wireEncode();
+  ndn::ControlResponse control(code, text);
+  const Block& encodedControl = control.wireEncode();
 
-    NFD_LOG_DEBUG("sending control response (Path 1)"
-                  << " Name: " << name
-                  << " code: " << code
-                  << " text: " << text);
+  NFD_LOG_DEBUG("sending control response"
+                << " Name: " << name
+                << " code: " << code
+                << " text: " << text);
 
-    NFD_LOG_DEBUG("sending raw control block size = " << encodedControl.size());
+  Data response(name);
+  response.setContent(encodedControl);
 
-    Data response(name);
-    response.setContent(encodedControl);
-
-    m_face->put(response);
-  }
-
-  // Path 2 - works, but not conformant to protocol.
-  // Encode ControlResponse and append Block as
-  // the last component of the name.
-  // {
-  //   ndn::ControlResponse control(code, text);
-  //   const Block& encodedControl = control.wireEncode();
-
-  //   NFD_LOG_DEBUG("sending control response (Path 2)"
-  //                 << " Name: " << name
-  //                 << " code: " << code
-  //                 << " text: " << text);
-
-  //   NFD_LOG_DEBUG("sending raw control block size = " << encodedControl.size());
-
-  //   Name responseName(name);
-  //   responseName.append(encodedControl);
-
-  //   Data response(responseName);
-  //   m_face->put(response);
-  // }
-
+  m_keyChain.sign(response);
+  m_face->put(response);
 }
 
 
diff --git a/daemon/mgmt/manager-base.hpp b/daemon/mgmt/manager-base.hpp
index 7308b3e..78ee38e 100644
--- a/daemon/mgmt/manager-base.hpp
+++ b/daemon/mgmt/manager-base.hpp
@@ -8,6 +8,7 @@
 #define NFD_MGMT_MANAGER_BASE_HPP
 
 #include "common.hpp"
+#include <ndn-cpp-dev/security/key-chain.hpp>
 
 namespace nfd {
 
@@ -30,6 +31,7 @@
 
 protected:
   shared_ptr<AppFace> m_face;
+   ndn::KeyChain m_keyChain;
 };