nrd<->rib: removing rib entries on face removal

refs #1327

Change-Id: I5abc10b3ab14fbf9b3bc6af64e896753c2cf5946
diff --git a/src/nrd.cpp b/src/nrd.cpp
index f22c000..09db6b2 100644
--- a/src/nrd.cpp
+++ b/src/nrd.cpp
@@ -34,17 +34,11 @@
                      ),
   };
 
-void
-Nrd::setInterestFilterFailed(const Name& name, const std::string& msg)
-{
-  std::cerr << "Error in setting interest filter (" << name << "): " << msg << std::endl;
-  m_face->shutdown();
-}
-
 Nrd::Nrd(const std::string& validatorConfig)
   : m_face(new Face())
-  , m_validator(m_face)
   , m_nfdController(new nfd::Controller(*m_face))
+  , m_validator(m_face)
+  , m_faceMonitor(*m_face)
   , m_verbDispatch(COMMAND_VERBS,
                    COMMAND_VERBS + (sizeof(COMMAND_VERBS) / sizeof(VerbAndProcessor)))
 {
@@ -63,9 +57,21 @@
   m_face->setInterestFilter(REMOTE_COMMAND_PREFIX.toUri(),
                             bind(&Nrd::onRibRequest, this, _2),
                             bind(&Nrd::setInterestFilterFailed, this, _1, _2));
+
+  std::cerr << "Monitoring faces" << std::endl;
+  m_faceMonitor.addSubscriber(boost::bind(&Nrd::onNotification, this, _1));
+  m_faceMonitor.startNotifications();
 }
 
 void
+Nrd::setInterestFilterFailed(const Name& name, const std::string& msg)
+{
+  std::cerr << "Error in setting interest filter (" << name << "): " << msg << std::endl;
+  m_face->shutdown();
+}
+
+
+void
 Nrd::sendResponse(const Name& name,
                   const nfd::ControlResponse& response)
 {
@@ -278,7 +284,6 @@
   m_face->shutdown();
 }
 
-
 void
 Nrd::enableLocalControlHeader()
 {
@@ -289,5 +294,14 @@
     bind(&Nrd::onControlHeaderError, this, _1, _2));
 }
 
+void
+Nrd::onNotification(const nfd::FaceEventNotification& notification)
+{
+  /// \todo A notification can be missed, in this case check Facelist
+  if (notification.getKind() == 2) { //face destroyed
+      m_managedRib.erase(notification.getFaceId());
+    }
+}
+
 } // namespace nrd
 } // namespace ndn
diff --git a/src/nrd.hpp b/src/nrd.hpp
index 49df0b5..b441de8 100644
--- a/src/nrd.hpp
+++ b/src/nrd.hpp
@@ -8,6 +8,7 @@
 #define NRD_HPP
 
 #include "rib.hpp"
+#include "face-monitor.hpp"
 
 namespace ndn {
 namespace nrd {
@@ -73,12 +74,17 @@
   bool
   extractOptions(const Interest& request,
                  PrefixRegOptions& extractedOptions);
+
+  void
+  onNotification(const nfd::FaceEventNotification& notification);
+
 private:
   Rib m_managedRib;
   ndn::shared_ptr<ndn::Face> m_face;
+  ndn::shared_ptr<nfd::Controller> m_nfdController;
   ndn::KeyChain m_keyChain;
   ndn::ValidatorConfig m_validator;
-  shared_ptr<nfd::Controller> m_nfdController;
+  ndn::FaceMonitor m_faceMonitor;
 
   typedef boost::function<void(Nrd*,
                                const Interest&,
diff --git a/src/rib.cpp b/src/rib.cpp
index 3fc9399..ce8d7a2 100644
--- a/src/rib.cpp
+++ b/src/rib.cpp
@@ -62,5 +62,19 @@
     }
 }
 
+void
+Rib::erase(uint64_t faceId)
+{
+  //Keep it simple for now, with Trie this will be changed.
+  RibTable::iterator it = m_rib.begin();
+  while (it != m_rib.end())
+  {
+    if (it->getFaceId() == faceId)
+      it = m_rib.erase(it);
+    else
+      ++it;
+  }
+}
+
 } // namespace nrd
 } // namespace ndn
diff --git a/src/rib.hpp b/src/rib.hpp
index f3a713a..3196817 100644
--- a/src/rib.hpp
+++ b/src/rib.hpp
@@ -33,6 +33,9 @@
   void
   erase(const PrefixRegOptions& options);
 
+  void
+  erase(uint64_t faceId);
+
   const_iterator
   begin() const;