30 #include <ndn-cxx/mgmt/nfd/control-command.hpp>
31 #include <ndn-cxx/mgmt/nfd/status-dataset.hpp>
32 #include <ndn-cxx/net/face-uri.hpp>
40 , m_scheduler(face.getIoContext())
41 , m_confParam(confParam)
42 , m_adjacencyList(confParam.getAdjacencyList())
43 , m_namePrefixList(confParam.getNamePrefixList())
44 , m_fib(m_face, m_scheduler, m_adjacencyList, m_confParam, keyChain)
45 , m_lsdb(m_face, keyChain, m_confParam)
46 , m_routingTable(m_scheduler, m_lsdb, m_confParam)
47 , m_namePrefixTable(confParam.getRouterPrefix(), m_fib, m_routingTable,
48 m_routingTable.afterRoutingChange, m_lsdb.onLsdbModified)
49 , m_helloProtocol(m_face, keyChain, confParam, m_routingTable, m_lsdb)
50 , m_onNewLsaConnection(m_lsdb.getSync().onNewLsa.connect(
51 [this] (const ndn::Name& updateName, uint64_t sequenceNumber,
52 const ndn::Name& originRouter, uint64_t incomingFaceId) {
53 registerStrategyForCerts(originRouter);
55 , m_onPrefixRegistrationSuccess(m_fib.onPrefixRegistrationSuccess.connect(
56 [
this] (
const ndn::Name& name) {
57 m_helloProtocol.sendHelloInterest(name);
59 , m_onInitialHelloDataValidated(m_helloProtocol.onInitialHelloDataValidated.connect(
60 [
this] (
const ndn::Name& neighbor) {
61 auto it = m_adjacencyList.findAdjacent(neighbor);
62 if (it != m_adjacencyList.end()) {
63 m_fib.registerPrefix(m_confParam.getSyncPrefix(), it->getFaceUri(), it->getLinkCost(),
64 ndn::time::milliseconds::max(), ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
67 , m_dispatcher(m_face, keyChain)
68 , m_datasetHandler(m_dispatcher, m_lsdb, m_routingTable)
69 , m_controller(m_face, keyChain)
70 , m_faceDatasetController(m_face, keyChain)
71 , m_prefixUpdateProcessor(m_dispatcher,
72 m_confParam.getPrefixUpdateValidator(),
75 m_confParam.getConfFileNameDynamic())
76 , m_nfdRibCommandProcessor(m_dispatcher,
79 , m_statsCollector(m_lsdb, m_helloProtocol)
80 , m_faceMonitor(m_face)
81 , m_terminateSignals(face.getIoContext(), SIGINT, SIGTERM)
85 m_faceMonitor.onNotification.connect(std::bind(&Nlsr::onFaceEventNotification,
this, _1));
86 m_faceMonitor.start();
88 m_fib.setStrategy(m_confParam.getLsaPrefix(), Fib::MULTICAST_STRATEGY, 0);
89 m_fib.setStrategy(m_confParam.getSyncPrefix(), Fib::MULTICAST_STRATEGY, 0);
91 NLSR_LOG_DEBUG(
"Default NLSR identity: " << m_confParam.getSigningInfo().getSignerName());
94 addDispatcherTopPrefix(ndn::Name(m_confParam.getRouterPrefix()).append(
"nlsr"));
95 addDispatcherTopPrefix(LOCALHOST_PREFIX);
97 enableIncomingFaceIdIndication();
99 initializeFaces(std::bind(&Nlsr::processFaceDataset,
this, _1),
100 std::bind(&Nlsr::onFaceDatasetFetchTimeout,
this, _1, _2, 0));
102 m_adjacencyList.writeLog();
107 for (
auto&& neighbor : m_adjacencyList.getAdjList()) {
108 neighbor.setLinkCost(0);
112 m_terminateSignals.async_wait([
this] (
auto&&... args) {
113 terminate(std::forward<decltype(args)>(args)...);
118 Nlsr::registerStrategyForCerts(
const ndn::Name& originRouter)
120 for (
const ndn::Name& router : m_strategySetOnRouters) {
121 if (router == originRouter) {
127 m_strategySetOnRouters.push_back(originRouter);
129 ndn::Name routerKey(originRouter);
130 routerKey.append(ndn::security::Certificate::KEY_COMPONENT);
131 ndn::Name instanceKey(originRouter);
132 instanceKey.append(
"nlsr").append(ndn::security::Certificate::KEY_COMPONENT);
134 m_fib.setStrategy(routerKey, Fib::BEST_ROUTE_STRATEGY, 0);
135 m_fib.setStrategy(instanceKey, Fib::BEST_ROUTE_STRATEGY, 0);
138 for (
size_t i = 0; i < originRouter.size(); ++i) {
139 if (originRouter[i].toUri() ==
"%C1.Router") {
142 siteKey.append(originRouter[i]);
144 ndn::Name opPrefix(siteKey);
145 siteKey.append(ndn::security::Certificate::KEY_COMPONENT);
146 m_fib.setStrategy(siteKey, Fib::BEST_ROUTE_STRATEGY, 0);
148 opPrefix.append(std::string(
"%C1.Operator"));
149 m_fib.setStrategy(opPrefix, Fib::BEST_ROUTE_STRATEGY, 0);
153 Nlsr::addDispatcherTopPrefix(
const ndn::Name& topPrefix)
155 registerPrefix(topPrefix);
158 m_dispatcher.addTopPrefix(topPrefix,
false, m_confParam.getSigningInfo());
160 catch (
const std::exception& e) {
161 NLSR_LOG_ERROR(
"Error setting top-level prefix in dispatcher: " << e.what());
166 Nlsr::registerPrefix(
const ndn::Name& prefix)
168 m_face.registerPrefix(prefix,
169 [] (
const ndn::Name& name) {
172 [] (
const ndn::Name& name,
const std::string& reason) {
173 NLSR_LOG_ERROR(
"Failed to register prefix " << name <<
" (" << reason <<
")");
174 NDN_THROW(Error(
"Prefix registration failed: " + reason));
179 Nlsr::onFaceEventNotification(
const ndn::nfd::FaceEventNotification& faceEventNotification)
183 switch (faceEventNotification.getKind()) {
184 case ndn::nfd::FACE_EVENT_DESTROYED: {
185 uint64_t faceId = faceEventNotification.getFaceId();
187 auto adjacent = m_adjacencyList.findAdjacent(faceId);
189 if (adjacent != m_adjacencyList.end()) {
190 NLSR_LOG_DEBUG(
"Face to " << adjacent->getName() <<
" with face id: " << faceId <<
" destroyed");
192 adjacent->setFaceId(0);
209 if (adjacent->getStatus() == Adjacent::STATUS_ACTIVE) {
210 adjacent->setStatus(Adjacent::STATUS_INACTIVE);
214 adjacent->setInterestTimedOutNo(m_confParam.getInterestRetryNumber());
217 m_routingTable.scheduleRoutingTableCalculation();
222 m_lsdb.scheduleAdjLsaBuild();
228 case ndn::nfd::FACE_EVENT_CREATED: {
230 ndn::FaceUri faceUri;
232 faceUri = ndn::FaceUri(faceEventNotification.getRemoteUri());
234 catch (
const std::exception& e) {
238 auto adjacent = m_adjacencyList.findAdjacent(faceUri);
239 uint64_t faceId = faceEventNotification.getFaceId();
243 if (adjacent != m_adjacencyList.end() &&
244 (adjacent->getFaceId() == 0 || adjacent->getFaceId() != faceId))
246 NLSR_LOG_DEBUG(
"Face creation event matches neighbor: " << adjacent->getName()
247 <<
". New Face ID: " << faceId <<
". Registering prefixes.");
248 adjacent->setFaceId(faceId);
250 registerAdjacencyPrefixes(*adjacent, ndn::time::milliseconds::max());
265 Nlsr::initializeFaces(
const FetchDatasetCallback& onFetchSuccess,
266 const FetchDatasetTimeoutCallback& onFetchFailure)
269 m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(onFetchSuccess, onFetchFailure);
273 Nlsr::processFaceDataset(
const std::vector<ndn::nfd::FaceStatus>& faces)
278 for (
auto&& adjacent : m_adjacencyList.getAdjList()) {
280 const std::string& faceUriString = adjacent.getFaceUri().toString();
282 for (
const auto& faceStatus : faces) {
285 if (adjacent.getFaceId() == 0 && faceUriString == faceStatus.getRemoteUri()) {
287 " FaceId: "<< faceStatus.getFaceId());
288 adjacent.setFaceId(faceStatus.getFaceId());
290 this->registerAdjacencyPrefixes(adjacent, ndn::time::milliseconds::max());
297 if (adjacent.getFaceId() == 0) {
299 " has no Face information in this dataset.");
303 scheduleDatasetFetch();
307 Nlsr::registerAdjacencyPrefixes(
const Adjacent& adj, ndn::time::milliseconds timeout)
309 ndn::FaceUri faceUri = adj.getFaceUri();
310 double linkCost = adj.getLinkCost();
311 const ndn::Name& adjName = adj.getName();
313 m_fib.registerPrefix(adjName, faceUri, linkCost,
314 timeout, ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
316 m_fib.registerPrefix(m_confParam.getLsaPrefix(),
317 faceUri, linkCost, timeout,
318 ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
322 Nlsr::onFaceDatasetFetchTimeout(uint32_t code,
323 const std::string& msg,
324 uint32_t nRetriesSoFar)
327 if (nRetriesSoFar++ < m_confParam.getFaceDatasetFetchTries()) {
328 NLSR_LOG_DEBUG(
"Failed to fetch dataset: " << msg <<
". Attempting retry #" << nRetriesSoFar);
329 m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(std::bind(&Nlsr::processFaceDataset,
this, _1),
330 std::bind(&Nlsr::onFaceDatasetFetchTimeout,
331 this, _1, _2, nRetriesSoFar));
334 NLSR_LOG_ERROR(
"Failed to fetch dataset: " << msg <<
". Exceeded limit of " <<
335 m_confParam.getFaceDatasetFetchTries() <<
", so not trying again this time.");
339 scheduleDatasetFetch();
344 Nlsr::scheduleDatasetFetch()
346 NLSR_LOG_DEBUG(
"Scheduling dataset fetch in " << m_confParam.getFaceDatasetFetchInterval());
348 m_scheduler.schedule(m_confParam.getFaceDatasetFetchInterval(), [
this] {
350 [this] (const auto& faces) { processFaceDataset(faces); },
351 [
this] (uint32_t code,
const std::string& msg) { onFaceDatasetFetchTimeout(code, msg, 0); });
356 Nlsr::enableIncomingFaceIdIndication()
358 NLSR_LOG_DEBUG(
"Enabling incoming face id indication for local face.");
360 m_controller.start<ndn::nfd::FaceUpdateCommand>(
361 ndn::nfd::ControlParameters()
362 .setFlagBit(ndn::nfd::FaceFlagBit::BIT_LOCAL_FIELDS_ENABLED,
true),
363 [] (
const ndn::nfd::ControlParameters& cp) {
365 <<
"for face id " << cp.getFaceId());
367 [] (
const ndn::nfd::ControlResponse& cr) {
368 NLSR_LOG_WARN(
"Failed to enable incoming face id indication feature: " <<
369 "(code: " << cr.getCode() <<
", reason: " << cr.getText() <<
")");
374 Nlsr::terminate(
const boost::system::error_code& error,
int signalNo)
378 NLSR_LOG_INFO(
"Caught signal " << signalNo <<
" (" << ::strsignal(signalNo) <<
"), exiting...");
379 m_face.getIoContext().stop();
A class to house all the configuration parameters for NLSR.
Nlsr(ndn::Face &face, ndn::KeyChain &keyChain, ConfParameter &confParam)
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
#define NLSR_LOG_DEBUG(x)
#define INIT_LOGGER(name)
#define NLSR_LOG_ERROR(x)
#define NLSR_LOG_TRACE(x)
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California.