blob: ec1718bd627521f4f20da71a3a525c223a7ae8a9 [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento4b9d30f2020-05-01 02:48:34 -04002/*
Davide Pesaventod90338d2021-01-07 17:50:05 -05003 * Copyright (c) 2014-2021, The University of Memphis,
Vince Lehmanc2e51f62015-01-20 15:03:11 -06004 * Regents of the University of California,
5 * Arizona Board of Regents.
akmhoque3d06e792014-05-27 16:23:20 -05006 *
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/>.
Alexander Afanasyev0ad01f32020-06-03 14:12:58 -040020 */
Vince Lehmanc2e51f62015-01-20 15:03:11 -060021
Ashlesh Gawande3909aa12017-07-28 16:01:35 -050022#include "conf-file-processor.hpp"
23#include "adjacent.hpp"
24#include "utility/name-helper.hpp"
25#include "update/prefix-update-processor.hpp"
26
Alexander Afanasyevb669f9c2014-11-14 12:41:54 -080027#include <ndn-cxx/name.hpp>
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050028#include <ndn-cxx/net/face-uri.hpp>
Alexander Afanasyevb669f9c2014-11-14 12:41:54 -080029
Davide Pesavento22520e62021-06-08 22:16:52 -040030#include <boost/filesystem.hpp>
31#include <boost/property_tree/info_parser.hpp>
32
Nick Gordone98480b2017-05-24 11:23:03 -050033#include <fstream>
Davide Pesavento22520e62021-06-08 22:16:52 -040034#include <iostream>
35
36namespace bf = boost::filesystem;
akmhoque53353462014-04-22 08:43:45 -050037
akmhoque53353462014-04-22 08:43:45 -050038namespace nlsr {
39
Vince Lehman7b616582014-10-17 16:25:39 -050040template <class T>
41class ConfigurationVariable
42{
43public:
dmcoomes9f936662017-03-02 10:33:09 -060044 typedef std::function<void(T)> ConfParameterCallback;
Vince Lehman7b616582014-10-17 16:25:39 -050045
46 ConfigurationVariable(const std::string& key, const ConfParameterCallback& setter)
47 : m_key(key)
48 , m_setterCallback(setter)
49 , m_minValue(0)
50 , m_maxValue(0)
51 , m_shouldCheckRange(false)
52 , m_isRequired(true)
53 {
54 }
55
56 bool
57 parseFromConfigSection(const ConfigSection& section)
58 {
59 try {
60 T value = section.get<T>(m_key);
61
62 if (!isValidValue(value)) {
63 return false;
64 }
65
66 m_setterCallback(value);
67 return true;
68 }
69 catch (const std::exception& ex) {
70
71 if (m_isRequired) {
72 std::cerr << ex.what() << std::endl;
73 std::cerr << "Missing required configuration variable" << std::endl;
74 return false;
75 }
76 else {
77 m_setterCallback(m_defaultValue);
78 return true;
79 }
80 }
81
82 return false;
83 }
84
85 void
86 setMinAndMaxValue(T min, T max)
87 {
88 m_minValue = min;
89 m_maxValue = max;
90 m_shouldCheckRange = true;
91 }
92
93 void
94 setOptional(T defaultValue)
95 {
96 m_isRequired = false;
97 m_defaultValue = defaultValue;
98 }
99
100private:
101 void
102 printOutOfRangeError(T value)
103 {
104 std::cerr << "Invalid value for " << m_key << ": "
105 << value << ". "
106 << "Valid values: "
107 << m_minValue << " - "
108 << m_maxValue << std::endl;
109 }
110
111 bool
112 isValidValue(T value)
113 {
114 if (!m_shouldCheckRange) {
115 return true;
116 }
117 else if (value < m_minValue || value > m_maxValue)
118 {
119 printOutOfRangeError(value);
120 return false;
121 }
122
123 return true;
124 }
125
126private:
127 const std::string m_key;
128 const ConfParameterCallback m_setterCallback;
129 T m_defaultValue;
130
131 T m_minValue;
132 T m_maxValue;
133
134 bool m_shouldCheckRange;
135 bool m_isRequired;
136};
137
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600138ConfFileProcessor::ConfFileProcessor(ConfParameter& confParam)
139 : m_confFileName(confParam.getConfFileName())
140 , m_confParam(confParam)
141{
142}
143
akmhoque157b0a42014-05-13 00:26:37 -0500144bool
akmhoqueb6450b12014-04-24 00:01:03 -0500145ConfFileProcessor::processConfFile()
akmhoque53353462014-04-22 08:43:45 -0500146{
akmhoque157b0a42014-05-13 00:26:37 -0500147 bool ret = true;
Nick Gordone98480b2017-05-24 11:23:03 -0500148 std::ifstream inputFile;
akmhoque157b0a42014-05-13 00:26:37 -0500149 inputFile.open(m_confFileName.c_str());
150 if (!inputFile.is_open()) {
Nick Gordone98480b2017-05-24 11:23:03 -0500151 std::string msg = "Failed to read configuration file: ";
akmhoque157b0a42014-05-13 00:26:37 -0500152 msg += m_confFileName;
Nick Gordone98480b2017-05-24 11:23:03 -0500153 std::cerr << msg << std::endl;
akmhoquead5fe952014-06-26 13:34:12 -0500154 return false;
akmhoque157b0a42014-05-13 00:26:37 -0500155 }
156 ret = load(inputFile);
157 inputFile.close();
Saurab Dulal427e0122019-11-28 11:58:02 -0600158
159 if (ret) {
160 m_confParam.buildRouterAndSyncUserPrefix();
161 m_confParam.writeLog();
162 }
163
akmhoque157b0a42014-05-13 00:26:37 -0500164 return ret;
165}
166
167bool
Nick Gordone98480b2017-05-24 11:23:03 -0500168ConfFileProcessor::load(std::istream& input)
akmhoque157b0a42014-05-13 00:26:37 -0500169{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700170 ConfigSection pt;
akmhoque157b0a42014-05-13 00:26:37 -0500171 try {
172 boost::property_tree::read_info(input, pt);
173 }
174 catch (const boost::property_tree::info_parser_error& error) {
Nick Gordone98480b2017-05-24 11:23:03 -0500175 std::stringstream msg;
akmhoque157b0a42014-05-13 00:26:37 -0500176 std::cerr << "Failed to parse configuration file " << std::endl;
177 std::cerr << m_confFileName << std::endl;
178 return false;
179 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700180
Ashlesh Gawande328fc112019-12-12 17:06:44 -0600181 for (const auto& tn : pt) {
182 if (!processSection(tn.first, tn.second)) {
183 return false;
akmhoque157b0a42014-05-13 00:26:37 -0500184 }
185 }
Ashlesh Gawande328fc112019-12-12 17:06:44 -0600186 return true;
akmhoque157b0a42014-05-13 00:26:37 -0500187}
188
189bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700190ConfFileProcessor::processSection(const std::string& sectionName, const ConfigSection& section)
akmhoque157b0a42014-05-13 00:26:37 -0500191{
192 bool ret = true;
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700193 if (sectionName == "general")
akmhoque53353462014-04-22 08:43:45 -0500194 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700195 ret = processConfSectionGeneral(section);
akmhoque157b0a42014-05-13 00:26:37 -0500196 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700197 else if (sectionName == "neighbors")
akmhoque157b0a42014-05-13 00:26:37 -0500198 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700199 ret = processConfSectionNeighbors(section);
akmhoque157b0a42014-05-13 00:26:37 -0500200 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700201 else if (sectionName == "hyperbolic")
akmhoque157b0a42014-05-13 00:26:37 -0500202 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700203 ret = processConfSectionHyperbolic(section);
akmhoque157b0a42014-05-13 00:26:37 -0500204 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700205 else if (sectionName == "fib")
akmhoque157b0a42014-05-13 00:26:37 -0500206 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700207 ret = processConfSectionFib(section);
akmhoque157b0a42014-05-13 00:26:37 -0500208 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700209 else if (sectionName == "advertising")
akmhoque157b0a42014-05-13 00:26:37 -0500210 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700211 ret = processConfSectionAdvertising(section);
akmhoque157b0a42014-05-13 00:26:37 -0500212 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700213 else if (sectionName == "security")
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700214 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700215 ret = processConfSectionSecurity(section);
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700216 }
akmhoque157b0a42014-05-13 00:26:37 -0500217 else
218 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700219 std::cerr << "Wrong configuration section: " << sectionName << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500220 }
221 return ret;
222}
223
224bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700225ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
akmhoque157b0a42014-05-13 00:26:37 -0500226{
227 try {
Nick Gordone98480b2017-05-24 11:23:03 -0500228 std::string network = section.get<std::string>("network");
229 std::string site = section.get<std::string>("site");
230 std::string router = section.get<std::string>("router");
akmhoque157b0a42014-05-13 00:26:37 -0500231 ndn::Name networkName(network);
232 if (!networkName.empty()) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600233 m_confParam.setNetwork(networkName);
akmhoque157b0a42014-05-13 00:26:37 -0500234 }
235 else {
Nick Gordone98480b2017-05-24 11:23:03 -0500236 std::cerr << " Network can not be null or empty or in bad URI format :(!" << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500237 return false;
238 }
239 ndn::Name siteName(site);
240 if (!siteName.empty()) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600241 m_confParam.setSiteName(siteName);
akmhoque157b0a42014-05-13 00:26:37 -0500242 }
243 else {
Nick Gordone98480b2017-05-24 11:23:03 -0500244 std::cerr << "Site can not be null or empty or in bad URI format:( !" << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500245 return false;
246 }
247 ndn::Name routerName(router);
248 if (!routerName.empty()) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600249 m_confParam.setRouterName(routerName);
akmhoque157b0a42014-05-13 00:26:37 -0500250 }
251 else {
Nick Gordone98480b2017-05-24 11:23:03 -0500252 std::cerr << " Router name can not be null or empty or in bad URI format:( !" << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500253 return false;
254 }
255 }
256 catch (const std::exception& ex) {
Nick Gordone98480b2017-05-24 11:23:03 -0500257 std::cerr << ex.what() << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500258 return false;
259 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700260
alvya2228c62014-12-09 10:25:11 -0600261 // lsa-refresh-time
alvy5a454952014-12-15 12:49:54 -0600262 uint32_t lsaRefreshTime = section.get<uint32_t>("lsa-refresh-time", LSA_REFRESH_TIME_DEFAULT);
alvya2228c62014-12-09 10:25:11 -0600263
264 if (lsaRefreshTime >= LSA_REFRESH_TIME_MIN && lsaRefreshTime <= LSA_REFRESH_TIME_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600265 m_confParam.setLsaRefreshTime(lsaRefreshTime);
akmhoque157b0a42014-05-13 00:26:37 -0500266 }
alvya2228c62014-12-09 10:25:11 -0600267 else {
268 std::cerr << "Wrong value for lsa-refresh-time ";
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500269 std::cerr << "Allowed value: " << LSA_REFRESH_TIME_MIN << "-";
alvya2228c62014-12-09 10:25:11 -0600270 std::cerr << LSA_REFRESH_TIME_MAX << std::endl;
271
272 return false;
273 }
274
275 // router-dead-interval
alvy5a454952014-12-15 12:49:54 -0600276 uint32_t routerDeadInterval = section.get<uint32_t>("router-dead-interval", (2*lsaRefreshTime));
alvya2228c62014-12-09 10:25:11 -0600277
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600278 if (routerDeadInterval > m_confParam.getLsaRefreshTime()) {
279 m_confParam.setRouterDeadInterval(routerDeadInterval);
alvya2228c62014-12-09 10:25:11 -0600280 }
281 else {
282 std::cerr << "Value of router-dead-interval must be larger than lsa-refresh-time" << std::endl;
283 return false;
284 }
285
286 // lsa-interest-lifetime
287 int lifetime = section.get<int>("lsa-interest-lifetime", LSA_INTEREST_LIFETIME_DEFAULT);
288
289 if (lifetime >= LSA_INTEREST_LIFETIME_MIN && lifetime <= LSA_INTEREST_LIFETIME_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600290 m_confParam.setLsaInterestLifetime(ndn::time::seconds(lifetime));
alvya2228c62014-12-09 10:25:11 -0600291 }
292 else {
293 std::cerr << "Wrong value for lsa-interest-timeout. "
294 << "Allowed value:" << LSA_INTEREST_LIFETIME_MIN << "-"
295 << LSA_INTEREST_LIFETIME_MAX << std::endl;
296
akmhoque157b0a42014-05-13 00:26:37 -0500297 return false;
298 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700299
Ashlesh Gawande32ec3fd2018-07-18 13:42:32 -0500300 // sync-protocol
Ashlesh Gawande30d96e42021-03-21 19:15:33 -0700301 std::string syncProtocol = section.get<std::string>("sync-protocol", "psync");
Ashlesh Gawande32ec3fd2018-07-18 13:42:32 -0500302 if (syncProtocol == "chronosync") {
Ashlesh Gawande30d96e42021-03-21 19:15:33 -0700303#ifdef HAVE_CHRONOSYNC
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600304 m_confParam.setSyncProtocol(SYNC_PROTOCOL_CHRONOSYNC);
Ashlesh Gawande30d96e42021-03-21 19:15:33 -0700305#else
306 std::cerr << "NLSR was compiled without Chronosync support!" << std::endl;
307 std::cerr << "Only PSync support is currently available ('sync-protocol psync')" << std::endl;
308 return false;
309#endif
Ashlesh Gawande32ec3fd2018-07-18 13:42:32 -0500310 }
311 else if (syncProtocol == "psync") {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600312 m_confParam.setSyncProtocol(SYNC_PROTOCOL_PSYNC);
Ashlesh Gawande32ec3fd2018-07-18 13:42:32 -0500313 }
314 else {
315 std::cerr << "Sync protocol " << syncProtocol << " is not supported!"
316 << "Use chronosync or psync" << std::endl;
317 return false;
318 }
319
320 // sync-interest-lifetime
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600321 uint32_t syncInterestLifetime = section.get<uint32_t>("sync-interest-lifetime",
322 SYNC_INTEREST_LIFETIME_DEFAULT);
Ashlesh Gawandef7da9c52018-02-06 17:36:46 -0600323 if (syncInterestLifetime >= SYNC_INTEREST_LIFETIME_MIN &&
324 syncInterestLifetime <= SYNC_INTEREST_LIFETIME_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600325 m_confParam.setSyncInterestLifetime(syncInterestLifetime);
Ashlesh Gawandef7da9c52018-02-06 17:36:46 -0600326 }
327 else {
328 std::cerr << "Wrong value for sync-interest-lifetime. "
329 << "Allowed value:" << SYNC_INTEREST_LIFETIME_MIN << "-"
330 << SYNC_INTEREST_LIFETIME_MAX << std::endl;
331
332 return false;
333 }
334
akmhoque674b0b12014-05-20 14:33:28 -0500335 try {
dulalsaurab82a34c22019-02-04 17:31:21 +0000336 std::string stateDir = section.get<std::string>("state-dir");
Ashlesh Gawande328fc112019-12-12 17:06:44 -0600337 if (bf::exists(stateDir)) {
338 if (bf::is_directory(stateDir)) {
Davide Pesavento22520e62021-06-08 22:16:52 -0400339 // copying nlsr.conf file to a user-defined directory for possible modification
340 std::string conFileDynamic = (bf::path(stateDir) / "nlsr.conf").string();
Ashlesh Gawande328fc112019-12-12 17:06:44 -0600341
342 if (m_confFileName == conFileDynamic) {
343 std::cerr << "Please use nlsr.conf stored at another location "
344 << "or change the state-dir in the configuration." << std::endl;
345 std::cerr << "The file at " << conFileDynamic <<
346 " is used as dynamic file for saving NLSR runtime changes." << std::endl;
347 std::cerr << "The dynamic file can be used for next run "
348 << "after copying to another location." << std::endl;
349 return false;
350 }
351
dulalsaurab82a34c22019-02-04 17:31:21 +0000352 m_confParam.setConfFileNameDynamic(conFileDynamic);
353 try {
Davide Pesavento22520e62021-06-08 22:16:52 -0400354 bf::copy_file(m_confFileName, conFileDynamic,
355#if BOOST_VERSION >= 107400
356 bf::copy_options::overwrite_existing
357#else
358 bf::copy_option::overwrite_if_exists
359#endif
360 );
dulalsaurab82a34c22019-02-04 17:31:21 +0000361 }
Ashlesh Gawande328fc112019-12-12 17:06:44 -0600362 catch (const bf::filesystem_error& e) {
dulalsaurab82a34c22019-02-04 17:31:21 +0000363 std::cerr << "Error copying conf file to the state directory: " << e.what() << std::endl;
Davide Pesavento22520e62021-06-08 22:16:52 -0400364 return false;
dulalsaurab82a34c22019-02-04 17:31:21 +0000365 }
Ashlesh Gawande328fc112019-12-12 17:06:44 -0600366
Davide Pesavento22520e62021-06-08 22:16:52 -0400367 std::string testFileName = (bf::path(stateDir) / "test.seq").string();
dulalsaurab82a34c22019-02-04 17:31:21 +0000368 std::ofstream testOutFile(testFileName);
369 if (testOutFile) {
370 m_confParam.setStateFileDir(stateDir);
akmhoque674b0b12014-05-20 14:33:28 -0500371 }
372 else {
Davide Pesavento22520e62021-06-08 22:16:52 -0400373 std::cerr << "NLSR does not have read/write permission on the state directory" << std::endl;
akmhoque674b0b12014-05-20 14:33:28 -0500374 return false;
375 }
376 testOutFile.close();
377 remove(testFileName.c_str());
378 }
379 else {
Davide Pesavento22520e62021-06-08 22:16:52 -0400380 std::cerr << "Provided path '" << stateDir << "' is not a directory" << std::endl;
akmhoque674b0b12014-05-20 14:33:28 -0500381 return false;
382 }
383 }
384 else {
Davide Pesavento22520e62021-06-08 22:16:52 -0400385 std::cerr << "Provided state directory '" << stateDir << "' does not exist" << std::endl;
akmhoque674b0b12014-05-20 14:33:28 -0500386 return false;
387 }
388 }
389 catch (const std::exception& ex) {
dulalsaurab82a34c22019-02-04 17:31:21 +0000390 std::cerr << "You must configure state directory" << std::endl;
akmhoque674b0b12014-05-20 14:33:28 -0500391 std::cerr << ex.what() << std::endl;
392 return false;
393 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700394
akmhoque157b0a42014-05-13 00:26:37 -0500395 return true;
396}
397
398bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700399ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
akmhoque157b0a42014-05-13 00:26:37 -0500400{
alvya2228c62014-12-09 10:25:11 -0600401 // hello-retries
402 int retrials = section.get<int>("hello-retries", HELLO_RETRIES_DEFAULT);
403
404 if (retrials >= HELLO_RETRIES_MIN && retrials <= HELLO_RETRIES_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600405 m_confParam.setInterestRetryNumber(retrials);
akmhoque157b0a42014-05-13 00:26:37 -0500406 }
alvya2228c62014-12-09 10:25:11 -0600407 else {
408 std::cerr << "Wrong value for hello-retries." << std::endl;
409 std::cerr << "Allowed value:" << HELLO_RETRIES_MIN << "-";
410 std::cerr << HELLO_RETRIES_MAX << std::endl;
411
akmhoque157b0a42014-05-13 00:26:37 -0500412 return false;
413 }
alvya2228c62014-12-09 10:25:11 -0600414
415 // hello-timeout
alvy5a454952014-12-15 12:49:54 -0600416 uint32_t timeOut = section.get<uint32_t>("hello-timeout", HELLO_TIMEOUT_DEFAULT);
alvya2228c62014-12-09 10:25:11 -0600417
418 if (timeOut >= HELLO_TIMEOUT_MIN && timeOut <= HELLO_TIMEOUT_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600419 m_confParam.setInterestResendTime(timeOut);
akmhoque157b0a42014-05-13 00:26:37 -0500420 }
alvya2228c62014-12-09 10:25:11 -0600421 else {
422 std::cerr << "Wrong value for hello-timeout. ";
423 std::cerr << "Allowed value:" << HELLO_TIMEOUT_MIN << "-";
424 std::cerr << HELLO_TIMEOUT_MAX << std::endl;
425
426 return false;
akmhoque157b0a42014-05-13 00:26:37 -0500427 }
alvya2228c62014-12-09 10:25:11 -0600428
429 // hello-interval
alvy5a454952014-12-15 12:49:54 -0600430 uint32_t interval = section.get<uint32_t>("hello-interval", HELLO_INTERVAL_DEFAULT);
alvya2228c62014-12-09 10:25:11 -0600431
432 if (interval >= HELLO_INTERVAL_MIN && interval <= HELLO_INTERVAL_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600433 m_confParam.setInfoInterestInterval(interval);
akmhoque157b0a42014-05-13 00:26:37 -0500434 }
alvya2228c62014-12-09 10:25:11 -0600435 else {
436 std::cerr << "Wrong value for hello-interval. ";
437 std::cerr << "Allowed value:" << HELLO_INTERVAL_MIN << "-";
438 std::cerr << HELLO_INTERVAL_MAX << std::endl;
439
440 return false;
akmhoque157b0a42014-05-13 00:26:37 -0500441 }
Vince Lehman7b616582014-10-17 16:25:39 -0500442
443 // Event intervals
444 // adj-lsa-build-interval
445 ConfigurationVariable<uint32_t> adjLsaBuildInterval("adj-lsa-build-interval",
dmcoomes9f936662017-03-02 10:33:09 -0600446 std::bind(&ConfParameter::setAdjLsaBuildInterval,
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600447 &m_confParam, _1));
Vince Lehman7b616582014-10-17 16:25:39 -0500448 adjLsaBuildInterval.setMinAndMaxValue(ADJ_LSA_BUILD_INTERVAL_MIN, ADJ_LSA_BUILD_INTERVAL_MAX);
449 adjLsaBuildInterval.setOptional(ADJ_LSA_BUILD_INTERVAL_DEFAULT);
450
451 if (!adjLsaBuildInterval.parseFromConfigSection(section)) {
452 return false;
453 }
Nick Gordond5c1a372016-10-31 13:56:23 -0500454 // Set the retry count for fetching the FaceStatus dataset
455 ConfigurationVariable<uint32_t> faceDatasetFetchTries("face-dataset-fetch-tries",
456 std::bind(&ConfParameter::setFaceDatasetFetchTries,
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600457 &m_confParam,
Nick Gordond5c1a372016-10-31 13:56:23 -0500458 _1));
459
460 faceDatasetFetchTries.setMinAndMaxValue(FACE_DATASET_FETCH_TRIES_MIN,
461 FACE_DATASET_FETCH_TRIES_MAX);
462 faceDatasetFetchTries.setOptional(FACE_DATASET_FETCH_TRIES_DEFAULT);
463
464 if (!faceDatasetFetchTries.parseFromConfigSection(section)) {
465 return false;
466 }
467
468 // Set the interval between FaceStatus dataset fetch attempts.
Ashlesh Gawande3909aa12017-07-28 16:01:35 -0500469 ConfigurationVariable<uint32_t> faceDatasetFetchInterval("face-dataset-fetch-interval",
Davide Pesaventod90338d2021-01-07 17:50:05 -0500470 std::bind(&ConfParameter::setFaceDatasetFetchInterval,
471 &m_confParam,
472 _1));
Nick Gordond5c1a372016-10-31 13:56:23 -0500473
Ashlesh Gawande3909aa12017-07-28 16:01:35 -0500474 faceDatasetFetchInterval.setMinAndMaxValue(FACE_DATASET_FETCH_INTERVAL_MIN,
475 FACE_DATASET_FETCH_INTERVAL_MAX);
476 faceDatasetFetchInterval.setOptional(FACE_DATASET_FETCH_INTERVAL_DEFAULT);
Nick Gordond5c1a372016-10-31 13:56:23 -0500477
478 if (!faceDatasetFetchInterval.parseFromConfigSection(section)) {
479 return false;
480 }
Vince Lehman7b616582014-10-17 16:25:39 -0500481
Ashlesh Gawande328fc112019-12-12 17:06:44 -0600482 for (const auto& tn : section) {
483 if (tn.first == "neighbor") {
akmhoque157b0a42014-05-13 00:26:37 -0500484 try {
Ashlesh Gawande328fc112019-12-12 17:06:44 -0600485 ConfigSection CommandAttriTree = tn.second;
akmhoque157b0a42014-05-13 00:26:37 -0500486 std::string name = CommandAttriTree.get<std::string>("name");
Nick Gordone9733ed2017-04-26 10:48:39 -0500487 std::string uriString = CommandAttriTree.get<std::string>("face-uri");
alvy2fe12872014-11-25 10:32:23 -0600488
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500489 ndn::FaceUri faceUri;
Davide Pesavento4b9d30f2020-05-01 02:48:34 -0400490 if (!faceUri.parse(uriString)) {
491 std::cerr << "face-uri parsing failed" << std::endl;
Ashlesh Gawande7e3f6d72019-01-25 13:13:43 -0600492 return false;
493 }
494
495 bool failedToCanonize = false;
Davide Pesavento4b9d30f2020-05-01 02:48:34 -0400496 faceUri.canonize([&faceUri] (const auto& canonicalUri) {
Ashlesh Gawande7e3f6d72019-01-25 13:13:43 -0600497 faceUri = canonicalUri;
498 },
Davide Pesavento4b9d30f2020-05-01 02:48:34 -0400499 [&faceUri, &failedToCanonize] (const auto& reason) {
Ashlesh Gawande7e3f6d72019-01-25 13:13:43 -0600500 failedToCanonize = true;
Davide Pesavento4b9d30f2020-05-01 02:48:34 -0400501 std::cerr << "Could not canonize URI: '" << faceUri
502 << "' because: " << reason << std::endl;
Ashlesh Gawande7e3f6d72019-01-25 13:13:43 -0600503 },
504 m_io,
505 TIME_ALLOWED_FOR_CANONIZATION);
506 m_io.run();
Ashlesh Gawande9ecbdc92019-03-11 13:18:45 -0700507 m_io.reset();
Ashlesh Gawande7e3f6d72019-01-25 13:13:43 -0600508
509 if (failedToCanonize) {
alvy2fe12872014-11-25 10:32:23 -0600510 return false;
511 }
512
Davide Pesavento4b9d30f2020-05-01 02:48:34 -0400513 double linkCost = CommandAttriTree.get<double>("link-cost", Adjacent::DEFAULT_LINK_COST);
akmhoque157b0a42014-05-13 00:26:37 -0500514 ndn::Name neighborName(name);
515 if (!neighborName.empty()) {
Vince Lehmancb76ade2014-08-28 21:24:41 -0500516 Adjacent adj(name, faceUri, linkCost, Adjacent::STATUS_INACTIVE, 0, 0);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600517 m_confParam.getAdjacencyList().insert(adj);
akmhoque157b0a42014-05-13 00:26:37 -0500518 }
519 else {
akmhoque674b0b12014-05-20 14:33:28 -0500520 std::cerr << " Wrong command format ! [name /nbr/name/ \n face-uri /uri\n]";
akmhoque157b0a42014-05-13 00:26:37 -0500521 std::cerr << " or bad URI format" << std::endl;
akmhoque53353462014-04-22 08:43:45 -0500522 }
523 }
akmhoque157b0a42014-05-13 00:26:37 -0500524 catch (const std::exception& ex) {
525 std::cerr << ex.what() << std::endl;
526 return false;
527 }
akmhoque53353462014-04-22 08:43:45 -0500528 }
529 }
akmhoque157b0a42014-05-13 00:26:37 -0500530 return true;
akmhoque53353462014-04-22 08:43:45 -0500531}
532
akmhoque157b0a42014-05-13 00:26:37 -0500533bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700534ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
akmhoque53353462014-04-22 08:43:45 -0500535{
alvya2228c62014-12-09 10:25:11 -0600536 // state
Nick Gordone98480b2017-05-24 11:23:03 -0500537 std::string state = section.get<std::string>("state", "off");
alvya2228c62014-12-09 10:25:11 -0600538
539 if (boost::iequals(state, "off")) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600540 m_confParam.setHyperbolicState(HYPERBOLIC_STATE_OFF);
akmhoque53353462014-04-22 08:43:45 -0500541 }
alvya2228c62014-12-09 10:25:11 -0600542 else if (boost::iequals(state, "on")) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600543 m_confParam.setHyperbolicState(HYPERBOLIC_STATE_ON);
alvya2228c62014-12-09 10:25:11 -0600544 }
545 else if (state == "dry-run") {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600546 m_confParam.setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
alvya2228c62014-12-09 10:25:11 -0600547 }
548 else {
549 std::cerr << "Wrong format for hyperbolic state." << std::endl;
550 std::cerr << "Allowed value: off, on, dry-run" << std::endl;
551
akmhoque157b0a42014-05-13 00:26:37 -0500552 return false;
akmhoque53353462014-04-22 08:43:45 -0500553 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700554
akmhoque157b0a42014-05-13 00:26:37 -0500555 try {
Laqin Fan54a43f02017-03-08 12:31:30 -0600556 // Radius and angle(s) are mandatory configuration parameters in hyperbolic section.
557 // Even if router can have hyperbolic routing calculation off but other router
558 // in the network may use hyperbolic routing calculation for FIB generation.
559 // So each router need to advertise its hyperbolic coordinates in the network
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700560 double radius = section.get<double>("radius");
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600561 std::string angleString = section.get<std::string>("angle");
562
563 std::stringstream ss(angleString);
564 std::vector<double> angles;
565
566 double angle;
567
Laqin Fan54a43f02017-03-08 12:31:30 -0600568 while (ss >> angle) {
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600569 angles.push_back(angle);
Laqin Fan54a43f02017-03-08 12:31:30 -0600570 if (ss.peek() == ',' || ss.peek() == ' ') {
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600571 ss.ignore();
572 }
573 }
574
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600575 if (!m_confParam.setCorR(radius)) {
akmhoque157b0a42014-05-13 00:26:37 -0500576 return false;
577 }
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600578 m_confParam.setCorTheta(angles);
akmhoque53353462014-04-22 08:43:45 -0500579 }
akmhoque157b0a42014-05-13 00:26:37 -0500580 catch (const std::exception& ex) {
581 std::cerr << ex.what() << std::endl;
582 if (state == "on" || state == "dry-run") {
583 return false;
584 }
akmhoque53353462014-04-22 08:43:45 -0500585 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700586
akmhoque157b0a42014-05-13 00:26:37 -0500587 return true;
akmhoque53353462014-04-22 08:43:45 -0500588}
589
akmhoque157b0a42014-05-13 00:26:37 -0500590bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700591ConfFileProcessor::processConfSectionFib(const ConfigSection& section)
akmhoque53353462014-04-22 08:43:45 -0500592{
alvya2228c62014-12-09 10:25:11 -0600593 // max-faces-per-prefix
594 int maxFacesPerPrefix = section.get<int>("max-faces-per-prefix", MAX_FACES_PER_PREFIX_DEFAULT);
595
596 if (maxFacesPerPrefix >= MAX_FACES_PER_PREFIX_MIN &&
597 maxFacesPerPrefix <= MAX_FACES_PER_PREFIX_MAX)
598 {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600599 m_confParam.setMaxFacesPerPrefix(maxFacesPerPrefix);
akmhoque53353462014-04-22 08:43:45 -0500600 }
alvya2228c62014-12-09 10:25:11 -0600601 else {
602 std::cerr << "Wrong value for max-faces-per-prefix. ";
603 std::cerr << MAX_FACES_PER_PREFIX_MIN << std::endl;
604
akmhoque157b0a42014-05-13 00:26:37 -0500605 return false;
606 }
Vince Lehman7b616582014-10-17 16:25:39 -0500607
608 // routing-calc-interval
609 ConfigurationVariable<uint32_t> routingCalcInterval("routing-calc-interval",
dmcoomes9f936662017-03-02 10:33:09 -0600610 std::bind(&ConfParameter::setRoutingCalcInterval,
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600611 &m_confParam, _1));
Vince Lehman7b616582014-10-17 16:25:39 -0500612 routingCalcInterval.setMinAndMaxValue(ROUTING_CALC_INTERVAL_MIN, ROUTING_CALC_INTERVAL_MAX);
613 routingCalcInterval.setOptional(ROUTING_CALC_INTERVAL_DEFAULT);
614
615 if (!routingCalcInterval.parseFromConfigSection(section)) {
616 return false;
617 }
618
akmhoque157b0a42014-05-13 00:26:37 -0500619 return true;
akmhoque53353462014-04-22 08:43:45 -0500620}
621
akmhoque157b0a42014-05-13 00:26:37 -0500622bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700623ConfFileProcessor::processConfSectionAdvertising(const ConfigSection& section)
akmhoque53353462014-04-22 08:43:45 -0500624{
Ashlesh Gawande328fc112019-12-12 17:06:44 -0600625 for (const auto& tn : section) {
626 if (tn.first == "prefix") {
akmhoque157b0a42014-05-13 00:26:37 -0500627 try {
Ashlesh Gawande328fc112019-12-12 17:06:44 -0600628 ndn::Name namePrefix(tn.second.data());
akmhoque157b0a42014-05-13 00:26:37 -0500629 if (!namePrefix.empty()) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600630 m_confParam.getNamePrefixList().insert(namePrefix);
akmhoque157b0a42014-05-13 00:26:37 -0500631 }
632 else {
akmhoque674b0b12014-05-20 14:33:28 -0500633 std::cerr << " Wrong command format ! [prefix /name/prefix] or bad URI" << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500634 return false;
635 }
636 }
637 catch (const std::exception& ex) {
638 std::cerr << ex.what() << std::endl;
639 return false;
640 }
akmhoque53353462014-04-22 08:43:45 -0500641 }
akmhoque53353462014-04-22 08:43:45 -0500642 }
akmhoque157b0a42014-05-13 00:26:37 -0500643 return true;
akmhoque53353462014-04-22 08:43:45 -0500644}
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700645
646bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700647ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700648{
649 ConfigSection::const_iterator it = section.begin();
650
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500651 if (it == section.end() || it->first != "validator") {
652 std::cerr << "Error: Expect validator section!" << std::endl;
653 return false;
654 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700655
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600656 m_confParam.getValidator().load(it->second, m_confFileName);
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500657
akmhoqued57f3672014-06-10 10:41:32 -0500658 it++;
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500659 if (it != section.end() && it->first == "prefix-update-validator") {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600660 m_confParam.getPrefixUpdateValidator().load(it->second, m_confFileName);
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700661
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500662 it++;
663 for (; it != section.end(); it++) {
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500664
665 if (it->first != "cert-to-publish") {
666 std::cerr << "Error: Expect cert-to-publish!" << std::endl;
667 return false;
668 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700669
670 std::string file = it->second.data();
Ashlesh Gawande328fc112019-12-12 17:06:44 -0600671 bf::path certfilePath = absolute(file, bf::path(m_confFileName).parent_path());
Alexander Afanasyev0ad01f32020-06-03 14:12:58 -0400672 auto idCert = ndn::io::load<ndn::security::Certificate>(certfilePath.string());
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700673
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500674 if (idCert == nullptr) {
675 std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
676 return false;
677 }
Saurab Dulal427e0122019-11-28 11:58:02 -0600678 m_confParam.addCertPath(certfilePath.string());
679 m_confParam.loadCertToValidator(*idCert);
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700680 }
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500681 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700682
683 return true;
684}
685
alvy2fe12872014-11-25 10:32:23 -0600686} // namespace nlsr