blob: b3067a3222464505b6de5f5a9dcf9443bd1a1561 [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014 University of Memphis,
4 * Regents of the University of California
5 *
6 * This file is part of NLSR (Named-data Link State Routing).
7 * See AUTHORS.md for complete list of NLSR authors and contributors.
8 *
9 * NLSR is free software: you can redistribute it and/or modify it under the terms
10 * of the GNU General Public License as published by the Free Software Foundation,
11 * either version 3 of the License, or (at your option) any later version.
12 *
13 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
21 * \author Minsheng Zhang <mzhang4@memphis.edu>
22 *
23 **/
akmhoque53353462014-04-22 08:43:45 -050024#include <iostream>
25#include <fstream>
Alexander Afanasyevb669f9c2014-11-14 12:41:54 -080026
27#include <ndn-cxx/name.hpp>
28
29// boost needs to be included after ndn-cxx, otherwise there will be conflict with _1, _2, ...
akmhoque157b0a42014-05-13 00:26:37 -050030#include <boost/algorithm/string.hpp>
31#include <boost/property_tree/info_parser.hpp>
32#include <boost/property_tree/ptree.hpp>
akmhoque674b0b12014-05-20 14:33:28 -050033#include <boost/filesystem.hpp>
akmhoque53353462014-04-22 08:43:45 -050034
akmhoque53353462014-04-22 08:43:45 -050035#include "conf-parameter.hpp"
akmhoque157b0a42014-05-13 00:26:37 -050036#include "conf-file-processor.hpp"
akmhoque53353462014-04-22 08:43:45 -050037#include "adjacent.hpp"
akmhoque157b0a42014-05-13 00:26:37 -050038#include "utility/name-helper.hpp"
akmhoque53353462014-04-22 08:43:45 -050039
akmhoque53353462014-04-22 08:43:45 -050040namespace nlsr {
41
42using namespace std;
43
Vince Lehman7b616582014-10-17 16:25:39 -050044template <class T>
45class ConfigurationVariable
46{
47public:
48 typedef ndn::function<void(T)> ConfParameterCallback;
49 typedef boost::property_tree::ptree ConfigSection;
50
51 ConfigurationVariable(const std::string& key, const ConfParameterCallback& setter)
52 : m_key(key)
53 , m_setterCallback(setter)
54 , m_minValue(0)
55 , m_maxValue(0)
56 , m_shouldCheckRange(false)
57 , m_isRequired(true)
58 {
59 }
60
61 bool
62 parseFromConfigSection(const ConfigSection& section)
63 {
64 try {
65 T value = section.get<T>(m_key);
66
67 if (!isValidValue(value)) {
68 return false;
69 }
70
71 m_setterCallback(value);
72 return true;
73 }
74 catch (const std::exception& ex) {
75
76 if (m_isRequired) {
77 std::cerr << ex.what() << std::endl;
78 std::cerr << "Missing required configuration variable" << std::endl;
79 return false;
80 }
81 else {
82 m_setterCallback(m_defaultValue);
83 return true;
84 }
85 }
86
87 return false;
88 }
89
90 void
91 setMinAndMaxValue(T min, T max)
92 {
93 m_minValue = min;
94 m_maxValue = max;
95 m_shouldCheckRange = true;
96 }
97
98 void
99 setOptional(T defaultValue)
100 {
101 m_isRequired = false;
102 m_defaultValue = defaultValue;
103 }
104
105private:
106 void
107 printOutOfRangeError(T value)
108 {
109 std::cerr << "Invalid value for " << m_key << ": "
110 << value << ". "
111 << "Valid values: "
112 << m_minValue << " - "
113 << m_maxValue << std::endl;
114 }
115
116 bool
117 isValidValue(T value)
118 {
119 if (!m_shouldCheckRange) {
120 return true;
121 }
122 else if (value < m_minValue || value > m_maxValue)
123 {
124 printOutOfRangeError(value);
125 return false;
126 }
127
128 return true;
129 }
130
131private:
132 const std::string m_key;
133 const ConfParameterCallback m_setterCallback;
134 T m_defaultValue;
135
136 T m_minValue;
137 T m_maxValue;
138
139 bool m_shouldCheckRange;
140 bool m_isRequired;
141};
142
akmhoque157b0a42014-05-13 00:26:37 -0500143bool
akmhoqueb6450b12014-04-24 00:01:03 -0500144ConfFileProcessor::processConfFile()
akmhoque53353462014-04-22 08:43:45 -0500145{
akmhoque157b0a42014-05-13 00:26:37 -0500146 bool ret = true;
147 ifstream inputFile;
148 inputFile.open(m_confFileName.c_str());
149 if (!inputFile.is_open()) {
150 string msg = "Failed to read configuration file: ";
151 msg += m_confFileName;
152 cerr << msg << endl;
akmhoquead5fe952014-06-26 13:34:12 -0500153 return false;
akmhoque157b0a42014-05-13 00:26:37 -0500154 }
155 ret = load(inputFile);
156 inputFile.close();
157 return ret;
158}
159
160bool
161ConfFileProcessor::load(istream& input)
162{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700163 ConfigSection pt;
akmhoque157b0a42014-05-13 00:26:37 -0500164 bool ret = true;
165 try {
166 boost::property_tree::read_info(input, pt);
167 }
168 catch (const boost::property_tree::info_parser_error& error) {
169 stringstream msg;
170 std::cerr << "Failed to parse configuration file " << std::endl;
171 std::cerr << m_confFileName << std::endl;
172 return false;
173 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700174
175 for (ConfigSection::const_iterator tn = pt.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500176 tn != pt.end(); ++tn) {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700177 ret = processSection(tn->first, tn->second);
akmhoque157b0a42014-05-13 00:26:37 -0500178 if (ret == false) {
179 break;
180 }
181 }
182 return ret;
183}
184
185bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700186ConfFileProcessor::processSection(const std::string& sectionName, const ConfigSection& section)
akmhoque157b0a42014-05-13 00:26:37 -0500187{
188 bool ret = true;
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700189 if (sectionName == "general")
akmhoque53353462014-04-22 08:43:45 -0500190 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700191 ret = processConfSectionGeneral(section);
akmhoque157b0a42014-05-13 00:26:37 -0500192 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700193 else if (sectionName == "neighbors")
akmhoque157b0a42014-05-13 00:26:37 -0500194 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700195 ret = processConfSectionNeighbors(section);
akmhoque157b0a42014-05-13 00:26:37 -0500196 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700197 else if (sectionName == "hyperbolic")
akmhoque157b0a42014-05-13 00:26:37 -0500198 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700199 ret = processConfSectionHyperbolic(section);
akmhoque157b0a42014-05-13 00:26:37 -0500200 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700201 else if (sectionName == "fib")
akmhoque157b0a42014-05-13 00:26:37 -0500202 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700203 ret = processConfSectionFib(section);
akmhoque157b0a42014-05-13 00:26:37 -0500204 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700205 else if (sectionName == "advertising")
akmhoque157b0a42014-05-13 00:26:37 -0500206 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700207 ret = processConfSectionAdvertising(section);
akmhoque157b0a42014-05-13 00:26:37 -0500208 }
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700209 else if (sectionName == "security")
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700210 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700211 ret = processConfSectionSecurity(section);
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700212 }
akmhoque157b0a42014-05-13 00:26:37 -0500213 else
214 {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700215 std::cerr << "Wrong configuration section: " << sectionName << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500216 }
217 return ret;
218}
219
220bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700221ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
akmhoque157b0a42014-05-13 00:26:37 -0500222{
223 try {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700224 std::string network = section.get<string>("network");
225 std::string site = section.get<string>("site");
226 std::string router = section.get<string>("router");
akmhoque157b0a42014-05-13 00:26:37 -0500227 ndn::Name networkName(network);
228 if (!networkName.empty()) {
229 m_nlsr.getConfParameter().setNetwork(networkName);
230 }
231 else {
232 cerr << " Network can not be null or empty or in bad URI format :(!" << endl;
233 return false;
234 }
235 ndn::Name siteName(site);
236 if (!siteName.empty()) {
237 m_nlsr.getConfParameter().setSiteName(siteName);
238 }
239 else {
240 cerr << "Site can not be null or empty or in bad URI format:( !" << endl;
241 return false;
242 }
243 ndn::Name routerName(router);
244 if (!routerName.empty()) {
245 m_nlsr.getConfParameter().setRouterName(routerName);
246 }
247 else {
248 cerr << " Router name can not be null or empty or in bad URI format:( !" << endl;
249 return false;
250 }
251 }
252 catch (const std::exception& ex) {
253 cerr << ex.what() << endl;
254 return false;
255 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700256
akmhoque157b0a42014-05-13 00:26:37 -0500257 try {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700258 int32_t lsaRefreshTime = section.get<int32_t>("lsa-refresh-time");
akmhoque157b0a42014-05-13 00:26:37 -0500259 if (lsaRefreshTime >= LSA_REFRESH_TIME_MIN &&
260 lsaRefreshTime <= LSA_REFRESH_TIME_MAX) {
261 m_nlsr.getConfParameter().setLsaRefreshTime(lsaRefreshTime);
262 }
263 else {
264 std::cerr << "Wrong value for lsa-refresh-time ";
265 std::cerr << "Allowed value: " << LSA_REFRESH_TIME_MIN << "-";;
266 std::cerr << LSA_REFRESH_TIME_MAX << std::endl;
267 return false;
268 }
269 }
270 catch (const std::exception& ex) {
271 std::cerr << ex.what() << std::endl;
272 return false;
273 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700274
akmhoque157b0a42014-05-13 00:26:37 -0500275 try {
Alexander Afanasyev1cf1e102014-08-17 19:47:57 -0700276 int32_t routerDeadInterval = section.get<int32_t>("router-dead-interval");
277
278 if (routerDeadInterval > m_nlsr.getConfParameter().getLsaRefreshTime()) {
279 m_nlsr.getConfParameter().setRouterDeadInterval(routerDeadInterval);
280 }
281 else {
282 std::cerr << "Value of router-dead-interval must be larger than lsa-refresh-time"
283 << std::endl;
284 return false;
285 }
286 }
287 catch (const std::exception& ex) {
288 std::cerr << ex.what() << std::endl;
289 // non-critical error. default value is 2 * lsa-refresh-time
290 }
291
292 try {
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700293 int lifetime = section.get<int>("lsa-interest-lifetime");
294 if (lifetime >= LSA_INTEREST_LIFETIME_MIN && lifetime <= LSA_INTEREST_LIFETIME_MAX) {
295 m_nlsr.getConfParameter().setLsaInterestLifetime(ndn::time::seconds(lifetime));
296 }
297 else {
298 std::cerr << "Wrong value for lsa-interest-timeout. "
299 << "Allowed value:" << LSA_INTEREST_LIFETIME_MIN << "-"
300 << LSA_INTEREST_LIFETIME_MAX << std::endl;
301 return false;
302 }
303 }
304 catch (const std::exception& ex) {
305 std::cerr << ex.what() << std::endl;
Alexander Afanasyev1cf1e102014-08-17 19:47:57 -0700306 // non-critical error. default value is 4
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700307 }
308
309 try {
Vince Lehmanf99b87f2014-08-26 15:54:27 -0500310
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700311 std::string logLevel = section.get<string>("log-level");
Vince Lehmanf99b87f2014-08-26 15:54:27 -0500312
313 if (isValidLogLevel(logLevel)) {
akmhoque157b0a42014-05-13 00:26:37 -0500314 m_nlsr.getConfParameter().setLogLevel(logLevel);
315 }
316 else {
Vince Lehmanf99b87f2014-08-26 15:54:27 -0500317 std::cerr << "Invalid value for log-level ";
318 std::cerr << "Valid values: ALL, TRACE, DEBUG, INFO, WARN, ERROR, NONE" << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500319 return false;
320 }
321 }
322 catch (const std::exception& ex) {
323 std::cerr << ex.what() << std::endl;
324 return false;
325 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700326
akmhoque674b0b12014-05-20 14:33:28 -0500327 try {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700328 std::string logDir = section.get<string>("log-dir");
akmhoque674b0b12014-05-20 14:33:28 -0500329 if (boost::filesystem::exists(logDir)) {
330 if (boost::filesystem::is_directory(logDir)) {
331 std::string testFileName=logDir+"/test.log";
332 ofstream testOutFile;
333 testOutFile.open(testFileName.c_str());
334 if (testOutFile.is_open() && testOutFile.good()) {
335 m_nlsr.getConfParameter().setLogDir(logDir);
336 }
337 else {
338 std::cerr << "User does not have read and write permission on the directory";
339 std::cerr << std::endl;
340 return false;
341 }
342 testOutFile.close();
343 remove(testFileName.c_str());
344 }
345 else {
346 std::cerr << "Provided path is not a directory" << std::endl;
347 return false;
348 }
349 }
350 else {
Muktadir R Chowdhurybfa27602014-10-31 10:57:41 -0500351 std::cerr << "Provided log directory <" << logDir << "> does not exist" << std::endl;
akmhoque674b0b12014-05-20 14:33:28 -0500352 return false;
353 }
354 }
355 catch (const std::exception& ex) {
356 std::cerr << "You must configure log directory" << std::endl;
357 std::cerr << ex.what() << std::endl;
358 return false;
359 }
Muktadir R Chowdhurybfa27602014-10-31 10:57:41 -0500360
akmhoque674b0b12014-05-20 14:33:28 -0500361 try {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700362 std::string seqDir = section.get<string>("seq-dir");
akmhoque674b0b12014-05-20 14:33:28 -0500363 if (boost::filesystem::exists(seqDir)) {
364 if (boost::filesystem::is_directory(seqDir)) {
365 std::string testFileName=seqDir+"/test.seq";
366 ofstream testOutFile;
367 testOutFile.open(testFileName.c_str());
368 if (testOutFile.is_open() && testOutFile.good()) {
369 m_nlsr.getConfParameter().setSeqFileDir(seqDir);
370 }
371 else {
372 std::cerr << "User does not have read and write permission on the directory";
373 std::cerr << std::endl;
374 return false;
375 }
376 testOutFile.close();
377 remove(testFileName.c_str());
378 }
379 else {
380 std::cerr << "Provided path is not a directory" << std::endl;
381 return false;
382 }
383 }
384 else {
Muktadir R Chowdhurybfa27602014-10-31 10:57:41 -0500385 std::cerr << "Provided sequence directory <" << seqDir << "> does not exist" << std::endl;
akmhoque674b0b12014-05-20 14:33:28 -0500386 return false;
387 }
388 }
389 catch (const std::exception& ex) {
390 std::cerr << "You must configure sequence directory" << std::endl;
391 std::cerr << ex.what() << std::endl;
392 return false;
393 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700394
Muktadir R Chowdhurybfa27602014-10-31 10:57:41 -0500395 try {
396 std::string log4cxxPath = section.get<string>("log4cxx-conf");
397
398 if (log4cxxPath == "") {
399 std::cerr << "No value provided for log4cxx-conf" << std::endl;
400 return false;
401 }
402
403 if (boost::filesystem::exists(log4cxxPath)) {
404 m_nlsr.getConfParameter().setLog4CxxConfPath(log4cxxPath);
405 }
406 else {
407 std::cerr << "Provided path for log4cxx-conf <" << log4cxxPath
408 << "> does not exist" << std::endl;
409
410 return false;
411 }
412 }
413 catch (const std::exception& ex) {
414 // Variable is optional so default configuration will be used; continue processing file
415 }
416
akmhoque157b0a42014-05-13 00:26:37 -0500417 return true;
418}
419
420bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700421ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
akmhoque157b0a42014-05-13 00:26:37 -0500422{
423 try {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700424 int retrials = section.get<int>("hello-retries");
akmhoque157b0a42014-05-13 00:26:37 -0500425 if (retrials >= HELLO_RETRIES_MIN && retrials <= HELLO_RETRIES_MAX) {
426 m_nlsr.getConfParameter().setInterestRetryNumber(retrials);
427 }
428 else {
429 std::cerr << "Wrong value for hello-retries. ";
430 std::cerr << "Allowed value:" << HELLO_RETRIES_MIN << "-";
431 std::cerr << HELLO_RETRIES_MAX << std::endl;
432 return false;
433 }
434 }
435 catch (const std::exception& ex) {
436 std::cerr << ex.what() << std::endl;
437 return false;
438 }
439 try {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700440 int timeOut = section.get<int>("hello-timeout");
akmhoque157b0a42014-05-13 00:26:37 -0500441 if (timeOut >= HELLO_TIMEOUT_MIN && timeOut <= HELLO_TIMEOUT_MAX) {
442 m_nlsr.getConfParameter().setInterestResendTime(timeOut);
443 }
444 else {
445 std::cerr << "Wrong value for hello-timeout. ";
446 std::cerr << "Allowed value:" << HELLO_TIMEOUT_MIN << "-";
447 std::cerr << HELLO_TIMEOUT_MAX << std::endl;
448 return false;
449 }
450 }
451 catch (const std::exception& ex) {
452 std::cerr << ex.what() << std::endl;
453 }
454 try {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700455 int interval = section.get<int>("hello-interval");
akmhoque157b0a42014-05-13 00:26:37 -0500456 if (interval >= HELLO_INTERVAL_MIN && interval <= HELLO_INTERVAL_MAX) {
457 m_nlsr.getConfParameter().setInfoInterestInterval(interval);
458 }
459 else {
460 std::cerr << "Wrong value for hello-interval. ";
461 std::cerr << "Allowed value:" << HELLO_INTERVAL_MIN << "-";
462 std::cerr << HELLO_INTERVAL_MAX << std::endl;
463 return false;
464 }
465 }
466 catch (const std::exception& ex) {
467 std::cerr << ex.what() << std::endl;
468 }
Vince Lehman7b616582014-10-17 16:25:39 -0500469
470 // Event intervals
471 // adj-lsa-build-interval
472 ConfigurationVariable<uint32_t> adjLsaBuildInterval("adj-lsa-build-interval",
473 bind(&ConfParameter::setAdjLsaBuildInterval,
474 &m_nlsr.getConfParameter(), _1));
475 adjLsaBuildInterval.setMinAndMaxValue(ADJ_LSA_BUILD_INTERVAL_MIN, ADJ_LSA_BUILD_INTERVAL_MAX);
476 adjLsaBuildInterval.setOptional(ADJ_LSA_BUILD_INTERVAL_DEFAULT);
477
478 if (!adjLsaBuildInterval.parseFromConfigSection(section)) {
479 return false;
480 }
481
482 // first-hello-interval
483 ConfigurationVariable<uint32_t> firstHelloInterval("first-hello-interval",
484 bind(&ConfParameter::setFirstHelloInterval,
485 &m_nlsr.getConfParameter(), _1));
486 firstHelloInterval.setMinAndMaxValue(FIRST_HELLO_INTERVAL_MIN, FIRST_HELLO_INTERVAL_MAX);
487 firstHelloInterval.setOptional(FIRST_HELLO_INTERVAL_DEFAULT);
488
489 if (!firstHelloInterval.parseFromConfigSection(section)) {
490 return false;
491 }
492
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700493 for (ConfigSection::const_iterator tn =
494 section.begin(); tn != section.end(); ++tn) {
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700495
akmhoque157b0a42014-05-13 00:26:37 -0500496 if (tn->first == "neighbor")
akmhoque53353462014-04-22 08:43:45 -0500497 {
akmhoque157b0a42014-05-13 00:26:37 -0500498 try {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700499 ConfigSection CommandAttriTree = tn->second;
akmhoque157b0a42014-05-13 00:26:37 -0500500 std::string name = CommandAttriTree.get<std::string>("name");
501 std::string faceUri = CommandAttriTree.get<std::string>("face-uri");
502 double linkCost = CommandAttriTree.get<double>("link-cost",
503 Adjacent::DEFAULT_LINK_COST);
504 ndn::Name neighborName(name);
505 if (!neighborName.empty()) {
Vince Lehmancb76ade2014-08-28 21:24:41 -0500506 Adjacent adj(name, faceUri, linkCost, Adjacent::STATUS_INACTIVE, 0, 0);
akmhoque157b0a42014-05-13 00:26:37 -0500507 m_nlsr.getAdjacencyList().insert(adj);
508 }
509 else {
akmhoque674b0b12014-05-20 14:33:28 -0500510 std::cerr << " Wrong command format ! [name /nbr/name/ \n face-uri /uri\n]";
akmhoque157b0a42014-05-13 00:26:37 -0500511 std::cerr << " or bad URI format" << std::endl;
akmhoque53353462014-04-22 08:43:45 -0500512 }
513 }
akmhoque157b0a42014-05-13 00:26:37 -0500514 catch (const std::exception& ex) {
515 std::cerr << ex.what() << std::endl;
516 return false;
517 }
akmhoque53353462014-04-22 08:43:45 -0500518 }
519 }
akmhoque157b0a42014-05-13 00:26:37 -0500520 return true;
akmhoque53353462014-04-22 08:43:45 -0500521}
522
akmhoque157b0a42014-05-13 00:26:37 -0500523bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700524ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
akmhoque53353462014-04-22 08:43:45 -0500525{
akmhoque157b0a42014-05-13 00:26:37 -0500526 std::string state;
527 try {
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700528 state= section.get<string>("state","off");
akmhoque157b0a42014-05-13 00:26:37 -0500529 if (boost::iequals(state, "off")) {
530 m_nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_OFF);
531 }
532 else if (boost::iequals(state, "on")) {
533 m_nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_ON);
534 }
535 else if (state == "dry-run") {
536 m_nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
537 }
538 else {
539 std::cerr << "Wrong format for hyperbolic state." << std::endl;
540 std::cerr << "Allowed value: off, on, dry-run" << std::endl;
541 return false;
542 }
akmhoque53353462014-04-22 08:43:45 -0500543 }
akmhoque157b0a42014-05-13 00:26:37 -0500544 catch (const std::exception& ex) {
545 std::cerr << ex.what() << std::endl;
546 return false;
akmhoque53353462014-04-22 08:43:45 -0500547 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700548
akmhoque157b0a42014-05-13 00:26:37 -0500549 try {
550 /* Radius and angle is mandatory configuration parameter in hyperbolic section.
551 * Even if router can have hyperbolic routing calculation off but other router
552 * in the network may use hyperbolic routing calculation for FIB generation.
553 * So each router need to advertise its hyperbolic coordinates in the network
554 */
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700555 double radius = section.get<double>("radius");
556 double angle = section.get<double>("angle");
akmhoque157b0a42014-05-13 00:26:37 -0500557 if (!m_nlsr.getConfParameter().setCorR(radius)) {
558 return false;
559 }
560 m_nlsr.getConfParameter().setCorTheta(angle);
akmhoque53353462014-04-22 08:43:45 -0500561 }
akmhoque157b0a42014-05-13 00:26:37 -0500562 catch (const std::exception& ex) {
563 std::cerr << ex.what() << std::endl;
564 if (state == "on" || state == "dry-run") {
565 return false;
566 }
akmhoque53353462014-04-22 08:43:45 -0500567 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700568
akmhoque157b0a42014-05-13 00:26:37 -0500569 return true;
akmhoque53353462014-04-22 08:43:45 -0500570}
571
akmhoque157b0a42014-05-13 00:26:37 -0500572bool
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700573ConfFileProcessor::processConfSectionFib(const ConfigSection& section)
akmhoque53353462014-04-22 08:43:45 -0500574{
akmhoque157b0a42014-05-13 00:26:37 -0500575 try {
576 int maxFacesPerPrefixNumber =
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700577 section.get<int>("max-faces-per-prefix");
akmhoque157b0a42014-05-13 00:26:37 -0500578 if (maxFacesPerPrefixNumber >= MAX_FACES_PER_PREFIX_MIN &&
579 maxFacesPerPrefixNumber <= MAX_FACES_PER_PREFIX_MAX)
akmhoque53353462014-04-22 08:43:45 -0500580 {
akmhoque157b0a42014-05-13 00:26:37 -0500581 m_nlsr.getConfParameter().setMaxFacesPerPrefix(maxFacesPerPrefixNumber);
akmhoque53353462014-04-22 08:43:45 -0500582 }
akmhoque157b0a42014-05-13 00:26:37 -0500583 else {
584 std::cerr << "Wrong value for max-faces-per-prefix. ";
akmhoque157b0a42014-05-13 00:26:37 -0500585 std::cerr << MAX_FACES_PER_PREFIX_MIN << std::endl;
586 return false;
akmhoque53353462014-04-22 08:43:45 -0500587 }
akmhoque53353462014-04-22 08:43:45 -0500588 }
akmhoque157b0a42014-05-13 00:26:37 -0500589 catch (const std::exception& ex) {
590 cerr << ex.what() << endl;
591 return false;
592 }
Vince Lehman7b616582014-10-17 16:25:39 -0500593
594 // routing-calc-interval
595 ConfigurationVariable<uint32_t> routingCalcInterval("routing-calc-interval",
596 bind(&ConfParameter::setRoutingCalcInterval,
597 &m_nlsr.getConfParameter(), _1));
598 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()) {
618 m_nlsr.getNamePrefixList().insert(namePrefix);
619 }
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
639 if (it == section.end() || it->first != "validator")
640 {
641 std::cerr << "Error: Expect validator section!" << std::endl;
642 return false;
643 }
644
645 m_nlsr.loadValidator(it->second, m_confFileName);
akmhoqued57f3672014-06-10 10:41:32 -0500646 it++;
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700647
648 for (; it != section.end(); it++)
649 {
650 using namespace boost::filesystem;
651 if (it->first != "cert-to-publish")
652 {
653 std::cerr << "Error: Expect cert-to-publish!" << std::endl;
654 return false;
655 }
656
657 std::string file = it->second.data();
658 path certfilePath = absolute(file, path(m_confFileName).parent_path());
659 ndn::shared_ptr<ndn::IdentityCertificate> idCert =
660 ndn::io::load<ndn::IdentityCertificate>(certfilePath.string());
661
662 if (!static_cast<bool>(idCert))
663 {
664 std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
665 return false;
666 }
667
668 m_nlsr.loadCertToPublish(idCert);
669 }
670
671 return true;
672}
673
Muktadir R Chowdhurybfa27602014-10-31 10:57:41 -0500674} // namespace nlsr