blob: d3e75be797b53896d6e4d66faaca7c7f46cebdfd [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Ashlesh Gawande7e3f6d72019-01-25 13:13:43 -06003 * Copyright (c) 2014-2019, 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/>.
akmhoque3d06e792014-05-27 16:23:20 -050020 **/
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
Nick Gordone98480b2017-05-24 11:23:03 -050027#include <boost/cstdint.hpp>
Alexander Afanasyevb669f9c2014-11-14 12:41:54 -080028
29#include <ndn-cxx/name.hpp>
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050030#include <ndn-cxx/net/face-uri.hpp>
Alexander Afanasyevb669f9c2014-11-14 12:41:54 -080031
Nick Gordone98480b2017-05-24 11:23:03 -050032#include <iostream>
33#include <fstream>
akmhoque53353462014-04-22 08:43:45 -050034
akmhoque53353462014-04-22 08:43:45 -050035namespace nlsr {
36
Vince Lehman7b616582014-10-17 16:25:39 -050037template <class T>
38class ConfigurationVariable
39{
40public:
dmcoomes9f936662017-03-02 10:33:09 -060041 typedef std::function<void(T)> ConfParameterCallback;
Vince Lehman7b616582014-10-17 16:25:39 -050042 typedef boost::property_tree::ptree ConfigSection;
43
44 ConfigurationVariable(const std::string& key, const ConfParameterCallback& setter)
45 : m_key(key)
46 , m_setterCallback(setter)
47 , m_minValue(0)
48 , m_maxValue(0)
49 , m_shouldCheckRange(false)
50 , m_isRequired(true)
51 {
52 }
53
54 bool
55 parseFromConfigSection(const ConfigSection& section)
56 {
57 try {
58 T value = section.get<T>(m_key);
59
60 if (!isValidValue(value)) {
61 return false;
62 }
63
64 m_setterCallback(value);
65 return true;
66 }
67 catch (const std::exception& ex) {
68
69 if (m_isRequired) {
70 std::cerr << ex.what() << std::endl;
71 std::cerr << "Missing required configuration variable" << std::endl;
72 return false;
73 }
74 else {
75 m_setterCallback(m_defaultValue);
76 return true;
77 }
78 }
79
80 return false;
81 }
82
83 void
84 setMinAndMaxValue(T min, T max)
85 {
86 m_minValue = min;
87 m_maxValue = max;
88 m_shouldCheckRange = true;
89 }
90
91 void
92 setOptional(T defaultValue)
93 {
94 m_isRequired = false;
95 m_defaultValue = defaultValue;
96 }
97
98private:
99 void
100 printOutOfRangeError(T value)
101 {
102 std::cerr << "Invalid value for " << m_key << ": "
103 << value << ". "
104 << "Valid values: "
105 << m_minValue << " - "
106 << m_maxValue << std::endl;
107 }
108
109 bool
110 isValidValue(T value)
111 {
112 if (!m_shouldCheckRange) {
113 return true;
114 }
115 else if (value < m_minValue || value > m_maxValue)
116 {
117 printOutOfRangeError(value);
118 return false;
119 }
120
121 return true;
122 }
123
124private:
125 const std::string m_key;
126 const ConfParameterCallback m_setterCallback;
127 T m_defaultValue;
128
129 T m_minValue;
130 T m_maxValue;
131
132 bool m_shouldCheckRange;
133 bool m_isRequired;
134};
135
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600136ConfFileProcessor::ConfFileProcessor(ConfParameter& confParam)
137 : m_confFileName(confParam.getConfFileName())
138 , m_confParam(confParam)
139{
140}
141
akmhoque157b0a42014-05-13 00:26:37 -0500142bool
akmhoqueb6450b12014-04-24 00:01:03 -0500143ConfFileProcessor::processConfFile()
akmhoque53353462014-04-22 08:43:45 -0500144{
akmhoque157b0a42014-05-13 00:26:37 -0500145 bool ret = true;
Nick Gordone98480b2017-05-24 11:23:03 -0500146 std::ifstream inputFile;
akmhoque157b0a42014-05-13 00:26:37 -0500147 inputFile.open(m_confFileName.c_str());
148 if (!inputFile.is_open()) {
Nick Gordone98480b2017-05-24 11:23:03 -0500149 std::string msg = "Failed to read configuration file: ";
akmhoque157b0a42014-05-13 00:26:37 -0500150 msg += m_confFileName;
Nick Gordone98480b2017-05-24 11:23:03 -0500151 std::cerr << msg << std::endl;
akmhoquead5fe952014-06-26 13:34:12 -0500152 return false;
akmhoque157b0a42014-05-13 00:26:37 -0500153 }
154 ret = load(inputFile);
155 inputFile.close();
156 return ret;
157}
158
159bool
Nick Gordone98480b2017-05-24 11:23:03 -0500160ConfFileProcessor::load(std::istream& input)
akmhoque157b0a42014-05-13 00:26:37 -0500161{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700162 ConfigSection pt;
akmhoque157b0a42014-05-13 00:26:37 -0500163 bool ret = true;
164 try {
165 boost::property_tree::read_info(input, pt);
166 }
167 catch (const boost::property_tree::info_parser_error& error) {
Nick Gordone98480b2017-05-24 11:23:03 -0500168 std::stringstream msg;
akmhoque157b0a42014-05-13 00:26:37 -0500169 std::cerr << "Failed to parse configuration file " << std::endl;
170 std::cerr << m_confFileName << std::endl;
171 return false;
172 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700173
174 for (ConfigSection::const_iterator tn = pt.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500175 tn != pt.end(); ++tn) {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700176 ret = processSection(tn->first, tn->second);
akmhoque157b0a42014-05-13 00:26:37 -0500177 if (ret == false) {
178 break;
179 }
180 }
181 return ret;
182}
183
184bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700185ConfFileProcessor::processSection(const std::string& sectionName, const ConfigSection& section)
akmhoque157b0a42014-05-13 00:26:37 -0500186{
187 bool ret = true;
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700188 if (sectionName == "general")
akmhoque53353462014-04-22 08:43:45 -0500189 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700190 ret = processConfSectionGeneral(section);
akmhoque157b0a42014-05-13 00:26:37 -0500191 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700192 else if (sectionName == "neighbors")
akmhoque157b0a42014-05-13 00:26:37 -0500193 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700194 ret = processConfSectionNeighbors(section);
akmhoque157b0a42014-05-13 00:26:37 -0500195 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700196 else if (sectionName == "hyperbolic")
akmhoque157b0a42014-05-13 00:26:37 -0500197 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700198 ret = processConfSectionHyperbolic(section);
akmhoque157b0a42014-05-13 00:26:37 -0500199 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700200 else if (sectionName == "fib")
akmhoque157b0a42014-05-13 00:26:37 -0500201 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700202 ret = processConfSectionFib(section);
akmhoque157b0a42014-05-13 00:26:37 -0500203 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700204 else if (sectionName == "advertising")
akmhoque157b0a42014-05-13 00:26:37 -0500205 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700206 ret = processConfSectionAdvertising(section);
akmhoque157b0a42014-05-13 00:26:37 -0500207 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700208 else if (sectionName == "security")
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700209 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700210 ret = processConfSectionSecurity(section);
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700211 }
akmhoque157b0a42014-05-13 00:26:37 -0500212 else
213 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700214 std::cerr << "Wrong configuration section: " << sectionName << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500215 }
216 return ret;
217}
218
219bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700220ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
akmhoque157b0a42014-05-13 00:26:37 -0500221{
222 try {
Nick Gordone98480b2017-05-24 11:23:03 -0500223 std::string network = section.get<std::string>("network");
224 std::string site = section.get<std::string>("site");
225 std::string router = section.get<std::string>("router");
akmhoque157b0a42014-05-13 00:26:37 -0500226 ndn::Name networkName(network);
227 if (!networkName.empty()) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600228 m_confParam.setNetwork(networkName);
akmhoque157b0a42014-05-13 00:26:37 -0500229 }
230 else {
Nick Gordone98480b2017-05-24 11:23:03 -0500231 std::cerr << " Network can not be null or empty or in bad URI format :(!" << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500232 return false;
233 }
234 ndn::Name siteName(site);
235 if (!siteName.empty()) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600236 m_confParam.setSiteName(siteName);
akmhoque157b0a42014-05-13 00:26:37 -0500237 }
238 else {
Nick Gordone98480b2017-05-24 11:23:03 -0500239 std::cerr << "Site can not be null or empty or in bad URI format:( !" << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500240 return false;
241 }
242 ndn::Name routerName(router);
243 if (!routerName.empty()) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600244 m_confParam.setRouterName(routerName);
akmhoque157b0a42014-05-13 00:26:37 -0500245 }
246 else {
Nick Gordone98480b2017-05-24 11:23:03 -0500247 std::cerr << " Router name can not be null or empty or in bad URI format:( !" << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500248 return false;
249 }
250 }
251 catch (const std::exception& ex) {
Nick Gordone98480b2017-05-24 11:23:03 -0500252 std::cerr << ex.what() << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500253 return false;
254 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700255
alvya2228c62014-12-09 10:25:11 -0600256 // lsa-refresh-time
alvy5a454952014-12-15 12:49:54 -0600257 uint32_t lsaRefreshTime = section.get<uint32_t>("lsa-refresh-time", LSA_REFRESH_TIME_DEFAULT);
alvya2228c62014-12-09 10:25:11 -0600258
259 if (lsaRefreshTime >= LSA_REFRESH_TIME_MIN && lsaRefreshTime <= LSA_REFRESH_TIME_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600260 m_confParam.setLsaRefreshTime(lsaRefreshTime);
akmhoque157b0a42014-05-13 00:26:37 -0500261 }
alvya2228c62014-12-09 10:25:11 -0600262 else {
263 std::cerr << "Wrong value for lsa-refresh-time ";
264 std::cerr << "Allowed value: " << LSA_REFRESH_TIME_MIN << "-";;
265 std::cerr << LSA_REFRESH_TIME_MAX << std::endl;
266
267 return false;
268 }
269
270 // router-dead-interval
alvy5a454952014-12-15 12:49:54 -0600271 uint32_t routerDeadInterval = section.get<uint32_t>("router-dead-interval", (2*lsaRefreshTime));
alvya2228c62014-12-09 10:25:11 -0600272
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600273 if (routerDeadInterval > m_confParam.getLsaRefreshTime()) {
274 m_confParam.setRouterDeadInterval(routerDeadInterval);
alvya2228c62014-12-09 10:25:11 -0600275 }
276 else {
277 std::cerr << "Value of router-dead-interval must be larger than lsa-refresh-time" << std::endl;
278 return false;
279 }
280
281 // lsa-interest-lifetime
282 int lifetime = section.get<int>("lsa-interest-lifetime", LSA_INTEREST_LIFETIME_DEFAULT);
283
284 if (lifetime >= LSA_INTEREST_LIFETIME_MIN && lifetime <= LSA_INTEREST_LIFETIME_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600285 m_confParam.setLsaInterestLifetime(ndn::time::seconds(lifetime));
alvya2228c62014-12-09 10:25:11 -0600286 }
287 else {
288 std::cerr << "Wrong value for lsa-interest-timeout. "
289 << "Allowed value:" << LSA_INTEREST_LIFETIME_MIN << "-"
290 << LSA_INTEREST_LIFETIME_MAX << std::endl;
291
akmhoque157b0a42014-05-13 00:26:37 -0500292 return false;
293 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700294
Ashlesh Gawande32ec3fd2018-07-18 13:42:32 -0500295 // sync-protocol
296 std::string syncProtocol = section.get<std::string>("sync-protocol", "chronosync");
297 if (syncProtocol == "chronosync") {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600298 m_confParam.setSyncProtocol(SYNC_PROTOCOL_CHRONOSYNC);
Ashlesh Gawande32ec3fd2018-07-18 13:42:32 -0500299 }
300 else if (syncProtocol == "psync") {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600301 m_confParam.setSyncProtocol(SYNC_PROTOCOL_PSYNC);
Ashlesh Gawande32ec3fd2018-07-18 13:42:32 -0500302 }
303 else {
304 std::cerr << "Sync protocol " << syncProtocol << " is not supported!"
305 << "Use chronosync or psync" << std::endl;
306 return false;
307 }
308
309 // sync-interest-lifetime
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600310 uint32_t syncInterestLifetime = section.get<uint32_t>("sync-interest-lifetime",
311 SYNC_INTEREST_LIFETIME_DEFAULT);
Ashlesh Gawandef7da9c52018-02-06 17:36:46 -0600312 if (syncInterestLifetime >= SYNC_INTEREST_LIFETIME_MIN &&
313 syncInterestLifetime <= SYNC_INTEREST_LIFETIME_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600314 m_confParam.setSyncInterestLifetime(syncInterestLifetime);
Ashlesh Gawandef7da9c52018-02-06 17:36:46 -0600315 }
316 else {
317 std::cerr << "Wrong value for sync-interest-lifetime. "
318 << "Allowed value:" << SYNC_INTEREST_LIFETIME_MIN << "-"
319 << SYNC_INTEREST_LIFETIME_MAX << std::endl;
320
321 return false;
322 }
323
akmhoque674b0b12014-05-20 14:33:28 -0500324 try {
dulalsaurab82a34c22019-02-04 17:31:21 +0000325 std::string stateDir = section.get<std::string>("state-dir");
326 if (boost::filesystem::exists(stateDir)) {
327 if (boost::filesystem::is_directory(stateDir)) {
328
329 // copying nlsr.conf file to a user define directory for possible modification
330 std::string conFileDynamic = (boost::filesystem::path(stateDir) / "nlsr.conf").c_str();
331 m_confParam.setConfFileNameDynamic(conFileDynamic);
332 try {
333 copy_file(m_confFileName, conFileDynamic, boost::filesystem::copy_option::overwrite_if_exists);
334 }
335 catch (const boost::filesystem::filesystem_error& e) {
336 std::cerr << "Error copying conf file to the state directory: " << e.what() << std::endl;
337 }
338 std::string testFileName = (boost::filesystem::path(stateDir) / "test.seq").c_str();
339 std::ofstream testOutFile(testFileName);
340 if (testOutFile) {
341 m_confParam.setStateFileDir(stateDir);
akmhoque674b0b12014-05-20 14:33:28 -0500342 }
343 else {
dulalsaurab82a34c22019-02-04 17:31:21 +0000344 std::cerr << "User does not have read and write permission on the state directory";
akmhoque674b0b12014-05-20 14:33:28 -0500345 std::cerr << std::endl;
346 return false;
347 }
348 testOutFile.close();
349 remove(testFileName.c_str());
350 }
351 else {
dulalsaurab82a34c22019-02-04 17:31:21 +0000352 std::cerr << "Provided: " << stateDir << "is not a directory" << std::endl;
akmhoque674b0b12014-05-20 14:33:28 -0500353 return false;
354 }
355 }
356 else {
dulalsaurab82a34c22019-02-04 17:31:21 +0000357 std::cerr << "Provided state directory <" << stateDir << "> does not exist" << std::endl;
akmhoque674b0b12014-05-20 14:33:28 -0500358 return false;
359 }
360 }
361 catch (const std::exception& ex) {
dulalsaurab82a34c22019-02-04 17:31:21 +0000362 std::cerr << "You must configure state directory" << std::endl;
akmhoque674b0b12014-05-20 14:33:28 -0500363 std::cerr << ex.what() << std::endl;
364 return false;
365 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700366
akmhoque157b0a42014-05-13 00:26:37 -0500367 return true;
368}
369
370bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700371ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
akmhoque157b0a42014-05-13 00:26:37 -0500372{
alvya2228c62014-12-09 10:25:11 -0600373 // hello-retries
374 int retrials = section.get<int>("hello-retries", HELLO_RETRIES_DEFAULT);
375
376 if (retrials >= HELLO_RETRIES_MIN && retrials <= HELLO_RETRIES_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600377 m_confParam.setInterestRetryNumber(retrials);
akmhoque157b0a42014-05-13 00:26:37 -0500378 }
alvya2228c62014-12-09 10:25:11 -0600379 else {
380 std::cerr << "Wrong value for hello-retries." << std::endl;
381 std::cerr << "Allowed value:" << HELLO_RETRIES_MIN << "-";
382 std::cerr << HELLO_RETRIES_MAX << std::endl;
383
akmhoque157b0a42014-05-13 00:26:37 -0500384 return false;
385 }
alvya2228c62014-12-09 10:25:11 -0600386
387 // hello-timeout
alvy5a454952014-12-15 12:49:54 -0600388 uint32_t timeOut = section.get<uint32_t>("hello-timeout", HELLO_TIMEOUT_DEFAULT);
alvya2228c62014-12-09 10:25:11 -0600389
390 if (timeOut >= HELLO_TIMEOUT_MIN && timeOut <= HELLO_TIMEOUT_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600391 m_confParam.setInterestResendTime(timeOut);
akmhoque157b0a42014-05-13 00:26:37 -0500392 }
alvya2228c62014-12-09 10:25:11 -0600393 else {
394 std::cerr << "Wrong value for hello-timeout. ";
395 std::cerr << "Allowed value:" << HELLO_TIMEOUT_MIN << "-";
396 std::cerr << HELLO_TIMEOUT_MAX << std::endl;
397
398 return false;
akmhoque157b0a42014-05-13 00:26:37 -0500399 }
alvya2228c62014-12-09 10:25:11 -0600400
401 // hello-interval
alvy5a454952014-12-15 12:49:54 -0600402 uint32_t interval = section.get<uint32_t>("hello-interval", HELLO_INTERVAL_DEFAULT);
alvya2228c62014-12-09 10:25:11 -0600403
404 if (interval >= HELLO_INTERVAL_MIN && interval <= HELLO_INTERVAL_MAX) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600405 m_confParam.setInfoInterestInterval(interval);
akmhoque157b0a42014-05-13 00:26:37 -0500406 }
alvya2228c62014-12-09 10:25:11 -0600407 else {
408 std::cerr << "Wrong value for hello-interval. ";
409 std::cerr << "Allowed value:" << HELLO_INTERVAL_MIN << "-";
410 std::cerr << HELLO_INTERVAL_MAX << std::endl;
411
412 return false;
akmhoque157b0a42014-05-13 00:26:37 -0500413 }
Vince Lehman7b616582014-10-17 16:25:39 -0500414
415 // Event intervals
416 // adj-lsa-build-interval
417 ConfigurationVariable<uint32_t> adjLsaBuildInterval("adj-lsa-build-interval",
dmcoomes9f936662017-03-02 10:33:09 -0600418 std::bind(&ConfParameter::setAdjLsaBuildInterval,
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600419 &m_confParam, _1));
Vince Lehman7b616582014-10-17 16:25:39 -0500420 adjLsaBuildInterval.setMinAndMaxValue(ADJ_LSA_BUILD_INTERVAL_MIN, ADJ_LSA_BUILD_INTERVAL_MAX);
421 adjLsaBuildInterval.setOptional(ADJ_LSA_BUILD_INTERVAL_DEFAULT);
422
423 if (!adjLsaBuildInterval.parseFromConfigSection(section)) {
424 return false;
425 }
Nick Gordond5c1a372016-10-31 13:56:23 -0500426 // Set the retry count for fetching the FaceStatus dataset
427 ConfigurationVariable<uint32_t> faceDatasetFetchTries("face-dataset-fetch-tries",
428 std::bind(&ConfParameter::setFaceDatasetFetchTries,
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600429 &m_confParam,
Nick Gordond5c1a372016-10-31 13:56:23 -0500430 _1));
431
432 faceDatasetFetchTries.setMinAndMaxValue(FACE_DATASET_FETCH_TRIES_MIN,
433 FACE_DATASET_FETCH_TRIES_MAX);
434 faceDatasetFetchTries.setOptional(FACE_DATASET_FETCH_TRIES_DEFAULT);
435
436 if (!faceDatasetFetchTries.parseFromConfigSection(section)) {
437 return false;
438 }
439
440 // Set the interval between FaceStatus dataset fetch attempts.
Ashlesh Gawande3909aa12017-07-28 16:01:35 -0500441 ConfigurationVariable<uint32_t> faceDatasetFetchInterval("face-dataset-fetch-interval",
Nick Gordond5c1a372016-10-31 13:56:23 -0500442 bind(&ConfParameter::setFaceDatasetFetchInterval,
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600443 &m_confParam,
Nick Gordond5c1a372016-10-31 13:56:23 -0500444 _1));
445
Ashlesh Gawande3909aa12017-07-28 16:01:35 -0500446 faceDatasetFetchInterval.setMinAndMaxValue(FACE_DATASET_FETCH_INTERVAL_MIN,
447 FACE_DATASET_FETCH_INTERVAL_MAX);
448 faceDatasetFetchInterval.setOptional(FACE_DATASET_FETCH_INTERVAL_DEFAULT);
Nick Gordond5c1a372016-10-31 13:56:23 -0500449
450 if (!faceDatasetFetchInterval.parseFromConfigSection(section)) {
451 return false;
452 }
Vince Lehman7b616582014-10-17 16:25:39 -0500453
454 // first-hello-interval
455 ConfigurationVariable<uint32_t> firstHelloInterval("first-hello-interval",
dmcoomes9f936662017-03-02 10:33:09 -0600456 std::bind(&ConfParameter::setFirstHelloInterval,
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600457 &m_confParam, _1));
Vince Lehman7b616582014-10-17 16:25:39 -0500458 firstHelloInterval.setMinAndMaxValue(FIRST_HELLO_INTERVAL_MIN, FIRST_HELLO_INTERVAL_MAX);
459 firstHelloInterval.setOptional(FIRST_HELLO_INTERVAL_DEFAULT);
460
461 if (!firstHelloInterval.parseFromConfigSection(section)) {
462 return false;
463 }
464
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700465 for (ConfigSection::const_iterator tn =
466 section.begin(); tn != section.end(); ++tn) {
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700467
Nick Gordond5c1a372016-10-31 13:56:23 -0500468 if (tn->first == "neighbor") {
akmhoque157b0a42014-05-13 00:26:37 -0500469 try {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700470 ConfigSection CommandAttriTree = tn->second;
akmhoque157b0a42014-05-13 00:26:37 -0500471 std::string name = CommandAttriTree.get<std::string>("name");
Nick Gordone9733ed2017-04-26 10:48:39 -0500472 std::string uriString = CommandAttriTree.get<std::string>("face-uri");
alvy2fe12872014-11-25 10:32:23 -0600473
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500474 ndn::FaceUri faceUri;
Laqin Fan54a43f02017-03-08 12:31:30 -0600475 if (! faceUri.parse(uriString)) {
Ashlesh Gawande7e3f6d72019-01-25 13:13:43 -0600476 std::cerr << "Parsing failed!" << std::endl;
477 return false;
478 }
479
480 bool failedToCanonize = false;
481 faceUri.canonize([&faceUri] (ndn::FaceUri canonicalUri) {
482 faceUri = canonicalUri;
483 },
484 [&faceUri, &failedToCanonize] (const std::string& reason) {
485 failedToCanonize = true;
486 std::cerr << "Could not canonize URI: " << faceUri
487 << "because: " << reason << std::endl;
488 },
489 m_io,
490 TIME_ALLOWED_FOR_CANONIZATION);
491 m_io.run();
Ashlesh Gawande9ecbdc92019-03-11 13:18:45 -0700492 m_io.reset();
Ashlesh Gawande7e3f6d72019-01-25 13:13:43 -0600493
494 if (failedToCanonize) {
alvy2fe12872014-11-25 10:32:23 -0600495 return false;
496 }
497
akmhoque157b0a42014-05-13 00:26:37 -0500498 double linkCost = CommandAttriTree.get<double>("link-cost",
499 Adjacent::DEFAULT_LINK_COST);
500 ndn::Name neighborName(name);
501 if (!neighborName.empty()) {
Vince Lehmancb76ade2014-08-28 21:24:41 -0500502 Adjacent adj(name, faceUri, linkCost, Adjacent::STATUS_INACTIVE, 0, 0);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600503 m_confParam.getAdjacencyList().insert(adj);
akmhoque157b0a42014-05-13 00:26:37 -0500504 }
505 else {
akmhoque674b0b12014-05-20 14:33:28 -0500506 std::cerr << " Wrong command format ! [name /nbr/name/ \n face-uri /uri\n]";
akmhoque157b0a42014-05-13 00:26:37 -0500507 std::cerr << " or bad URI format" << std::endl;
akmhoque53353462014-04-22 08:43:45 -0500508 }
509 }
akmhoque157b0a42014-05-13 00:26:37 -0500510 catch (const std::exception& ex) {
511 std::cerr << ex.what() << std::endl;
512 return false;
513 }
akmhoque53353462014-04-22 08:43:45 -0500514 }
515 }
akmhoque157b0a42014-05-13 00:26:37 -0500516 return true;
akmhoque53353462014-04-22 08:43:45 -0500517}
518
akmhoque157b0a42014-05-13 00:26:37 -0500519bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700520ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
akmhoque53353462014-04-22 08:43:45 -0500521{
alvya2228c62014-12-09 10:25:11 -0600522 // state
Nick Gordone98480b2017-05-24 11:23:03 -0500523 std::string state = section.get<std::string>("state", "off");
alvya2228c62014-12-09 10:25:11 -0600524
525 if (boost::iequals(state, "off")) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600526 m_confParam.setHyperbolicState(HYPERBOLIC_STATE_OFF);
akmhoque53353462014-04-22 08:43:45 -0500527 }
alvya2228c62014-12-09 10:25:11 -0600528 else if (boost::iequals(state, "on")) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600529 m_confParam.setHyperbolicState(HYPERBOLIC_STATE_ON);
alvya2228c62014-12-09 10:25:11 -0600530 }
531 else if (state == "dry-run") {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600532 m_confParam.setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
alvya2228c62014-12-09 10:25:11 -0600533 }
534 else {
535 std::cerr << "Wrong format for hyperbolic state." << std::endl;
536 std::cerr << "Allowed value: off, on, dry-run" << std::endl;
537
akmhoque157b0a42014-05-13 00:26:37 -0500538 return false;
akmhoque53353462014-04-22 08:43:45 -0500539 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700540
akmhoque157b0a42014-05-13 00:26:37 -0500541 try {
Laqin Fan54a43f02017-03-08 12:31:30 -0600542 // Radius and angle(s) are mandatory configuration parameters in hyperbolic section.
543 // Even if router can have hyperbolic routing calculation off but other router
544 // in the network may use hyperbolic routing calculation for FIB generation.
545 // So each router need to advertise its hyperbolic coordinates in the network
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700546 double radius = section.get<double>("radius");
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600547 std::string angleString = section.get<std::string>("angle");
548
549 std::stringstream ss(angleString);
550 std::vector<double> angles;
551
552 double angle;
553
Laqin Fan54a43f02017-03-08 12:31:30 -0600554 while (ss >> angle) {
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600555 angles.push_back(angle);
Laqin Fan54a43f02017-03-08 12:31:30 -0600556 if (ss.peek() == ',' || ss.peek() == ' ') {
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600557 ss.ignore();
558 }
559 }
560
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600561 if (!m_confParam.setCorR(radius)) {
akmhoque157b0a42014-05-13 00:26:37 -0500562 return false;
563 }
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600564 m_confParam.setCorTheta(angles);
akmhoque53353462014-04-22 08:43:45 -0500565 }
akmhoque157b0a42014-05-13 00:26:37 -0500566 catch (const std::exception& ex) {
567 std::cerr << ex.what() << std::endl;
568 if (state == "on" || state == "dry-run") {
569 return false;
570 }
akmhoque53353462014-04-22 08:43:45 -0500571 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700572
akmhoque157b0a42014-05-13 00:26:37 -0500573 return true;
akmhoque53353462014-04-22 08:43:45 -0500574}
575
akmhoque157b0a42014-05-13 00:26:37 -0500576bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700577ConfFileProcessor::processConfSectionFib(const ConfigSection& section)
akmhoque53353462014-04-22 08:43:45 -0500578{
alvya2228c62014-12-09 10:25:11 -0600579 // max-faces-per-prefix
580 int maxFacesPerPrefix = section.get<int>("max-faces-per-prefix", MAX_FACES_PER_PREFIX_DEFAULT);
581
582 if (maxFacesPerPrefix >= MAX_FACES_PER_PREFIX_MIN &&
583 maxFacesPerPrefix <= MAX_FACES_PER_PREFIX_MAX)
584 {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600585 m_confParam.setMaxFacesPerPrefix(maxFacesPerPrefix);
akmhoque53353462014-04-22 08:43:45 -0500586 }
alvya2228c62014-12-09 10:25:11 -0600587 else {
588 std::cerr << "Wrong value for max-faces-per-prefix. ";
589 std::cerr << MAX_FACES_PER_PREFIX_MIN << std::endl;
590
akmhoque157b0a42014-05-13 00:26:37 -0500591 return false;
592 }
Vince Lehman7b616582014-10-17 16:25:39 -0500593
594 // routing-calc-interval
595 ConfigurationVariable<uint32_t> routingCalcInterval("routing-calc-interval",
dmcoomes9f936662017-03-02 10:33:09 -0600596 std::bind(&ConfParameter::setRoutingCalcInterval,
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600597 &m_confParam, _1));
Vince Lehman7b616582014-10-17 16:25:39 -0500598 routingCalcInterval.setMinAndMaxValue(ROUTING_CALC_INTERVAL_MIN, ROUTING_CALC_INTERVAL_MAX);
599 routingCalcInterval.setOptional(ROUTING_CALC_INTERVAL_DEFAULT);
600
601 if (!routingCalcInterval.parseFromConfigSection(section)) {
602 return false;
603 }
604
akmhoque157b0a42014-05-13 00:26:37 -0500605 return true;
akmhoque53353462014-04-22 08:43:45 -0500606}
607
akmhoque157b0a42014-05-13 00:26:37 -0500608bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700609ConfFileProcessor::processConfSectionAdvertising(const ConfigSection& section)
akmhoque53353462014-04-22 08:43:45 -0500610{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700611 for (ConfigSection::const_iterator tn =
612 section.begin(); tn != section.end(); ++tn) {
akmhoque157b0a42014-05-13 00:26:37 -0500613 if (tn->first == "prefix") {
614 try {
615 std::string prefix = tn->second.data();
616 ndn::Name namePrefix(prefix);
617 if (!namePrefix.empty()) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600618 m_confParam.getNamePrefixList().insert(namePrefix);
akmhoque157b0a42014-05-13 00:26:37 -0500619 }
620 else {
akmhoque674b0b12014-05-20 14:33:28 -0500621 std::cerr << " Wrong command format ! [prefix /name/prefix] or bad URI" << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500622 return false;
623 }
624 }
625 catch (const std::exception& ex) {
626 std::cerr << ex.what() << std::endl;
627 return false;
628 }
akmhoque53353462014-04-22 08:43:45 -0500629 }
akmhoque53353462014-04-22 08:43:45 -0500630 }
akmhoque157b0a42014-05-13 00:26:37 -0500631 return true;
akmhoque53353462014-04-22 08:43:45 -0500632}
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700633
634bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700635ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700636{
637 ConfigSection::const_iterator it = section.begin();
638
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500639 if (it == section.end() || it->first != "validator") {
640 std::cerr << "Error: Expect validator section!" << std::endl;
641 return false;
642 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700643
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600644 m_confParam.getValidator().load(it->second, m_confFileName);
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500645
akmhoqued57f3672014-06-10 10:41:32 -0500646 it++;
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500647 if (it != section.end() && it->first == "prefix-update-validator") {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600648 m_confParam.getPrefixUpdateValidator().load(it->second, m_confFileName);
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700649
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500650 it++;
651 for (; it != section.end(); it++) {
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700652 using namespace boost::filesystem;
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500653
654 if (it->first != "cert-to-publish") {
655 std::cerr << "Error: Expect cert-to-publish!" << std::endl;
656 return false;
657 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700658
659 std::string file = it->second.data();
660 path certfilePath = absolute(file, path(m_confFileName).parent_path());
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500661 std::shared_ptr<ndn::security::v2::Certificate> idCert =
662 ndn::io::load<ndn::security::v2::Certificate>(certfilePath.string());
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700663
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500664 if (idCert == nullptr) {
665 std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
666 return false;
667 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700668
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600669 m_confParam.getCertStore().insert(*idCert);
670 m_confParam.getValidator().loadAnchor("Authoritative-Certificate",
671 ndn::security::v2::Certificate(*idCert));
672 m_confParam.getPrefixUpdateValidator().loadAnchor("Authoritative-Certificate",
673 ndn::security::v2::Certificate(*idCert));
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700674 }
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500675 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700676
677 return true;
678}
679
alvy2fe12872014-11-25 10:32:23 -0600680} // namespace nlsr