src: set best-route strategy for certificate prefixes

refs: #4881

Change-Id: I655c261233e478bf01ff298b74af5eb62a33ffaf
diff --git a/src/communication/sync-logic-handler.cpp b/src/communication/sync-logic-handler.cpp
index 78547e2..1784267 100644
--- a/src/communication/sync-logic-handler.cpp
+++ b/src/communication/sync-logic-handler.cpp
@@ -140,7 +140,7 @@
                        "is enabled. Not going to fetch.");
         return;
       }
-      (*onNewLsa)(updateName, seqNo);
+      (*onNewLsa)(updateName, seqNo, originRouter);
     }
   }
 }
diff --git a/src/conf-file-processor.cpp b/src/conf-file-processor.cpp
index d3e75be..1517a87 100644
--- a/src/conf-file-processor.cpp
+++ b/src/conf-file-processor.cpp
@@ -261,7 +261,7 @@
   }
   else {
     std::cerr << "Wrong value for lsa-refresh-time ";
-    std::cerr << "Allowed value: " << LSA_REFRESH_TIME_MIN << "-";;
+    std::cerr << "Allowed value: " << LSA_REFRESH_TIME_MIN << "-";
     std::cerr << LSA_REFRESH_TIME_MAX << std::endl;
 
     return false;
diff --git a/src/lsdb.cpp b/src/lsdb.cpp
index d917fa6..01c1ee0 100644
--- a/src/lsdb.cpp
+++ b/src/lsdb.cpp
@@ -55,7 +55,8 @@
   , m_adjLsaBuildInterval(m_confParam.getAdjLsaBuildInterval())
   , m_sequencingManager(m_confParam.getStateFileDir(), m_confParam.getHyperbolicState())
   , m_onNewLsaConnection(m_sync.onNewLsa->connect(
-      [this] (const ndn::Name& updateName, uint64_t sequenceNumber) {
+      [this] (const ndn::Name& updateName, uint64_t sequenceNumber,
+              const ndn::Name& originRouter) {
         ndn::Name lsaInterest{updateName};
         lsaInterest.appendNumber(sequenceNumber);
         expressInterest(lsaInterest, 0);
diff --git a/src/lsdb.hpp b/src/lsdb.hpp
index 9d6575f..9f37002 100644
--- a/src/lsdb.hpp
+++ b/src/lsdb.hpp
@@ -207,6 +207,11 @@
     return m_isBuildAdjLsaSheduled;
   }
 
+  const SyncLogicHandler&
+  getSync() {
+    return m_sync;
+  }
+
 private:
   /* \brief Add a name LSA to the LSDB if it isn't already there.
      \param nlsa The candidade name LSA.
@@ -292,8 +297,6 @@
   expireOrRefreshCoordinateLsa(const ndn::Name& lsaKey,
                                uint64_t seqNo);
 
-private:
-
   void
   processInterestForNameLsa(const ndn::Interest& interest,
                             const ndn::Name& lsaKey,
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index 4dc536a..a6da9a0 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -54,6 +54,11 @@
            m_confParam, m_namePrefixTable, m_routingTable)
   , m_afterSegmentValidatedConnection(m_lsdb.afterSegmentValidatedSignal.connect(
                                       std::bind(&Nlsr::afterFetcherSignalEmitted, this, _1)))
+  , m_onNewLsaConnection(m_lsdb.getSync().onNewLsa->connect(
+                          [this] (const ndn::Name& updateName, uint64_t sequenceNumber,
+                                  const ndn::Name& originRouter) {
+                            registerStrategyForCerts(originRouter);
+                          }))
   , m_dispatcher(m_face, m_keyChain)
   , m_datasetHandler(m_dispatcher, m_lsdb, m_routingTable)
   , m_helloProtocol(m_face, m_keyChain, m_signingInfo, confParam, m_routingTable, m_lsdb)
@@ -78,6 +83,41 @@
 }
 
 void
+Nlsr::registerStrategyForCerts(const ndn::Name& originRouter)
+{
+  for (const ndn::Name& router : m_strategySetOnRouters) {
+    if (router == originRouter) {
+      // Have already set strategy for this router's certs once
+      return;
+    }
+  }
+
+  m_strategySetOnRouters.push_back(originRouter);
+
+  ndn::Name routerKey(originRouter);
+  routerKey.append("KEY");
+  ndn::Name instanceKey(originRouter);
+  instanceKey.append("nlsr").append("KEY");
+
+  m_fib.setStrategy(routerKey, Fib::BEST_ROUTE_V2_STRATEGY, 0);
+  m_fib.setStrategy(instanceKey, Fib::BEST_ROUTE_V2_STRATEGY, 0);
+
+  ndn::Name siteKey;
+  for (size_t i = 0; i < originRouter.size(); ++i) {
+    if (originRouter[i].toUri() == "%C1.Router") {
+      break;
+    }
+    siteKey.append(originRouter[i]);
+  }
+  ndn::Name opPrefix(siteKey);
+  siteKey.append("KEY");
+  m_fib.setStrategy(siteKey, Fib::BEST_ROUTE_V2_STRATEGY, 0);
+
+  opPrefix.append(std::string("%C1.Operator"));
+  m_fib.setStrategy(opPrefix, Fib::BEST_ROUTE_V2_STRATEGY, 0);
+}
+
+void
 Nlsr::registrationFailed(const ndn::Name& name)
 {
   NLSR_LOG_ERROR("ERROR: Failed to register prefix in local hub's daemon");
@@ -135,10 +175,8 @@
 void
 Nlsr::setStrategies()
 {
-  const std::string strategy("ndn:/localhost/nfd/strategy/multicast");
-
-  m_fib.setStrategy(m_confParam.getLsaPrefix(), strategy, 0);
-  m_fib.setStrategy(m_confParam.getSyncPrefix(), strategy, 0);
+  m_fib.setStrategy(m_confParam.getLsaPrefix(), Fib::MULTICAST_STRATEGY, 0);
+  m_fib.setStrategy(m_confParam.getSyncPrefix(), Fib::MULTICAST_STRATEGY, 0);
 }
 
 void
@@ -156,9 +194,9 @@
 void
 Nlsr::afterFetcherSignalEmitted(const ndn::Data& lsaSegment)
 {
-  NLSR_LOG_TRACE("SegmentFetcher fetched a data segment. Start inserting cert to own cert store.");
   ndn::Name keyName = lsaSegment.getSignature().getKeyLocator().getName();
   if (getCertificate(keyName) == nullptr) {
+    NLSR_LOG_TRACE("Publishing certificate for: " << keyName);
     publishCertFromCache(keyName);
   }
   else {
@@ -171,6 +209,7 @@
 {
   const ndn::security::v2::Certificate* cert = m_validator.getUnverifiedCertCache()
                                                           .find(keyName);
+
   if (cert != nullptr) {
     m_certStore.insert(*cert);
     NLSR_LOG_TRACE(*cert);
@@ -187,6 +226,7 @@
     }
   }
   else {
+    // Happens for root cert
     NLSR_LOG_TRACE("Cert for " << keyName << " was not found in the Validator's cache. ");
   }
 }
diff --git a/src/nlsr.hpp b/src/nlsr.hpp
index c0d6bc4..2124ceb 100644
--- a/src/nlsr.hpp
+++ b/src/nlsr.hpp
@@ -83,6 +83,9 @@
   Nlsr(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam);
 
   void
+  registerStrategyForCerts(const ndn::Name& originRouter);
+
+  void
   registrationFailed(const ndn::Name& name);
 
   void
@@ -268,6 +271,7 @@
   NamePrefixList& m_namePrefixList;
   bool m_isDaemonProcess;
   ndn::security::ValidatorConfig& m_validator;
+  std::vector<ndn::Name> m_strategySetOnRouters;
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   Fib m_fib;
@@ -277,6 +281,7 @@
 
 private:
   ndn::util::signal::ScopedConnection m_afterSegmentValidatedConnection;
+  ndn::util::signal::ScopedConnection m_onNewLsaConnection;
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   ndn::mgmt::Dispatcher m_dispatcher;
diff --git a/src/route/fib.cpp b/src/route/fib.cpp
index 5966108..7d08e12 100644
--- a/src/route/fib.cpp
+++ b/src/route/fib.cpp
@@ -34,6 +34,8 @@
 INIT_LOGGER(route.Fib);
 
 const uint64_t Fib::GRACE_PERIOD = 10;
+const std::string Fib::MULTICAST_STRATEGY("ndn:/localhost/nfd/strategy/multicast");
+const std::string Fib::BEST_ROUTE_V2_STRATEGY("ndn:/localhost/nfd/strategy/best-route");
 
 Fib::Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList,
          ConfParameter& conf, ndn::security::v2::KeyChain& keyChain)
diff --git a/src/route/fib.hpp b/src/route/fib.hpp
index 2d4f47f..f2d952a 100644
--- a/src/route/fib.hpp
+++ b/src/route/fib.hpp
@@ -237,6 +237,10 @@
   void
   refreshEntry(const ndn::Name& name, afterRefreshCallback refreshCb);
 
+public:
+  static const std::string MULTICAST_STRATEGY;
+  static const std::string BEST_ROUTE_V2_STRATEGY;
+
 private:
   ndn::Scheduler& m_scheduler;
   int32_t m_refreshTime;
diff --git a/src/sequencing-manager.cpp b/src/sequencing-manager.cpp
index 9f52b71..2aa8e98 100644
--- a/src/sequencing-manager.cpp
+++ b/src/sequencing-manager.cpp
@@ -76,7 +76,7 @@
     inputFile >> lsaOrCombinedSeqNo >> seqNo;
     m_adjLsaSeq = seqNo;
 
-    inputFile >> lsaOrCombinedSeqNo >> seqNo;;
+    inputFile >> lsaOrCombinedSeqNo >> seqNo;
     m_corLsaSeq = seqNo;
 
     // File was in old format and had a combined sequence number
diff --git a/src/signals.hpp b/src/signals.hpp
index 7da49ec..a0191ff 100644
--- a/src/signals.hpp
+++ b/src/signals.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017,  The University of Memphis,
+ * Copyright (c) 2014-2019,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -33,7 +33,7 @@
 class SyncLogicHandler;
 
 using AfterRoutingChange = ndn::util::Signal<RoutingTable, const std::list<RoutingTableEntry>&>;
-using OnNewLsa = ndn::util::Signal<SyncLogicHandler, const ndn::Name&, const uint64_t&>;
+using OnNewLsa = ndn::util::Signal<SyncLogicHandler, const ndn::Name&, const uint64_t&, const ndn::Name&>;
 
 } // namespace nlsr
 
diff --git a/src/tlv/routing-table-status.cpp b/src/tlv/routing-table-status.cpp
index 6f4bb24..a35f88c 100644
--- a/src/tlv/routing-table-status.cpp
+++ b/src/tlv/routing-table-status.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2018,  The University of Memphis,
+ * Copyright (c) 2014-2019,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -139,7 +139,7 @@
 std::ostream&
 operator<<(std::ostream& os, const RoutingTableStatus& rtStatus)
 {
-  os << "Routing Table Status: " << std::endl;;
+  os << "Routing Table Status: " << std::endl;
 
   bool isFirst = true;
 
diff --git a/src/update/prefix-update-processor.cpp b/src/update/prefix-update-processor.cpp
index 0e20c8c..3552123 100644
--- a/src/update/prefix-update-processor.cpp
+++ b/src/update/prefix-update-processor.cpp
@@ -126,7 +126,7 @@
 bool
 PrefixUpdateProcessor::addOrDeletePrefix(const ndn::Name& prefix, bool addPrefix)
 {
-  std::string value = " prefix " + prefix.toUri();;
+  std::string value = " prefix " + prefix.toUri();
   std::string fileString;
   std::string line;
   std::string trimedLine;
diff --git a/tests/communication/test-sync-logic-handler.cpp b/tests/communication/test-sync-logic-handler.cpp
index b94bcb5..4dc6346 100644
--- a/tests/communication/test-sync-logic-handler.cpp
+++ b/tests/communication/test-sync-logic-handler.cpp
@@ -105,7 +105,8 @@
 
     // Actual testing done here -- signal function callback
     ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
-      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
+           const ndn::Name& originRouter) {
         BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
         BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
       });
@@ -129,7 +130,8 @@
     std::string updateName = this->updateNamePrefix + std::to_string(lsaType);
 
     ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
-      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
+           const ndn::Name& originRouter) {
         BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
         BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
       });
@@ -152,7 +154,8 @@
     std::string updateName = this->updateNamePrefix + std::to_string(lsaType);
 
     ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
-      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
+           const ndn::Name& originRouter) {
         BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
         BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
       });
@@ -178,7 +181,8 @@
               .append(std::to_string(lsaType));
 
     ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
-      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
+           const ndn::Name& originRouter) {
         BOOST_FAIL("Updates for self should not be emitted!");
       });
 
@@ -199,7 +203,8 @@
     updateName.append(this->conf.getRouterName()).append(std::to_string(lsaType));
 
     ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
-      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
+           const ndn::Name& originRouter) {
         BOOST_FAIL("Malformed updates should not be emitted!");
       });
 
@@ -221,7 +226,8 @@
   const uint64_t sequenceNumber = 1;
   SyncLogicHandler sync{this->face, testLsaAlwaysFalse, this->conf};
     ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
-      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
+           const ndn::Name& originRouter) {
         BOOST_FAIL("An update for an LSA with non-new sequence number should not emit!");
       });