blob: 492f9c2c452c01c51679f27c0c1cbae902818d39 [file] [log] [blame]
Obaid3f48fe52014-02-27 21:45:23 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "nrd.hpp"
8
9namespace ndn {
10namespace nrd {
11
12const Name Nrd::COMMAND_PREFIX = "/localhost/nrd";
Obaidea56c612014-03-17 22:50:47 -050013const Name Nrd::REMOTE_COMMAND_PREFIX = "/localhop/nrd";
Obaid3f48fe52014-02-27 21:45:23 -060014
15const size_t Nrd::COMMAND_UNSIGNED_NCOMPS =
16 Nrd::COMMAND_PREFIX.size() +
17 1 + // verb
18 1; // verb options
19
20const size_t Nrd::COMMAND_SIGNED_NCOMPS =
21 Nrd::COMMAND_UNSIGNED_NCOMPS +
22 4; // (timestamp, nonce, signed info tlv, signature tlv)
23
24const Nrd::VerbAndProcessor Nrd::COMMAND_VERBS[] =
25 {
26 VerbAndProcessor(
27 Name::Component("register"),
28 &Nrd::insertEntry
29 ),
30
31 VerbAndProcessor(
32 Name::Component("unregister"),
33 &Nrd::deleteEntry
34 ),
35 };
36
Obaid5748c0c2014-04-09 18:00:42 -050037Nrd::Nrd(const ndn::nrd::ConfigSection& securitySection,
38 const std::string& validatorConfig)
Yingdi Yudefb5e42014-03-31 18:18:09 -070039 : m_face(new Face())
Yingdi Yudefb5e42014-03-31 18:18:09 -070040 , m_nfdController(new nfd::Controller(*m_face))
Obaid68711872014-04-08 03:16:40 -050041 , m_validator(m_face)
42 , m_faceMonitor(*m_face)
Alexander Afanasyevd9e98732014-03-27 16:09:10 -070043 , m_verbDispatch(COMMAND_VERBS,
Obaid3f48fe52014-02-27 21:45:23 -060044 COMMAND_VERBS + (sizeof(COMMAND_VERBS) / sizeof(VerbAndProcessor)))
45{
Obaidea56c612014-03-17 22:50:47 -050046 //check whether the components of localhop and localhost prefixes are same
Alexander Afanasyev80f06a52014-03-27 14:40:00 -070047 BOOST_ASSERT(COMMAND_PREFIX.size() == REMOTE_COMMAND_PREFIX.size());
Obaidea56c612014-03-17 22:50:47 -050048
Obaid5748c0c2014-04-09 18:00:42 -050049 //m_validator.load(validatorConfig);
50 m_validator.load(securitySection, validatorConfig);
Yingdi Yudefb5e42014-03-31 18:18:09 -070051
Obaidea56c612014-03-17 22:50:47 -050052 std::cerr << "Setting interest filter on: " << COMMAND_PREFIX.toUri() << std::endl;
Yingdi Yudefb5e42014-03-31 18:18:09 -070053 m_face->setController(m_nfdController);
54 m_face->setInterestFilter(COMMAND_PREFIX.toUri(),
55 bind(&Nrd::onRibRequest, this, _2),
56 bind(&Nrd::setInterestFilterFailed, this, _1, _2));
Alexander Afanasyev80f06a52014-03-27 14:40:00 -070057
Obaidea56c612014-03-17 22:50:47 -050058 std::cerr << "Setting interest filter on: " << REMOTE_COMMAND_PREFIX.toUri() << std::endl;
Yingdi Yudefb5e42014-03-31 18:18:09 -070059 m_face->setInterestFilter(REMOTE_COMMAND_PREFIX.toUri(),
60 bind(&Nrd::onRibRequest, this, _2),
61 bind(&Nrd::setInterestFilterFailed, this, _1, _2));
Obaid68711872014-04-08 03:16:40 -050062
63 std::cerr << "Monitoring faces" << std::endl;
64 m_faceMonitor.addSubscriber(boost::bind(&Nrd::onNotification, this, _1));
65 m_faceMonitor.startNotifications();
Obaid3f48fe52014-02-27 21:45:23 -060066}
67
68void
Obaid68711872014-04-08 03:16:40 -050069Nrd::setInterestFilterFailed(const Name& name, const std::string& msg)
70{
71 std::cerr << "Error in setting interest filter (" << name << "): " << msg << std::endl;
72 m_face->shutdown();
73}
74
Obaid68711872014-04-08 03:16:40 -050075void
Obaid3f48fe52014-02-27 21:45:23 -060076Nrd::sendResponse(const Name& name,
77 const nfd::ControlResponse& response)
78{
79 const Block& encodedControl = response.wireEncode();
80
81 Data responseData(name);
82 responseData.setContent(encodedControl);
83
84 m_keyChain.sign(responseData);
Yingdi Yudefb5e42014-03-31 18:18:09 -070085 m_face->put(responseData);
Obaid3f48fe52014-02-27 21:45:23 -060086}
87
88void
89Nrd::sendResponse(const Name& name,
90 uint32_t code,
91 const std::string& text)
92{
93 nfd::ControlResponse response(code, text);
94 sendResponse(name, response);
95}
96
97void
98Nrd::onRibRequest(const Interest& request)
99{
Yingdi Yudefb5e42014-03-31 18:18:09 -0700100 m_validator.validate(request,
101 bind(&Nrd::onRibRequestValidated, this, _1),
102 bind(&Nrd::onRibRequestValidationFailed, this, _1, _2));
103}
Obaid3f48fe52014-02-27 21:45:23 -0600104
Yingdi Yudefb5e42014-03-31 18:18:09 -0700105void
106Nrd::onRibRequestValidated(const shared_ptr<const Interest>& request)
107{
108 const Name& command = request->getName();
Obaid3f48fe52014-02-27 21:45:23 -0600109
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700110 //REMOTE_COMMAND_PREFIX number of componenets are same as
Obaidea56c612014-03-17 22:50:47 -0500111 // NRD_COMMAND_PREFIX's so no extra checks are required.
Obaid3f48fe52014-02-27 21:45:23 -0600112 const Name::Component& verb = command.get(COMMAND_PREFIX.size());
113 VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find(verb);
114
115 if (verbProcessor != m_verbDispatch.end())
116 {
117 PrefixRegOptions options;
Yingdi Yudefb5e42014-03-31 18:18:09 -0700118 if (!extractOptions(*request, options))
Obaid3f48fe52014-02-27 21:45:23 -0600119 {
120 sendResponse(command, 400, "Malformed command");
121 return;
122 }
123
124 /// \todo authorize command
125 if (false)
126 {
Yingdi Yudefb5e42014-03-31 18:18:09 -0700127 sendResponse(request->getName(), 403, "Unauthorized command");
Obaid3f48fe52014-02-27 21:45:23 -0600128 return;
129 }
130
131 // \todo add proper log support
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700132 std::cout << "Received options (name, faceid, cost): " << options.getName() <<
Yingdi Yudefb5e42014-03-31 18:18:09 -0700133 ", " << options.getFaceId() << ", " << options.getCost() << std::endl;
Obaid3f48fe52014-02-27 21:45:23 -0600134
135 nfd::ControlResponse response;
Yingdi Yudefb5e42014-03-31 18:18:09 -0700136 (verbProcessor->second)(this, *request, options);
Obaid3f48fe52014-02-27 21:45:23 -0600137 }
138 else
139 {
Yingdi Yudefb5e42014-03-31 18:18:09 -0700140 sendResponse(request->getName(), 501, "Unsupported command");
Obaid3f48fe52014-02-27 21:45:23 -0600141 }
142}
143
Yingdi Yudefb5e42014-03-31 18:18:09 -0700144void
145Nrd::onRibRequestValidationFailed(const shared_ptr<const Interest>& request,
146 const std::string& failureInfo)
147{
148 sendResponse(request->getName(), 403, failureInfo);
149}
150
Obaid3f48fe52014-02-27 21:45:23 -0600151bool
152Nrd::extractOptions(const Interest& request,
153 PrefixRegOptions& extractedOptions)
154{
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700155 // const Name& command = request.getName();
156 //REMOTE_COMMAND_PREFIX is same in size of NRD_COMMAND_PREFIX
Obaidea56c612014-03-17 22:50:47 -0500157 //so no extra processing is required.
Obaid3f48fe52014-02-27 21:45:23 -0600158 const size_t optionCompIndex = COMMAND_PREFIX.size() + 1;
159
160 try
161 {
162 Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
163 extractedOptions.wireDecode(rawOptions);
164 }
165 catch (const ndn::Tlv::Error& e)
166 {
167 return false;
168 }
169
170 if (extractedOptions.getFaceId() == 0)
171 {
172 std::cout <<"IncomingFaceId: " << request.getIncomingFaceId() << std::endl;
173 extractedOptions.setFaceId(request.getIncomingFaceId());
174 }
175 return true;
176}
177
178void
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700179Nrd::onCommandError(uint32_t code, const std::string& error,
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700180 const Interest& request,
Obaid3f48fe52014-02-27 21:45:23 -0600181 const PrefixRegOptions& options)
182{
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700183 std::cout << "NFD Error: " << error << " (code: " << code << ")" << std::endl;
184
Obaid3f48fe52014-02-27 21:45:23 -0600185 nfd::ControlResponse response;
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700186
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700187 if (code == 404)
188 {
189 response.setCode(code);
190 response.setText(error);
191 }
192 else
193 {
194 response.setCode(533);
195 std::ostringstream os;
196 os << "Failure to update NFD " << "(NFD Error: " << code << " " << error << ")";
197 response.setText(os.str());
198 }
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700199
Obaid3f48fe52014-02-27 21:45:23 -0600200 sendResponse(request.getName(), response);
201 m_managedRib.erase(options);
202}
203
204void
205Nrd::onUnRegSuccess(const Interest& request, const PrefixRegOptions& options)
206{
207 nfd::ControlResponse response;
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700208
Obaid3f48fe52014-02-27 21:45:23 -0600209 response.setCode(200);
210 response.setText("Success");
211 response.setBody(options.wireEncode());
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700212
213 std::cout << "Success: Name unregistered (" <<
Yingdi Yudefb5e42014-03-31 18:18:09 -0700214 options.getName() << ", " <<
215 options.getFaceId() << ")" << std::endl;
Obaid3f48fe52014-02-27 21:45:23 -0600216 sendResponse(request.getName(), response);
217 m_managedRib.erase(options);
218}
219
220void
221Nrd::onRegSuccess(const Interest& request, const PrefixRegOptions& options)
222{
223 nfd::ControlResponse response;
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700224
Obaid3f48fe52014-02-27 21:45:23 -0600225 response.setCode(200);
226 response.setText("Success");
227 response.setBody(options.wireEncode());
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700228
229 std::cout << "Success: Name registered (" << options.getName() << ", " <<
Yingdi Yudefb5e42014-03-31 18:18:09 -0700230 options.getFaceId() << ")" << std::endl;
Obaid3f48fe52014-02-27 21:45:23 -0600231 sendResponse(request.getName(), response);
232}
233
Obaid3f48fe52014-02-27 21:45:23 -0600234void
235Nrd::insertEntry(const Interest& request, const PrefixRegOptions& options)
236{
237 // For right now, just pass the options to fib as it is,
238 // without processing flags. Later options will be first added to
239 // Rib tree, then nrd will generate fib updates based on flags and then
240 // will add next hops one by one..
241 m_managedRib.insert(options);
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700242 m_nfdController->start<nfd::FibAddNextHopCommand>(
Yingdi Yudefb5e42014-03-31 18:18:09 -0700243 nfd::ControlParameters()
244 .setName(options.getName())
245 .setFaceId(options.getFaceId())
246 .setCost(options.getCost()),
247 bind(&Nrd::onRegSuccess, this, request, options),
248 bind(&Nrd::onCommandError, this, _1, _2, request, options));
Obaid3f48fe52014-02-27 21:45:23 -0600249}
250
Obaid3f48fe52014-02-27 21:45:23 -0600251void
252Nrd::deleteEntry(const Interest& request, const PrefixRegOptions& options)
253{
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700254 m_nfdController->start<nfd::FibRemoveNextHopCommand>(
Yingdi Yudefb5e42014-03-31 18:18:09 -0700255 nfd::ControlParameters()
256 .setName(options.getName())
257 .setFaceId(options.getFaceId()),
258 bind(&Nrd::onUnRegSuccess, this, request, options),
259 bind(&Nrd::onCommandError, this, _1, _2, request, options));
Obaid3f48fe52014-02-27 21:45:23 -0600260}
261
Obaid3f48fe52014-02-27 21:45:23 -0600262void
263Nrd::listen()
264{
265 std::cout << "NRD started: listening for incoming interests" << std::endl;
Yingdi Yudefb5e42014-03-31 18:18:09 -0700266 m_face->processEvents();
Obaid3f48fe52014-02-27 21:45:23 -0600267}
268
Obaid3f48fe52014-02-27 21:45:23 -0600269void
270Nrd::onControlHeaderSuccess()
271{
272 std::cout << "Local control header enabled" << std::endl;
273}
274
Obaid3f48fe52014-02-27 21:45:23 -0600275void
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700276Nrd::onControlHeaderError(uint32_t code, const std::string& reason)
Obaid3f48fe52014-02-27 21:45:23 -0600277{
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700278 std::cout << "Error: couldn't enable local control header "
279 << "(code: " << code << ", info: " << reason << ")" << std::endl;
Yingdi Yudefb5e42014-03-31 18:18:09 -0700280 m_face->shutdown();
Obaid3f48fe52014-02-27 21:45:23 -0600281}
282
Obaid3f48fe52014-02-27 21:45:23 -0600283void
284Nrd::enableLocalControlHeader()
285{
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700286 m_nfdController->start<nfd::FaceEnableLocalControlCommand>(
287 nfd::ControlParameters()
288 .setLocalControlFeature(nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
289 bind(&Nrd::onControlHeaderSuccess, this),
Yingdi Yudefb5e42014-03-31 18:18:09 -0700290 bind(&Nrd::onControlHeaderError, this, _1, _2));
Obaid3f48fe52014-02-27 21:45:23 -0600291}
292
Obaid68711872014-04-08 03:16:40 -0500293void
294Nrd::onNotification(const nfd::FaceEventNotification& notification)
295{
296 /// \todo A notification can be missed, in this case check Facelist
Obaid5748c0c2014-04-09 18:00:42 -0500297 std::cerr << "Notification Rcvd: " << notification << std::endl;
298 if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) { //face destroyed
299 m_managedRib.erase(notification.getFaceId());
300 }
Obaid68711872014-04-08 03:16:40 -0500301}
302
Obaid3f48fe52014-02-27 21:45:23 -0600303} // namespace nrd
304} // namespace ndn