33 #include <ndn-cxx/net/face-uri.hpp> 34 #include <ndn-cxx/signature.hpp> 42 Nlsr::Nlsr(boost::asio::io_service& ioService, ndn::Scheduler& scheduler, ndn::Face& face, ndn::KeyChain& keyChain)
44 , m_scheduler(scheduler)
45 , m_keyChain(keyChain)
49 , m_configFileName(
"nlsr.conf")
50 , m_nlsrLsdb(*this, scheduler)
52 , m_isBuildAdjLsaSheduled(false)
53 , m_isRouteCalculationScheduled(false)
54 , m_isRoutingTableCalculating(false)
55 , m_routingTable(scheduler)
56 , m_fib(m_nlsrFace, scheduler, m_adjacencyList, m_confParam, m_keyChain)
57 , m_namePrefixTable(*this, m_routingTable.afterRoutingChange)
58 , m_dispatcher(m_nlsrFace, m_keyChain)
59 , m_datasetHandler(m_nlsrLsdb,
64 , m_helloProtocol(*this, scheduler)
65 , m_validator(
ndn::make_unique<
ndn::security::v2::CertificateFetcherDirectFetch>(m_nlsrFace))
66 , m_controller(m_nlsrFace, m_keyChain)
67 , m_faceDatasetController(m_nlsrFace, m_keyChain)
68 , m_prefixUpdateProcessor(m_dispatcher,
72 , m_nfdRibCommandProcessor(m_dispatcher,
75 , m_statsCollector(m_nlsrLsdb, m_helloProtocol)
76 , m_faceMonitor(m_nlsrFace)
79 m_faceMonitor.onNotification.connect(std::bind(&Nlsr::onFaceEventNotification,
this, _1));
80 m_faceMonitor.start();
86 NLSR_LOG_ERROR(
"ERROR: Failed to register prefix in local hub's daemon");
87 BOOST_THROW_EXCEPTION(
Error(
"Error: Prefix registration failed"));
103 NLSR_LOG_DEBUG(
"Setting interest filter for Hello interest: " << name);
107 &m_helloProtocol, _1, _2),
111 ndn::nfd::ROUTE_FLAG_CAPTURE);
119 NLSR_LOG_DEBUG(
"Setting interest filter for LsaPrefix: " << name);
123 &m_nlsrLsdb, _1, _2),
127 ndn::nfd::ROUTE_FLAG_CAPTURE);
135 m_dispatcher.addTopPrefix(topPrefix,
false, m_signingInfo);
137 catch (
const std::exception& e) {
138 NLSR_LOG_ERROR(
"Error setting top-level prefix in dispatcher: " << e.what() <<
"\n");
145 const std::string strategy(
"ndn:/localhost/nfd/strategy/multicast");
152 Nlsr::canonizeContinuation(std::list<Adjacent>::iterator iterator,
153 std::function<
void(
void)>
finally)
156 canonizeContinuation(iterator,
finally);
163 std::function<
void(std::list<Adjacent>::iterator)> then,
164 std::function<
void(
void)>
finally)
166 if (currentNeighbor != m_adjacencyList.
getAdjList().end()) {
167 ndn::FaceUri uri(currentNeighbor->getFaceUri());
168 uri.canonize([
this, then, currentNeighbor] (ndn::FaceUri canonicalUri) {
170 <<
" to: " << canonicalUri);
171 currentNeighbor->setFaceUri(canonicalUri);
172 then(std::next(currentNeighbor));
174 [
this, then, currentNeighbor] (
const std::string& reason) {
175 NLSR_LOG_ERROR(
"Could not canonize URI: " << currentNeighbor->getFaceUri()
176 <<
" because: " << reason);
177 then(std::next(currentNeighbor));
179 m_nlsrFace.getIoService(),
192 m_certStore.
insert(certificate);
193 m_validator.loadAnchor(
"Authoritative-Certificate",
194 ndn::security::v2::Certificate(certificate));
196 loadAnchor(
"Authoritative-Certificate",
197 ndn::security::v2::Certificate(certificate));
212 NLSR_LOG_TRACE(
"SegmentFetcher fetched a data segment. Start inserting cert to own cert store.");
213 ndn::Name keyName = lsaSegment.getSignature().getKeyLocator().getName();
218 NLSR_LOG_TRACE(
"Certificate is already in the store: " << keyName);
225 const ndn::security::v2::Certificate* cert = m_validator.getUnverifiedCertCache()
227 if (cert !=
nullptr) {
228 m_certStore.
insert(*cert);
231 << ndn::security::v2::extractKeyNameFromCertName(cert->getName()));
232 m_nlsrFace.setInterestFilter(ndn::security::v2::extractKeyNameFromCertName(cert->getName()),
233 std::bind(&Nlsr::onKeyInterest,
235 std::bind(&Nlsr::onKeyPrefixRegSuccess,
this, _1),
238 ndn::nfd::ROUTE_FLAG_CAPTURE);
240 if (!cert->getKeyName().equals(cert->getSignature().getKeyLocator().getName())) {
245 NLSR_LOG_TRACE(
"Cert for " << keyName <<
" was not found in the Validator's cache. ");
274 NLSR_LOG_DEBUG(
"Default NLSR identity: " << m_signingInfo.getSignerName());
286 enableIncomingFaceIdIndication();
301 registerLocalhostPrefix();
308 std::list<Adjacent>& neighbors = m_adjacencyList.
getAdjList();
310 for (std::list<Adjacent>::iterator it = neighbors.begin(); it != neighbors.end(); ++it) {
322 nlsrInstanceName.append(
"NLSR");
325 m_keyChain.deleteIdentity(m_keyChain.getPib().getIdentity(nlsrInstanceName));
326 }
catch (
const std::exception& e) {
330 auto nlsrInstanceIdentity = m_keyChain.createIdentity(nlsrInstanceName);
331 auto nlsrInstanceKey = nlsrInstanceIdentity.getDefaultKey();
333 ndn::security::v2::Certificate certificate;
335 ndn::Name certificateName = nlsrInstanceKey.getName();
336 certificateName.append(
"NA");
337 certificateName.appendVersion();
338 certificate.setName(certificateName);
341 certificate.setContentType(ndn::tlv::ContentType_Key);
342 certificate.setFreshnessPeriod(ndn::time::days(365));
345 certificate.setContent(nlsrInstanceKey.getPublicKey().data(), nlsrInstanceKey.getPublicKey().size());
348 ndn::SignatureInfo signatureInfo;
349 signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(ndn::time::system_clock::TimePoint(),
350 ndn::time::system_clock::now()
351 + ndn::time::days(365)));
353 m_keyChain.sign(certificate,
354 ndn::security::SigningInfo(m_keyChain.getPib().getIdentity(m_confParam.
getRouterPrefix()))
355 .setSignatureInfo(signatureInfo));
357 catch (
const std::exception& e) {
359 <<
"NLSR is running without security." 360 <<
" If security is enabled NLSR will not converge.");
362 std::cerr <<
"Router's " << e.what() <<
". NLSR is running without security " 363 <<
"(Only for testing, should not be used in production.)" 364 <<
" If security is enabled NLSR will not converge." << std::endl;
367 m_signingInfo = ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID,
372 m_defaultCertName = certificate.getName();
376 Nlsr::registerKeyPrefix()
380 nlsrKeyPrefix.append(
"NLSR");
381 nlsrKeyPrefix.append(
"KEY");
383 m_nlsrFace.setInterestFilter(nlsrKeyPrefix,
384 std::bind(&Nlsr::onKeyInterest,
386 std::bind(&Nlsr::onKeyPrefixRegSuccess,
this, _1),
389 ndn::nfd::ROUTE_FLAG_CAPTURE);
393 routerKeyPrefix.append(
"KEY");
395 m_nlsrFace.setInterestFilter(routerKeyPrefix,
396 std::bind(&Nlsr::onKeyInterest,
398 std::bind(&Nlsr::onKeyPrefixRegSuccess,
this, _1),
401 ndn::nfd::ROUTE_FLAG_CAPTURE);
406 operatorKeyPrefix.append(std::string(
"%C1.Operator"));
408 m_nlsrFace.setInterestFilter(operatorKeyPrefix,
409 std::bind(&Nlsr::onKeyInterest,
411 std::bind(&Nlsr::onKeyPrefixRegSuccess,
this, _1),
414 ndn::nfd::ROUTE_FLAG_CAPTURE);
419 siteKeyPrefix.append(
"KEY");
421 m_nlsrFace.setInterestFilter(siteKeyPrefix,
422 std::bind(&Nlsr::onKeyInterest,
424 std::bind(&Nlsr::onKeyPrefixRegSuccess,
this, _1),
427 ndn::nfd::ROUTE_FLAG_CAPTURE);
431 Nlsr::registerLocalhostPrefix()
439 Nlsr::onKeyInterest(
const ndn::Name& name,
const ndn::Interest& interest)
441 NLSR_LOG_DEBUG(
"Got interest for certificate. Interest: " << interest.getName());
443 const ndn::Name& interestName = interest.getName();
444 const ndn::security::v2::Certificate* cert =
getCertificate(interestName);
446 if (cert ==
nullptr) {
451 m_nlsrFace.put(*cert);
455 Nlsr::onKeyPrefixRegSuccess(
const ndn::Name& name)
457 NLSR_LOG_DEBUG(
"KEY prefix: " << name <<
" registration is successful.");
461 Nlsr::onFaceEventNotification(
const ndn::nfd::FaceEventNotification& faceEventNotification)
465 switch (faceEventNotification.getKind()) {
466 case ndn::nfd::FACE_EVENT_DESTROYED: {
467 uint64_t faceId = faceEventNotification.getFaceId();
471 if (adjacent != m_adjacencyList.
end()) {
472 NLSR_LOG_DEBUG(
"Face to " << adjacent->getName() <<
" with face id: " << faceId <<
" destroyed");
474 adjacent->setFaceId(0);
508 case ndn::nfd::FACE_EVENT_CREATED: {
510 ndn::FaceUri faceUri;
512 faceUri = ndn::FaceUri(faceEventNotification.getRemoteUri());
514 catch (
const std::exception& e) {
522 if (adjacent != m_adjacencyList.
end()) {
523 NLSR_LOG_DEBUG(
"Face creation event matches neighbor: " << adjacent->getName()
524 <<
". New Face ID: " << faceEventNotification.getFaceId()
525 <<
". Registering prefixes.");
526 adjacent->setFaceId(faceEventNotification.getFaceId());
550 m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(onFetchSuccess, onFetchFailure);
560 for (
auto& adjacent : m_adjacencyList.
getAdjList()) {
562 const std::string faceUriString = adjacent.getFaceUri().toString();
564 for (
const ndn::nfd::FaceStatus& faceStatus : faces) {
567 if (adjacent.getFaceId() == 0 && faceUriString == faceStatus.getRemoteUri()) {
569 " FaceId: "<< faceStatus.getFaceId());
570 adjacent.setFaceId(faceStatus.getFaceId());
579 if (adjacent.getFaceId() == 0) {
581 " has no Face information in this dataset.");
585 scheduleDatasetFetch();
590 const ndn::time::milliseconds& timeout)
594 const ndn::Name& adjName = adj.
getName();
597 timeout, ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
600 faceUri, linkCost, timeout,
601 ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
604 faceUri, linkCost, timeout,
605 ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
610 const std::string& msg,
611 uint32_t nRetriesSoFar)
616 NLSR_LOG_DEBUG(
"Failed to fetch dataset: " << msg <<
". Attempting retry #" << nRetriesSoFar);
620 this, _1, _2, nRetriesSoFar));
623 NLSR_LOG_ERROR(
"Failed to fetch dataset: " << msg <<
". Exceeded limit of " <<
628 scheduleDatasetFetch();
633 Nlsr::scheduleDatasetFetch()
640 [
this] (
const std::vector<ndn::nfd::FaceStatus>& faces) {
643 [
this] (uint32_t code,
const std::string& msg) {
650 Nlsr::enableIncomingFaceIdIndication()
652 NLSR_LOG_DEBUG(
"Enabling incoming face id indication for local face.");
654 m_controller.start<ndn::nfd::FaceUpdateCommand>(
655 ndn::nfd::ControlParameters()
656 .setFlagBit(ndn::nfd::FaceFlagBit::BIT_LOCAL_FIELDS_ENABLED,
true),
657 bind(&Nlsr::onFaceIdIndicationSuccess,
this, _1),
658 bind(&Nlsr::onFaceIdIndicationFailure,
this, _1));
662 Nlsr::onFaceIdIndicationSuccess(
const ndn::nfd::ControlParameters& cp)
665 <<
"for face id " << cp.getFaceId());
669 Nlsr::onFaceIdIndicationFailure(
const ndn::nfd::ControlResponse& cr)
671 std::ostringstream os;
672 os <<
"Failed to enable incoming face id indication feature: " <<
673 "(code: " << cr.getCode() <<
", reason: " << cr.getText() <<
")";
681 m_nlsrFace.processEvents();
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)
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
const ndn::time::milliseconds & getSyncInterestLifetime() const
void scheduleAdjLsaBuild()
Schedules a build of this router's LSA.
std::function< void(uint32_t, const std::string &)> FetchDatasetTimeoutCallback
ConfParameter & getConfParameter()
void setAdjLsaBuildInterval(uint32_t interval)
const ndn::FaceUri & getFaceUri() const
const std::string & getSeqFileDir() const
void connectToFetcher(ndn::util::SegmentFetcher &fetcher)
#define NLSR_LOG_DEBUG(x)
const ndn::Name & getRouterPrefix() const
std::function< void(const std::vector< ndn::nfd::FaceStatus > &)> FetchDatasetCallback
void initiateSeqNoFromFile(int hypState)
void setStrategy(const ndn::Name &name, const std::string &strategy, uint32_t count)
SyncLogicHandler & getSyncLogicHandler()
RoutingTable & getRoutingTable()
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)
void canonizeNeighborUris(std::list< Adjacent >::iterator currentNeighbor, std::function< void(std::list< Adjacent >::iterator)> then, std::function< void(void)> finally)
Canonize the URI for this and all proceeding neighbors in a list.
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 setLsaRefreshTime(const ndn::time::seconds &lsaRefreshTime)
void scheduleRoutingTableCalculation(Nlsr &pnlsr)
Schedules a calculation event in the event scheduler only if one isn't already scheduled.
void onRegistrationSuccess(const ndn::Name &name)
void setEntryRefreshTime(int32_t fert)
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.
SequencingManager & getSequencingManager()
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
uint32_t getLsaRefreshTime() const
void setRoutingCalcInterval(uint32_t interval)
const ndn::Name & getChronosyncPrefix() const
A neighbor reachable over a Face.
#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.
uint32_t getAdjLsaBuildInterval() const
AdjacencyList::iterator findAdjacent(const ndn::Name &adjName)
const ndn::time::seconds TIME_ALLOWED_FOR_CANONIZATION
void setThisRouterPrefix(std::string trp)
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.
ndn::Face & getNlsrFace()
Nlsr(boost::asio::io_service &ioService, ndn::Scheduler &scheduler, ndn::Face &face, ndn::KeyChain &keyChain)
void setRouterNameCommandPrefix(const ndn::Name &routerName)
void createSyncSocket(const ndn::Name &syncPrefix, const ndn::time::milliseconds &syncInterestLifetime=ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT))
Create and configure a socket to enable ChronoSync for this NLSR.
bool buildAndInstallOwnNameLsa()
Builds a name LSA for this router and then installs it into the LSDB.
bool buildAndInstallOwnCoordinateLsa()
Builds a cor. LSA for this router and installs it into the LSDB.
int32_t getHyperbolicState() const
uint64_t getLinkCost() const
uint32_t getRoutingCalcInterval() const
void setSeqFileDirectory(std::string filePath)
Set the sequence file directory.
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.