33 #include <ndn-cxx/net/face-uri.hpp> 34 #include <ndn-cxx/signature.hpp> 44 , m_scheduler(face.getIoService())
45 , m_keyChain(keyChain)
46 , m_confParam(confParam)
47 , m_adjacencyList(confParam.getAdjacencyList())
48 , m_namePrefixList(confParam.getNamePrefixList())
49 , m_validator(m_confParam.getValidator())
50 , m_fib(m_face, m_scheduler, m_adjacencyList, m_confParam, m_keyChain)
51 , m_routingTable(m_scheduler, m_fib, m_lsdb, m_namePrefixTable, m_confParam)
52 , m_namePrefixTable(m_fib, m_routingTable, m_routingTable.afterRoutingChange)
53 , m_lsdb(m_face, m_keyChain, m_signingInfo,
54 m_confParam, m_namePrefixTable, m_routingTable)
55 , m_afterSegmentValidatedConnection(m_lsdb.afterSegmentValidatedSignal.connect(
56 std::bind(&
Nlsr::afterFetcherSignalEmitted, this, _1)))
57 , m_onNewLsaConnection(m_lsdb.getSync().onNewLsa->connect(
58 [this] (const
ndn::Name& updateName, uint64_t sequenceNumber,
59 const
ndn::Name& originRouter) {
62 , m_dispatcher(m_face, m_keyChain)
63 , m_datasetHandler(m_dispatcher, m_lsdb, m_routingTable)
64 , m_helloProtocol(m_face, m_keyChain, m_signingInfo, confParam, m_routingTable, m_lsdb)
66 , m_controller(m_face, m_keyChain)
67 , m_faceDatasetController(m_face, m_keyChain)
68 , m_prefixUpdateProcessor(m_dispatcher,
73 , m_nfdRibCommandProcessor(m_dispatcher,
76 , m_statsCollector(m_lsdb, m_helloProtocol)
77 , m_faceMonitor(m_face)
79 m_faceMonitor.onNotification.connect(std::bind(&Nlsr::onFaceEventNotification,
this, _1));
80 m_faceMonitor.start();
88 for (
const ndn::Name& router : m_strategySetOnRouters) {
89 if (router == originRouter) {
95 m_strategySetOnRouters.push_back(originRouter);
97 ndn::Name routerKey(originRouter);
98 routerKey.append(
"KEY");
99 ndn::Name instanceKey(originRouter);
100 instanceKey.append(
"nlsr").append(
"KEY");
106 for (
size_t i = 0; i < originRouter.size(); ++i) {
107 if (originRouter[i].toUri() ==
"%C1.Router") {
110 siteKey.append(originRouter[i]);
112 ndn::Name opPrefix(siteKey);
113 siteKey.append(
"KEY");
116 opPrefix.append(std::string(
"%C1.Operator"));
123 NLSR_LOG_ERROR(
"ERROR: Failed to register prefix in local hub's daemon");
124 BOOST_THROW_EXCEPTION(
Error(
"Error: Prefix registration failed"));
140 NLSR_LOG_DEBUG(
"Setting interest filter for Hello interest: " << name);
142 m_face.setInterestFilter(ndn::InterestFilter(name).allowLoopback(
false),
146 m_signingInfo, ndn::nfd::ROUTE_FLAG_CAPTURE);
154 NLSR_LOG_DEBUG(
"Setting interest filter for LsaPrefix: " << name);
156 m_face.setInterestFilter(ndn::InterestFilter(name).allowLoopback(
false),
160 m_signingInfo, ndn::nfd::ROUTE_FLAG_CAPTURE);
168 m_dispatcher.addTopPrefix(topPrefix,
false, m_signingInfo);
170 catch (
const std::exception& e) {
171 NLSR_LOG_ERROR(
"Error setting top-level prefix in dispatcher: " << e.what() <<
"\n");
186 m_certStore.
insert(certificate);
187 m_validator.loadAnchor(
"Authoritative-Certificate",
188 ndn::security::v2::Certificate(certificate));
190 loadAnchor(
"Authoritative-Certificate",
191 ndn::security::v2::Certificate(certificate));
197 ndn::Name keyName = lsaSegment.getSignature().getKeyLocator().getName();
203 NLSR_LOG_TRACE(
"Certificate is already in the store: " << keyName);
210 const ndn::security::v2::Certificate* cert = m_validator.getUnverifiedCertCache()
213 if (cert !=
nullptr) {
214 m_certStore.
insert(*cert);
216 ndn::Name certName = ndn::security::v2::extractKeyNameFromCertName(cert->getName());
218 m_face.setInterestFilter(ndn::InterestFilter(certName).allowLoopback(
false),
219 std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
220 std::bind(&Nlsr::onKeyPrefixRegSuccess,
this, _1),
222 m_signingInfo, ndn::nfd::ROUTE_FLAG_CAPTURE);
224 if (!cert->getKeyName().equals(cert->getSignature().getKeyLocator().getName())) {
230 NLSR_LOG_TRACE(
"Cert for " << keyName <<
" was not found in the Validator's cache. ");
245 NLSR_LOG_DEBUG(
"Default NLSR identity: " << m_signingInfo.getSignerName());
259 enableIncomingFaceIdIndication();
261 m_lsdb.buildAndInstallOwnNameLsa();
265 m_lsdb.buildAndInstallOwnCoordinateLsa();
269 registerLocalhostPrefix();
270 registerRouterPrefix();
277 std::list<Adjacent>& neighbors = m_adjacencyList.
getAdjList();
279 for (std::list<Adjacent>::iterator it = neighbors.begin(); it != neighbors.end(); ++it) {
291 nlsrInstanceName.append(
"nlsr");
294 m_keyChain.deleteIdentity(m_keyChain.getPib().getIdentity(nlsrInstanceName));
295 }
catch (
const std::exception& e) {
299 auto nlsrInstanceIdentity = m_keyChain.createIdentity(nlsrInstanceName);
300 auto nlsrInstanceKey = nlsrInstanceIdentity.getDefaultKey();
302 ndn::security::v2::Certificate certificate;
304 ndn::Name certificateName = nlsrInstanceKey.getName();
305 certificateName.append(
"NA");
306 certificateName.appendVersion();
307 certificate.setName(certificateName);
310 certificate.setContentType(ndn::tlv::ContentType_Key);
311 certificate.setFreshnessPeriod(ndn::time::days(365));
314 certificate.setContent(nlsrInstanceKey.getPublicKey().data(), nlsrInstanceKey.getPublicKey().size());
317 ndn::SignatureInfo signatureInfo;
318 signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(ndn::time::system_clock::TimePoint(),
319 ndn::time::system_clock::now()
320 + ndn::time::days(365)));
322 m_keyChain.sign(certificate,
323 ndn::security::SigningInfo(m_keyChain.getPib().getIdentity(m_confParam.
getRouterPrefix()))
324 .setSignatureInfo(signatureInfo));
326 catch (
const std::exception& e) {
328 <<
"NLSR is running without security." 329 <<
" If security is enabled NLSR will not converge.");
331 std::cerr <<
"Router's " << e.what() <<
". NLSR is running without security " 332 <<
"(Only for testing, should not be used in production.)" 333 <<
" If security is enabled NLSR will not converge." << std::endl;
336 m_signingInfo = ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID,
343 Nlsr::registerKeyPrefix()
347 nlsrKeyPrefix.append(
"nlsr");
348 nlsrKeyPrefix.append(
"KEY");
350 m_face.setInterestFilter(ndn::InterestFilter(nlsrKeyPrefix).allowLoopback(
false),
351 std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
352 std::bind(&Nlsr::onKeyPrefixRegSuccess,
this, _1),
354 m_signingInfo, ndn::nfd::ROUTE_FLAG_CAPTURE);
358 routerKeyPrefix.append(
"KEY");
360 m_face.setInterestFilter(ndn::InterestFilter(routerKeyPrefix).allowLoopback(
false),
361 std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
362 std::bind(&Nlsr::onKeyPrefixRegSuccess,
this, _1),
364 m_signingInfo, ndn::nfd::ROUTE_FLAG_CAPTURE);
367 ndn::Name operatorKeyPrefix = m_confParam.
getNetwork();
368 operatorKeyPrefix.append(m_confParam.
getSiteName());
369 operatorKeyPrefix.append(std::string(
"%C1.Operator"));
371 m_face.setInterestFilter(ndn::InterestFilter(operatorKeyPrefix).allowLoopback(
false),
372 std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
373 std::bind(&Nlsr::onKeyPrefixRegSuccess,
this, _1),
375 m_signingInfo, ndn::nfd::ROUTE_FLAG_CAPTURE);
378 ndn::Name siteKeyPrefix = m_confParam.
getNetwork();
380 siteKeyPrefix.append(
"KEY");
382 m_face.setInterestFilter(ndn::InterestFilter(siteKeyPrefix).allowLoopback(
false),
383 std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
384 std::bind(&Nlsr::onKeyPrefixRegSuccess,
this, _1),
386 m_signingInfo, ndn::nfd::ROUTE_FLAG_CAPTURE);
390 Nlsr::registerLocalhostPrefix()
398 Nlsr::registerRouterPrefix()
400 m_face.registerPrefix(ndn::Name(m_confParam.
getRouterPrefix()).append(
"nlsr"),
406 Nlsr::onKeyInterest(
const ndn::Name& name,
const ndn::Interest& interest)
408 NLSR_LOG_DEBUG(
"Got interest for certificate. Interest: " << interest.getName());
410 const ndn::Name& interestName = interest.getName();
411 const ndn::security::v2::Certificate* cert =
getCertificate(interestName);
413 if (cert ==
nullptr) {
422 Nlsr::onKeyPrefixRegSuccess(
const ndn::Name& name)
424 NLSR_LOG_DEBUG(
"KEY prefix: " << name <<
" registration is successful.");
428 Nlsr::onFaceEventNotification(
const ndn::nfd::FaceEventNotification& faceEventNotification)
432 switch (faceEventNotification.getKind()) {
433 case ndn::nfd::FACE_EVENT_DESTROYED: {
434 uint64_t faceId = faceEventNotification.getFaceId();
438 if (adjacent != m_adjacencyList.
end()) {
439 NLSR_LOG_DEBUG(
"Face to " << adjacent->getName() <<
" with face id: " << faceId <<
" destroyed");
441 adjacent->setFaceId(0);
469 m_lsdb.scheduleAdjLsaBuild();
475 case ndn::nfd::FACE_EVENT_CREATED: {
477 ndn::FaceUri faceUri;
479 faceUri = ndn::FaceUri(faceEventNotification.getRemoteUri());
481 catch (
const std::exception& e) {
489 if (adjacent != m_adjacencyList.
end()) {
490 NLSR_LOG_DEBUG(
"Face creation event matches neighbor: " << adjacent->getName()
491 <<
". New Face ID: " << faceEventNotification.getFaceId()
492 <<
". Registering prefixes.");
493 adjacent->setFaceId(faceEventNotification.getFaceId());
501 m_lsdb.scheduleAdjLsaBuild();
517 m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(onFetchSuccess, onFetchFailure);
527 for (
auto& adjacent : m_adjacencyList.
getAdjList()) {
529 const std::string faceUriString = adjacent.getFaceUri().toString();
531 for (
const ndn::nfd::FaceStatus& faceStatus : faces) {
534 if (adjacent.getFaceId() == 0 && faceUriString == faceStatus.getRemoteUri()) {
536 " FaceId: "<< faceStatus.getFaceId());
537 adjacent.setFaceId(faceStatus.getFaceId());
546 if (adjacent.getFaceId() == 0) {
548 " has no Face information in this dataset.");
552 scheduleDatasetFetch();
557 const ndn::time::milliseconds& timeout)
561 const ndn::Name& adjName = adj.
getName();
564 timeout, ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
567 faceUri, linkCost, timeout,
568 ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
571 faceUri, linkCost, timeout,
572 ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
577 const std::string& msg,
578 uint32_t nRetriesSoFar)
583 NLSR_LOG_DEBUG(
"Failed to fetch dataset: " << msg <<
". Attempting retry #" << nRetriesSoFar);
587 this, _1, _2, nRetriesSoFar));
590 NLSR_LOG_ERROR(
"Failed to fetch dataset: " << msg <<
". Exceeded limit of " <<
595 scheduleDatasetFetch();
600 Nlsr::scheduleDatasetFetch()
607 [
this] (
const std::vector<ndn::nfd::FaceStatus>& faces) {
610 [
this] (uint32_t code,
const std::string& msg) {
617 Nlsr::enableIncomingFaceIdIndication()
619 NLSR_LOG_DEBUG(
"Enabling incoming face id indication for local face.");
621 m_controller.start<ndn::nfd::FaceUpdateCommand>(
622 ndn::nfd::ControlParameters()
623 .setFlagBit(ndn::nfd::FaceFlagBit::BIT_LOCAL_FIELDS_ENABLED,
true),
624 bind(&Nlsr::onFaceIdIndicationSuccess,
this, _1),
625 bind(&Nlsr::onFaceIdIndicationFailure,
this, _1));
629 Nlsr::onFaceIdIndicationSuccess(
const ndn::nfd::ControlParameters& cp)
632 <<
"for face id " << cp.getFaceId());
636 Nlsr::onFaceIdIndicationFailure(
const ndn::nfd::ControlResponse& cr)
638 std::ostringstream os;
639 os <<
"Failed to enable incoming face id indication feature: " <<
640 "(code: " << cr.getCode() <<
", reason: " << cr.getText() <<
")";
void initializeFaces(const FetchDatasetCallback &onFetchSuccess, const FetchDatasetTimeoutCallback &onFetchFailure)
Initializes neighbors' Faces using information from NFD.
void onFaceDatasetFetchTimeout(uint32_t code, const std::string &reason, uint32_t nRetriesSoFar)
A class to house all the configuration parameters for NLSR.
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
std::function< void(uint32_t, const std::string &)> FetchDatasetTimeoutCallback
const ndn::FaceUri & getFaceUri() const
static const std::string MULTICAST_STRATEGY
const std::string & getConfFileNameDynamic() const
void scheduleRoutingTableCalculation()
Schedules a calculation event in the event scheduler only if one isn't already scheduled.
#define NLSR_LOG_DEBUG(x)
ndn::security::ValidatorConfig & getPrefixUpdateValidator()
const ndn::Name & getRouterPrefix() const
std::function< void(const std::vector< ndn::nfd::FaceStatus > &)> FetchDatasetCallback
Nlsr(ndn::Face &face, ndn::KeyChain &keyChain, ConfParameter &confParam)
void setStrategy(const ndn::Name &name, const std::string &strategy, uint32_t count)
static const std::string BEST_ROUTE_V2_STRATEGY
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
void setLsaInterestFilter()
void addDispatcherTopPrefix(const ndn::Name &topPrefix)
Add top level prefixes for Dispatcher.
static const ndn::Name LOCALHOST_PREFIX
void scheduleInterest(uint32_t seconds)
Schedules a Hello Interest event.
void registerAdjacencyPrefixes(const Adjacent &adj, const ndn::time::milliseconds &timeout)
Registers NLSR-specific prefixes for a neighbor (Adjacent)
#define INIT_LOGGER(name)
const ndn::Name & getSyncPrefix() const
uint32_t getInterestRetryNumber() const
ndn::security::ValidatorConfig & getValidator()
const ndn::Name & getName() const
void insert(const ndn::security::v2::Certificate &certificate)
const ndn::Name & getLsaPrefix() const
void onRegistrationSuccess(const ndn::Name &name)
void loadCertToPublish(const ndn::security::v2::Certificate &certificate)
Add a certificate NLSR claims to be authoritative for to the certificate store.
void publishCertFromCache(const ndn::Name &keyName)
Retrieves the chain of certificates from Validator's cache and store them in Nlsr's own CertificateSt...
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
Processes a Hello Interest from a neighbor.
void setInfoInterestFilter()
void afterFetcherSignalEmitted(const ndn::Data &lsaSegment)
Callback when SegmentFetcher retrieves a segment.
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
A neighbor reachable over a Face.
void registerStrategyForCerts(const ndn::Name &originRouter)
#define NLSR_LOG_ERROR(x)
void registrationFailed(const ndn::Name &name)
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
AdjacencyList::iterator findAdjacent(const ndn::Name &adjName)
security::CertificateStore & getCertStore()
uint32_t getFirstHelloInterval() const
uint32_t getFaceDatasetFetchTries() const
const ndn::Name & getNetwork() const
const ndn::security::v2::Certificate * getCertificate(const ndn::Name &certificateKeyName)
Find a certificate.
int32_t getHyperbolicState() const
uint64_t getLinkCost() const
const ndn::Name & getSiteName() const
void processFaceDataset(const std::vector< ndn::nfd::FaceStatus > &faces)
Consumes a Face StatusDataset to configure NLSR neighbors.
const ndn::time::seconds getFaceDatasetFetchInterval() const
std::list< Adjacent > & getAdjList()
#define NLSR_LOG_TRACE(x)
const_iterator end() const
void registerPrefix(const ndn::Name &namePrefix, const ndn::FaceUri &faceUri, uint64_t faceCost, const ndn::time::milliseconds &timeout, uint64_t flags, uint8_t times)
Inform NFD of a next-hop.