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/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
 }