Loading...
Searching...
No Matches
conf-file-processor.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014-2025, The University of Memphis,
4 * Regents of the University of California,
5 * Arizona Board of Regents.
6 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
20 */
21
23#include "adjacent.hpp"
26
27#include <ndn-cxx/name.hpp>
28#include <ndn-cxx/net/face-uri.hpp>
29#include <ndn-cxx/util/io.hpp>
30
31#include <boost/algorithm/string.hpp>
32#include <boost/property_tree/info_parser.hpp>
33#include <boost/property_tree/exceptions.hpp>
34
35#include <filesystem>
36#include <fstream>
37#include <iostream>
38
39namespace nlsr {
40
41namespace fs = std::filesystem;
42
43template <class T>
44class ConfigurationVariable
45{
46public:
47 typedef std::function<void(T)> ConfParameterCallback;
48
49 ConfigurationVariable(const std::string& key, const ConfParameterCallback& setter)
50 : m_key(key)
51 , m_setterCallback(setter)
52 , m_minValue(0)
53 , m_maxValue(0)
54 , m_shouldCheckRange(false)
55 , m_isRequired(true)
56 {
57 }
58
59 bool
60 parseFromConfigSection(const ConfigSection& section)
61 {
62 try {
63 T value = section.get<T>(m_key);
64
65 if (!isValidValue(value)) {
66 return false;
67 }
68
69 m_setterCallback(value);
70 return true;
71 }
72 catch (const std::exception& ex) {
73
74 if (m_isRequired) {
75 std::cerr << ex.what() << std::endl;
76 std::cerr << "Missing required configuration variable" << std::endl;
77 return false;
78 }
79 else {
80 m_setterCallback(m_defaultValue);
81 return true;
82 }
83 }
84
85 return false;
86 }
87
88 void
89 setMinAndMaxValue(T min, T max)
90 {
91 m_minValue = min;
92 m_maxValue = max;
93 m_shouldCheckRange = true;
94 }
95
96 void
97 setOptional(T defaultValue)
98 {
99 m_isRequired = false;
100 m_defaultValue = defaultValue;
101 }
102
103private:
104 void
105 printOutOfRangeError(T value)
106 {
107 std::cerr << "Invalid value for " << m_key << ": "
108 << value << ". "
109 << "Valid values: "
110 << m_minValue << " - "
111 << m_maxValue << std::endl;
112 }
113
114 bool
115 isValidValue(T value)
116 {
117 if (!m_shouldCheckRange) {
118 return true;
119 }
120 else if (value < m_minValue || value > m_maxValue)
121 {
122 printOutOfRangeError(value);
123 return false;
124 }
125
126 return true;
127 }
128
129private:
130 const std::string m_key;
131 const ConfParameterCallback m_setterCallback;
132
133 T m_defaultValue;
134 T m_minValue;
135 T m_maxValue;
136
137 bool m_shouldCheckRange;
138 bool m_isRequired;
139};
140
142 : m_confFileName(confParam.getConfFileName())
143 , m_confParam(confParam)
144{
145}
146
147bool
149{
150 std::ifstream inputFile(m_confFileName);
151 if (!inputFile.is_open()) {
152 std::cerr << "Failed to read configuration file: " << m_confFileName << std::endl;
153 return false;
154 }
155
156 if (!load(inputFile)) {
157 return false;
158 }
159
160 m_confParam.buildRouterAndSyncUserPrefix();
161 m_confParam.writeLog();
162 return true;
163}
164
165bool
166ConfFileProcessor::load(std::istream& input)
167{
168 ConfigSection pt;
169 try {
170 boost::property_tree::read_info(input, pt);
171 }
172 catch (const boost::property_tree::ptree_error& e) {
173 std::cerr << "Failed to parse configuration file '" << m_confFileName
174 << "': " << e.what() << std::endl;
175 return false;
176 }
177
178 for (const auto& tn : pt) {
179 if (!processSection(tn.first, tn.second)) {
180 return false;
181 }
182 }
183 return true;
184}
185
186bool
187ConfFileProcessor::processSection(const std::string& sectionName, const ConfigSection& section)
188{
189 bool ret = true;
190 if (sectionName == "general") {
191 ret = processConfSectionGeneral(section);
192 }
193 else if (sectionName == "neighbors") {
194 ret = processConfSectionNeighbors(section);
195 }
196 else if (sectionName == "hyperbolic") {
197 ret = processConfSectionHyperbolic(section);
198 }
199 else if (sectionName == "fib") {
200 ret = processConfSectionFib(section);
201 }
202 else if (sectionName == "advertising") {
203 ret = processConfSectionAdvertising(section);
204 }
205 else if (sectionName == "security") {
206 ret = processConfSectionSecurity(section);
207 }
208 else {
209 std::cerr << "Unknown configuration section: " << sectionName << std::endl;
210 }
211 return ret;
212}
213
214bool
215ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
216{
217 // sync-protocol
218 std::string syncProtocol = section.get<std::string>("sync-protocol", "psync");
219 if (syncProtocol == "chronosync") {
220#ifdef HAVE_CHRONOSYNC
222#else
223 std::cerr << "NLSR was compiled without ChronoSync support!\n";
224 return false;
225#endif
226 }
227 else if (syncProtocol == "psync") {
228#ifdef HAVE_PSYNC
230#else
231 std::cerr << "NLSR was compiled without PSync support!\n";
232 return false;
233#endif
234 }
235 else if (syncProtocol == "svs") {
236#ifdef HAVE_SVS
238#else
239 std::cerr << "NLSR was compiled without SVS support!\n";
240 return false;
241#endif
242 }
243 else {
244 std::cerr << "Sync protocol '" << syncProtocol << "' is not supported!\n"
245 << "Use 'chronosync' or 'psync' or 'svs'\n";
246 return false;
247 }
248
249 try {
250 std::string network = section.get<std::string>("network");
251 std::string site = section.get<std::string>("site");
252 std::string router = section.get<std::string>("router");
253 ndn::Name networkName(network);
254 if (!networkName.empty()) {
255 m_confParam.setNetwork(networkName);
256 }
257 else {
258 std::cerr << "Network can not be null or empty or in bad URI format" << std::endl;
259 return false;
260 }
261 ndn::Name siteName(site);
262 if (!siteName.empty()) {
263 m_confParam.setSiteName(siteName);
264 }
265 else {
266 std::cerr << "Site can not be null or empty or in bad URI format" << std::endl;
267 return false;
268 }
269 ndn::Name routerName(router);
270 if (!routerName.empty()) {
271 m_confParam.setRouterName(routerName);
272 }
273 else {
274 std::cerr << "Router name can not be null or empty or in bad URI format" << std::endl;
275 return false;
276 }
277 }
278 catch (const std::exception& ex) {
279 std::cerr << ex.what() << std::endl;
280 return false;
281 }
282
283 // lsa-refresh-time
284 uint32_t lsaRefreshTime = section.get<uint32_t>("lsa-refresh-time", LSA_REFRESH_TIME_DEFAULT);
285
286 if (lsaRefreshTime >= LSA_REFRESH_TIME_MIN && lsaRefreshTime <= LSA_REFRESH_TIME_MAX) {
287 m_confParam.setLsaRefreshTime(lsaRefreshTime);
288 }
289 else {
290 std::cerr << "Invalid value for lsa-refresh-time. "
291 << "Allowed range: " << LSA_REFRESH_TIME_MIN
292 << "-" << LSA_REFRESH_TIME_MAX << std::endl;
293 return false;
294 }
295
296 // router-dead-interval
297 uint32_t routerDeadInterval = section.get<uint32_t>("router-dead-interval", 2 * lsaRefreshTime);
298
299 if (routerDeadInterval > m_confParam.getLsaRefreshTime()) {
300 m_confParam.setRouterDeadInterval(routerDeadInterval);
301 }
302 else {
303 std::cerr << "Value of router-dead-interval must be larger than lsa-refresh-time" << std::endl;
304 return false;
305 }
306
307 // lsa-interest-lifetime
308 int lifetime = section.get<int>("lsa-interest-lifetime", LSA_INTEREST_LIFETIME_DEFAULT);
309
310 if (lifetime >= LSA_INTEREST_LIFETIME_MIN && lifetime <= LSA_INTEREST_LIFETIME_MAX) {
311 m_confParam.setLsaInterestLifetime(ndn::time::seconds(lifetime));
312 }
313 else {
314 std::cerr << "Invalid value for lsa-interest-timeout. "
315 << "Allowed range: " << LSA_INTEREST_LIFETIME_MIN
316 << "-" << LSA_INTEREST_LIFETIME_MAX << std::endl;
317 return false;
318 }
319
320 // sync-interest-lifetime
321 uint32_t syncInterestLifetime = section.get<uint32_t>("sync-interest-lifetime",
323 if (syncInterestLifetime >= SYNC_INTEREST_LIFETIME_MIN &&
324 syncInterestLifetime <= SYNC_INTEREST_LIFETIME_MAX) {
325 m_confParam.setSyncInterestLifetime(syncInterestLifetime);
326 }
327 else {
328 std::cerr << "Invalid value for sync-interest-lifetime. "
329 << "Allowed range: " << SYNC_INTEREST_LIFETIME_MIN
330 << "-" << SYNC_INTEREST_LIFETIME_MAX << std::endl;
331 return false;
332 }
333
334 // state-dir
335 try {
336 fs::path stateDir(section.get<std::string>("state-dir"));
337 if (fs::exists(stateDir)) {
338 if (fs::is_directory(stateDir)) {
339 // copying nlsr.conf file to a user-defined directory for possible modification
340 auto conFileDynamic = stateDir / "nlsr.conf";
341 if (m_confFileName == conFileDynamic.string()) {
342 std::cerr << "Please use nlsr.conf stored at another location "
343 << "or change the state-dir in the configuration." << std::endl;
344 std::cerr << "The file at " << conFileDynamic <<
345 " is used as dynamic file for saving NLSR runtime changes." << std::endl;
346 std::cerr << "The dynamic file can be used for next run "
347 << "after copying to another location." << std::endl;
348 return false;
349 }
350
351 m_confParam.setConfFileNameDynamic(conFileDynamic.string());
352 try {
353 fs::copy_file(m_confFileName, conFileDynamic, fs::copy_options::overwrite_existing);
354 }
355 catch (const fs::filesystem_error& e) {
356 std::cerr << "Error copying conf file to state-dir: " << e.what() << std::endl;
357 return false;
358 }
359
360 auto testFilePath = stateDir / "test.seq";
361 std::ofstream testFile(testFilePath);
362 if (testFile) {
363 m_confParam.setStateFileDir(stateDir.string());
364 }
365 else {
366 std::cerr << "NLSR does not have read/write permission on state-dir" << std::endl;
367 return false;
368 }
369 testFile.close();
370 fs::remove(testFilePath);
371 }
372 else {
373 std::cerr << "Provided state-dir " << stateDir << " is not a directory" << std::endl;
374 return false;
375 }
376 }
377 else {
378 std::cerr << "Provided state-dir " << stateDir << " does not exist" << std::endl;
379 return false;
380 }
381 }
382 catch (const std::exception& ex) {
383 std::cerr << "You must configure state-dir" << std::endl;
384 std::cerr << ex.what() << std::endl;
385 return false;
386 }
387
388 return true;
389}
390
391bool
392ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
393{
394 // hello-retries
395 int retrials = section.get<int>("hello-retries", HELLO_RETRIES_DEFAULT);
396
397 if (retrials >= HELLO_RETRIES_MIN && retrials <= HELLO_RETRIES_MAX) {
398 m_confParam.setInterestRetryNumber(retrials);
399 }
400 else {
401 std::cerr << "Invalid value for hello-retries. "
402 << "Allowed range: " << HELLO_RETRIES_MIN << "-" << HELLO_RETRIES_MAX << std::endl;
403 return false;
404 }
405
406 // hello-timeout
407 uint32_t timeOut = section.get<uint32_t>("hello-timeout", HELLO_TIMEOUT_DEFAULT);
408
409 if (timeOut >= HELLO_TIMEOUT_MIN && timeOut <= HELLO_TIMEOUT_MAX) {
410 m_confParam.setInterestResendTime(timeOut);
411 }
412 else {
413 std::cerr << "Invalid value for hello-timeout. "
414 << "Allowed range: " << HELLO_TIMEOUT_MIN << "-" << HELLO_TIMEOUT_MAX << std::endl;
415 return false;
416 }
417
418 // hello-interval
419 uint32_t interval = section.get<uint32_t>("hello-interval", HELLO_INTERVAL_DEFAULT);
420
421 if (interval >= HELLO_INTERVAL_MIN && interval <= HELLO_INTERVAL_MAX) {
422 m_confParam.setInfoInterestInterval(interval);
423 }
424 else {
425 std::cerr << "Invalid value for hello-interval. "
426 << "Allowed range: " << HELLO_INTERVAL_MIN << "-" << HELLO_INTERVAL_MAX << std::endl;
427 return false;
428 }
429
430 // Event intervals
431 // adj-lsa-build-interval
432 ConfigurationVariable<uint32_t> adjLsaBuildInterval("adj-lsa-build-interval",
434 &m_confParam, _1));
435 adjLsaBuildInterval.setMinAndMaxValue(ADJ_LSA_BUILD_INTERVAL_MIN, ADJ_LSA_BUILD_INTERVAL_MAX);
436 adjLsaBuildInterval.setOptional(ADJ_LSA_BUILD_INTERVAL_DEFAULT);
437
438 if (!adjLsaBuildInterval.parseFromConfigSection(section)) {
439 return false;
440 }
441 // Set the retry count for fetching the FaceStatus dataset
442 ConfigurationVariable<uint32_t> faceDatasetFetchTries("face-dataset-fetch-tries",
444 &m_confParam, _1));
445
446 faceDatasetFetchTries.setMinAndMaxValue(FACE_DATASET_FETCH_TRIES_MIN,
448 faceDatasetFetchTries.setOptional(FACE_DATASET_FETCH_TRIES_DEFAULT);
449
450 if (!faceDatasetFetchTries.parseFromConfigSection(section)) {
451 return false;
452 }
453
454 // Set the interval between FaceStatus dataset fetch attempts.
455 ConfigurationVariable<uint32_t> faceDatasetFetchInterval("face-dataset-fetch-interval",
457 &m_confParam, _1));
458
459 faceDatasetFetchInterval.setMinAndMaxValue(FACE_DATASET_FETCH_INTERVAL_MIN,
461 faceDatasetFetchInterval.setOptional(FACE_DATASET_FETCH_INTERVAL_DEFAULT);
462
463 if (!faceDatasetFetchInterval.parseFromConfigSection(section)) {
464 return false;
465 }
466
467 for (const auto& tn : section) {
468 if (tn.first == "neighbor") {
469 try {
470 ConfigSection CommandAttriTree = tn.second;
471 std::string name = CommandAttriTree.get<std::string>("name");
472 std::string uriString = CommandAttriTree.get<std::string>("face-uri");
473
474 ndn::FaceUri faceUri;
475 if (!faceUri.parse(uriString)) {
476 std::cerr << "face-uri parsing failed" << std::endl;
477 return false;
478 }
479
480 bool failedToCanonize = false;
481 faceUri.canonize([&faceUri] (const auto& canonicalUri) {
482 faceUri = canonicalUri;
483 },
484 [&faceUri, &failedToCanonize] (const auto& reason) {
485 failedToCanonize = true;
486 std::cerr << "Could not canonize URI: '" << faceUri
487 << "' because: " << reason << std::endl;
488 },
489 m_io,
491 m_io.run();
492 m_io.restart();
493
494 if (failedToCanonize) {
495 return false;
496 }
497
498 double linkCost = CommandAttriTree.get<double>("link-cost", Adjacent::DEFAULT_LINK_COST);
499 ndn::Name neighborName(name);
500 if (!neighborName.empty()) {
501 Adjacent adj(name, faceUri, linkCost, Adjacent::STATUS_INACTIVE, 0, 0);
502 m_confParam.getAdjacencyList().insert(adj);
503 }
504 else {
505 std::cerr << "No neighbor name found or bad URI format! Expected:\n"
506 << " name [neighbor router name]\n face-uri [face uri]\n link-cost [link cost] OPTIONAL" << std::endl;
507 }
508 }
509 catch (const std::exception& ex) {
510 std::cerr << ex.what() << std::endl;
511 return false;
512 }
513 }
514 }
515 return true;
516}
517
518bool
519ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
520{
521 // state
522 std::string state = section.get<std::string>("state", "off");
523
524 if (boost::iequals(state, "off")) {
526 }
527 else if (boost::iequals(state, "on")) {
529 }
530 else if (boost::iequals(state, "dry-run")) {
532 }
533 else {
534 std::cerr << "Invalid setting for hyperbolic state. "
535 << "Allowed values: off, on, dry-run" << std::endl;
536 return false;
537 }
538
539 try {
540 // Radius and angle(s) are mandatory configuration parameters in hyperbolic section.
541 // Even if router can have hyperbolic routing calculation off but other router
542 // in the network may use hyperbolic routing calculation for FIB generation.
543 // So each router need to advertise its hyperbolic coordinates in the network
544 double radius = section.get<double>("radius");
545 std::string angleString = section.get<std::string>("angle");
546
547 std::stringstream ss(angleString);
548 std::vector<double> angles;
549
550 double angle;
551
552 while (ss >> angle) {
553 angles.push_back(angle);
554 if (ss.peek() == ',' || ss.peek() == ' ') {
555 ss.ignore();
556 }
557 }
558
559 if (!m_confParam.setCorR(radius)) {
560 return false;
561 }
562 m_confParam.setCorTheta(angles);
563 }
564 catch (const std::exception& ex) {
565 std::cerr << ex.what() << std::endl;
566 if (state == "on" || state == "dry-run") {
567 return false;
568 }
569 }
570
571 return true;
572}
573
574bool
575ConfFileProcessor::processConfSectionFib(const ConfigSection& section)
576{
577 // max-faces-per-prefix
578 int maxFacesPerPrefix = section.get<int>("max-faces-per-prefix", MAX_FACES_PER_PREFIX_DEFAULT);
579
580 if (maxFacesPerPrefix >= MAX_FACES_PER_PREFIX_MIN &&
581 maxFacesPerPrefix <= MAX_FACES_PER_PREFIX_MAX) {
582 m_confParam.setMaxFacesPerPrefix(maxFacesPerPrefix);
583 }
584 else {
585 std::cerr << "Invalid value for max-faces-per-prefix. "
586 << "Allowed range: " << MAX_FACES_PER_PREFIX_MIN
587 << "-" << MAX_FACES_PER_PREFIX_MAX << std::endl;
588 return false;
589 }
590
591 // routing-calc-interval
592 ConfigurationVariable<uint32_t> routingCalcInterval("routing-calc-interval",
594 &m_confParam, _1));
595 routingCalcInterval.setMinAndMaxValue(ROUTING_CALC_INTERVAL_MIN, ROUTING_CALC_INTERVAL_MAX);
596 routingCalcInterval.setOptional(ROUTING_CALC_INTERVAL_DEFAULT);
597
598 if (!routingCalcInterval.parseFromConfigSection(section)) {
599 return false;
600 }
601
602 return true;
603}
604
605bool
606ConfFileProcessor::processConfSectionAdvertising(const ConfigSection& section)
607{
608 for (const auto& tn : section) {
609 try {
610 ndn::Name namePrefix(tn.first.data());
611 if (!namePrefix.empty()) {
612 m_confParam.getNamePrefixList().insert(namePrefix, "", tn.second.get_value<uint64_t>());
613 }
614 else {
615 std::cerr << " Wrong format or bad URI!\nExpected [name in ndn URI format] [cost],"
616 << " got prefix: " << tn.first.data() << " cost:" << tn.second.data() << std::endl;
617 return false;
618 }
619 }
620 catch (const boost::property_tree::ptree_bad_data& ex) {
621 //Catches errors from get_value above
622 std::cerr << "Invalid cost format; only integers are allowed" << std::endl;
623 return false;
624 }
625 catch (const std::exception& ex) {
626 std::cerr << ex.what() << std::endl;
627 return false;
628 }
629 }
630 return true;
631}
632
633bool
634ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
635{
636 auto it = section.begin();
637
638 if (it == section.end() || it->first != "validator") {
639 std::cerr << "Error: Expected validator section!" << std::endl;
640 return false;
641 }
642
643 m_confParam.getValidator().load(it->second, m_confFileName);
644
645 it++;
646 if (it != section.end() && it->first == "prefix-update-validator") {
647 m_confParam.getPrefixUpdateValidator().load(it->second, m_confFileName);
648
649 it++;
650 for (; it != section.end(); it++) {
651 if (it->first != "cert-to-publish") {
652 std::cerr << "Error: Expected cert-to-publish!" << std::endl;
653 return false;
654 }
655
656 fs::path certPath = fs::canonical(fs::path(m_confFileName).parent_path() / it->second.data());
657 std::ifstream ifs(certPath);
658
659 ndn::security::Certificate idCert;
660 try {
661 idCert = ndn::io::loadTlv<ndn::security::Certificate>(ifs);
662 }
663 catch (const std::exception& e) {
664 std::cerr << "Error: Cannot load cert-to-publish " << certPath << ": " << e.what() << std::endl;
665 return false;
666 }
667
668 m_confParam.addCertPath(certPath.string());
669 m_confParam.loadCertToValidator(idCert);
670 }
671 }
672
673 return true;
674}
675
676} // namespace nlsr
bool insert(const Adjacent &adjacent)
static constexpr double DEFAULT_LINK_COST
Definition adjacent.hpp:186
ConfFileProcessor(ConfParameter &confParam)
bool processConfFile()
Load and parse the configuration file, then populate NLSR.
A class to house all the configuration parameters for NLSR.
void setHyperbolicState(HyperbolicState ihc)
void setRouterName(const ndn::Name &routerName)
void setSiteName(const ndn::Name &siteName)
void setInterestRetryNumber(uint32_t irn)
void setMaxFacesPerPrefix(uint32_t mfpp)
void setRouterDeadInterval(uint32_t rdt)
void writeLog()
Dump the current state of all attributes to the log.
void setSyncProtocol(SyncProtocol syncProtocol)
void setStateFileDir(const std::string &ssfd)
void setLsaRefreshTime(uint32_t lrt)
void setInterestResendTime(uint32_t irt)
void loadCertToValidator(const ndn::security::Certificate &cert)
uint32_t getLsaRefreshTime() const
NamePrefixList & getNamePrefixList()
void setAdjLsaBuildInterval(uint32_t interval)
void setConfFileNameDynamic(const std::string &confFileDynamic)
void setInfoInterestInterval(uint32_t iii)
void addCertPath(const std::string &certPath)
void setFaceDatasetFetchTries(uint32_t count)
void setLsaInterestLifetime(const ndn::time::seconds &lifetime)
void setSyncInterestLifetime(uint32_t syncInterestLifetime)
void setCorTheta(const std::vector< double > &ct)
bool setCorR(double cr)
void setFaceDatasetFetchInterval(uint32_t interval)
AdjacencyList & getAdjacencyList()
ndn::security::ValidatorConfig & getPrefixUpdateValidator()
void setNetwork(const ndn::Name &networkName)
ndn::security::ValidatorConfig & getValidator()
void setRoutingCalcInterval(uint32_t interval)
bool insert(const ndn::Name &name, const std::string &source="", double cost=0)
Inserts name and source combination.
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California.
@ FACE_DATASET_FETCH_TRIES_DEFAULT
@ FACE_DATASET_FETCH_TRIES_MIN
@ FACE_DATASET_FETCH_TRIES_MAX
@ LSA_REFRESH_TIME_MIN
@ LSA_REFRESH_TIME_MAX
@ LSA_REFRESH_TIME_DEFAULT
@ HELLO_RETRIES_MAX
@ HELLO_RETRIES_DEFAULT
@ HELLO_RETRIES_MIN
@ ROUTING_CALC_INTERVAL_DEFAULT
@ ROUTING_CALC_INTERVAL_MIN
@ ROUTING_CALC_INTERVAL_MAX
@ MAX_FACES_PER_PREFIX_MIN
@ MAX_FACES_PER_PREFIX_DEFAULT
@ MAX_FACES_PER_PREFIX_MAX
@ FACE_DATASET_FETCH_INTERVAL_DEFAULT
@ FACE_DATASET_FETCH_INTERVAL_MIN
@ FACE_DATASET_FETCH_INTERVAL_MAX
constexpr ndn::time::seconds TIME_ALLOWED_FOR_CANONIZATION
Definition common.hpp:40
@ ADJ_LSA_BUILD_INTERVAL_DEFAULT
@ ADJ_LSA_BUILD_INTERVAL_MIN
@ ADJ_LSA_BUILD_INTERVAL_MAX
@ HYPERBOLIC_STATE_ON
@ HYPERBOLIC_STATE_DRY_RUN
@ HYPERBOLIC_STATE_OFF
@ LSA_INTEREST_LIFETIME_MAX
@ LSA_INTEREST_LIFETIME_DEFAULT
@ LSA_INTEREST_LIFETIME_MIN
boost::property_tree::ptree ConfigSection
@ HELLO_INTERVAL_MIN
@ HELLO_INTERVAL_DEFAULT
@ HELLO_INTERVAL_MAX
@ HELLO_TIMEOUT_DEFAULT
@ HELLO_TIMEOUT_MIN
@ HELLO_TIMEOUT_MAX
@ SYNC_INTEREST_LIFETIME_MIN
@ SYNC_INTEREST_LIFETIME_MAX
@ SYNC_INTEREST_LIFETIME_DEFAULT