prefix-update-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-2022, 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 "logger.hpp"
24 #include "lsdb.hpp"
25 #include "nlsr.hpp"
26 
27 #include <ndn-cxx/face.hpp>
28 #include <ndn-cxx/mgmt/nfd/control-response.hpp>
29 
30 #include <boost/algorithm/string.hpp>
31 #include <algorithm>
32 #include <fstream>
33 
34 namespace nlsr {
35 namespace update {
36 
37 INIT_LOGGER(update.PrefixUpdateProcessor);
38 
41 using SignerTag = ndn::SimpleTag<ndn::Name, 20>;
42 
45 static std::optional<std::string>
46 getSignerFromTag(const ndn::Interest& interest)
47 {
48  auto signerTag = interest.getTag<SignerTag>();
49  if (signerTag == nullptr) {
50  return std::nullopt;
51  }
52  else {
53  return signerTag->get().toUri();
54  }
55 }
56 
57 PrefixUpdateProcessor::PrefixUpdateProcessor(ndn::mgmt::Dispatcher& dispatcher,
58  ndn::security::ValidatorConfig& validator,
59  NamePrefixList& namePrefixList,
60  Lsdb& lsdb, const std::string& configFileName)
61  : CommandManagerBase(dispatcher, namePrefixList, lsdb, "prefix-update")
62  , m_validator(validator)
63  , m_confFileNameDynamic(configFileName)
64 {
65  NLSR_LOG_DEBUG("Setting dispatcher to capture Interests for: "
66  << ndn::Name(Nlsr::LOCALHOST_PREFIX).append("prefix-update"));
67 
68  m_dispatcher.addControlCommand<ndn::nfd::ControlParameters>(makeRelPrefix("advertise"),
69  makeAuthorization(),
70  std::bind(&PrefixUpdateProcessor::validateParameters<AdvertisePrefixCommand>,
71  this, _1),
72  std::bind(&PrefixUpdateProcessor::advertiseAndInsertPrefix, this, _1, _2, _3, _4));
73 
74  m_dispatcher.addControlCommand<ndn::nfd::ControlParameters>(makeRelPrefix("withdraw"),
75  makeAuthorization(),
76  std::bind(&PrefixUpdateProcessor::validateParameters<WithdrawPrefixCommand>,
77  this, _1),
78  std::bind(&PrefixUpdateProcessor::withdrawAndRemovePrefix, this, _1, _2, _3, _4));
79 }
80 
81 ndn::mgmt::Authorization
82 PrefixUpdateProcessor::makeAuthorization()
83 {
84  return [=] (const ndn::Name& prefix, const ndn::Interest& interest,
85  const ndn::mgmt::ControlParameters* params,
86  const ndn::mgmt::AcceptContinuation& accept,
87  const ndn::mgmt::RejectContinuation& reject) {
88  m_validator.validate(interest,
89  [accept] (const ndn::Interest& request) {
90 
91  auto signer1 = getSignerFromTag(request);
92  std::string signer = signer1.value_or("*");
93  NLSR_LOG_DEBUG("accept " << request.getName() << " signer=" << signer);
94  accept(signer);
95  },
96  [reject] (const ndn::Interest& request, const ndn::security::ValidationError& error) {
97  NLSR_LOG_DEBUG("reject " << request.getName() << " signer=" <<
98  getSignerFromTag(request).value_or("?") << ' ' << error);
99  reject(ndn::mgmt::RejectReply::STATUS403);
100  });
101  };
102 }
103 
104 void
105 PrefixUpdateProcessor::loadValidator(boost::property_tree::ptree section,
106  const std::string& filename)
107 {
108  m_validator.load(section, filename);
109 }
110 
111 bool
113 {
114  std::string line;
115  std::fstream fp(m_confFileNameDynamic);
116  if (!fp.good() || !fp.is_open()) {
117  NLSR_LOG_ERROR("Failed to open configuration file for parsing");
118  return true;
119  }
120  while (!fp.eof()) {
121  getline(fp, line);
122  if (line == prefix) {
123  return true;
124  }
125  }
126  fp.close();
127  return false;
128 }
129 
130 bool
131 PrefixUpdateProcessor::addOrDeletePrefix(const ndn::Name& prefix, bool addPrefix)
132 {
133  std::string value = " prefix " + prefix.toUri();
134  std::string fileString;
135  std::string line;
136  std::string trimedLine;
137  std::fstream input(m_confFileNameDynamic, input.in);
138  if (!input.good() || !input.is_open()) {
139  NLSR_LOG_ERROR("Failed to open configuration file for parsing");
140  return false;
141  }
142 
143  if (addPrefix) {
144  //check if prefix already exist in the nlsr configuration file
145  if (checkForPrefixInFile(value)) {
146  NLSR_LOG_ERROR("Prefix already exists in the configuration file");
147  return false;
148  }
149  while (!input.eof()) {
150  getline(input, line);
151  if (!line.empty()) {
152  fileString.append(line + "\n");
153  if (line == "advertising") {
154  getline(input, line);
155  fileString.append(line + "\n" + value + "\n");
156  }
157  }
158  }
159  }
160  else {
161  if (!checkForPrefixInFile(value)) {
162  NLSR_LOG_ERROR("Prefix doesn't exists in the configuration file");
163  return false;
164  }
165  boost::trim(value);
166  while (!input.eof()) {
167  getline(input, line);
168  if (!line.empty()) {
169  std::string trimLine = line;
170  boost::trim(trimLine);
171  if (trimLine != value) {
172  fileString.append(line + "\n");
173  }
174  }
175  }
176  }
177  input.close();
178  std::ofstream output(m_confFileNameDynamic);
179  output << fileString;
180  output.close();
181  return true;
182 }
183 
184 std::optional<bool>
186 {
187  return addOrDeletePrefix(prefix, true);
188 }
189 
190 std::optional<bool>
191 PrefixUpdateProcessor::afterWithdraw(const ndn::Name& prefix)
192 {
193  return addOrDeletePrefix(prefix, false);
194 }
195 
196 } // namespace update
197 } // namespace nlsr
static const ndn::Name LOCALHOST_PREFIX
Definition: nlsr.hpp:161
void withdrawAndRemovePrefix(const ndn::Name &prefix, const ndn::Interest &interest, const ndn::mgmt::ControlParameters &parameters, const ndn::mgmt::CommandContinuation &done)
remove desired name prefix from the advertised name prefix list or remove a prefix from the FIB if pa...
void advertiseAndInsertPrefix(const ndn::Name &prefix, const ndn::Interest &interest, const ndn::mgmt::ControlParameters &parameters, const ndn::mgmt::CommandContinuation &done)
add desired name prefix to the advertised name prefix list or insert a prefix into the FIB if paramet...
ndn::PartialName makeRelPrefix(const std::string &verb) const
generate the relative prefix for a handler by appending the verb name to the module name
ndn::mgmt::Dispatcher & m_dispatcher
void loadValidator(ConfigSection section, const std::string &filename)
Load the validator's configuration from a section of a configuration file.
std::optional< bool > afterAdvertise(const ndn::Name &prefix) override
save an advertised prefix to the nlsr configuration file returns bool from the overridden function wh...
PrefixUpdateProcessor(ndn::mgmt::Dispatcher &dispatcher, ndn::security::ValidatorConfig &validator, NamePrefixList &namePrefixList, Lsdb &lsdb, const std::string &configFileName)
bool addOrDeletePrefix(const ndn::Name &prefix, bool addPrefix)
Add or delete an advertise or withdrawn prefix to the nlsr configuration file.
std::optional< bool > afterWithdraw(const ndn::Name &prefix) override
save an advertised prefix to the nlsr configuration file returns bool from the overridden function wh...
bool checkForPrefixInFile(const std::string prefix)
Check if a prefix exists in the nlsr configuration file.
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
#define NLSR_LOG_DEBUG(x)
Definition: logger.hpp:38
#define INIT_LOGGER(name)
Definition: logger.hpp:35
#define NLSR_LOG_ERROR(x)
Definition: logger.hpp:41
ndn::SimpleTag< ndn::Name, 20 > SignerTag
an Interest tag to indicate command signer
static std::optional< std::string > getSignerFromTag(const ndn::Interest &interest)
obtain signer from SignerTag attached to Interest, if available
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California.