blob: 09db6b230db855df414aa5ad140a4b6000ce8132 [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
Yingdi Yudefb5e42014-03-31 18:18:09 -070037Nrd::Nrd(const std::string& validatorConfig)
38 : m_face(new Face())
Yingdi Yudefb5e42014-03-31 18:18:09 -070039 , m_nfdController(new nfd::Controller(*m_face))
Obaid68711872014-04-08 03:16:40 -050040 , m_validator(m_face)
41 , m_faceMonitor(*m_face)
Alexander Afanasyevd9e98732014-03-27 16:09:10 -070042 , m_verbDispatch(COMMAND_VERBS,
Obaid3f48fe52014-02-27 21:45:23 -060043 COMMAND_VERBS + (sizeof(COMMAND_VERBS) / sizeof(VerbAndProcessor)))
44{
Obaidea56c612014-03-17 22:50:47 -050045 //check whether the components of localhop and localhost prefixes are same
Alexander Afanasyev80f06a52014-03-27 14:40:00 -070046 BOOST_ASSERT(COMMAND_PREFIX.size() == REMOTE_COMMAND_PREFIX.size());
Obaidea56c612014-03-17 22:50:47 -050047
Yingdi Yudefb5e42014-03-31 18:18:09 -070048 m_validator.load(validatorConfig);
49
Obaidea56c612014-03-17 22:50:47 -050050 std::cerr << "Setting interest filter on: " << COMMAND_PREFIX.toUri() << std::endl;
Yingdi Yudefb5e42014-03-31 18:18:09 -070051 m_face->setController(m_nfdController);
52 m_face->setInterestFilter(COMMAND_PREFIX.toUri(),
53 bind(&Nrd::onRibRequest, this, _2),
54 bind(&Nrd::setInterestFilterFailed, this, _1, _2));
Alexander Afanasyev80f06a52014-03-27 14:40:00 -070055
Obaidea56c612014-03-17 22:50:47 -050056 std::cerr << "Setting interest filter on: " << REMOTE_COMMAND_PREFIX.toUri() << std::endl;
Yingdi Yudefb5e42014-03-31 18:18:09 -070057 m_face->setInterestFilter(REMOTE_COMMAND_PREFIX.toUri(),
58 bind(&Nrd::onRibRequest, this, _2),
59 bind(&Nrd::setInterestFilterFailed, this, _1, _2));
Obaid68711872014-04-08 03:16:40 -050060
61 std::cerr << "Monitoring faces" << std::endl;
62 m_faceMonitor.addSubscriber(boost::bind(&Nrd::onNotification, this, _1));
63 m_faceMonitor.startNotifications();
Obaid3f48fe52014-02-27 21:45:23 -060064}
65
66void
Obaid68711872014-04-08 03:16:40 -050067Nrd::setInterestFilterFailed(const Name& name, const std::string& msg)
68{
69 std::cerr << "Error in setting interest filter (" << name << "): " << msg << std::endl;
70 m_face->shutdown();
71}
72
73
74void
Obaid3f48fe52014-02-27 21:45:23 -060075Nrd::sendResponse(const Name& name,
76 const nfd::ControlResponse& response)
77{
78 const Block& encodedControl = response.wireEncode();
79
80 Data responseData(name);
81 responseData.setContent(encodedControl);
82
83 m_keyChain.sign(responseData);
Yingdi Yudefb5e42014-03-31 18:18:09 -070084 m_face->put(responseData);
Obaid3f48fe52014-02-27 21:45:23 -060085}
86
87void
88Nrd::sendResponse(const Name& name,
89 uint32_t code,
90 const std::string& text)
91{
92 nfd::ControlResponse response(code, text);
93 sendResponse(name, response);
94}
95
96void
97Nrd::onRibRequest(const Interest& request)
98{
Yingdi Yudefb5e42014-03-31 18:18:09 -070099 m_validator.validate(request,
100 bind(&Nrd::onRibRequestValidated, this, _1),
101 bind(&Nrd::onRibRequestValidationFailed, this, _1, _2));
102}
Obaid3f48fe52014-02-27 21:45:23 -0600103
Yingdi Yudefb5e42014-03-31 18:18:09 -0700104void
105Nrd::onRibRequestValidated(const shared_ptr<const Interest>& request)
106{
107 const Name& command = request->getName();
Obaid3f48fe52014-02-27 21:45:23 -0600108
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700109 //REMOTE_COMMAND_PREFIX number of componenets are same as
Obaidea56c612014-03-17 22:50:47 -0500110 // NRD_COMMAND_PREFIX's so no extra checks are required.
Obaid3f48fe52014-02-27 21:45:23 -0600111 const Name::Component& verb = command.get(COMMAND_PREFIX.size());
112 VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find(verb);
113
114 if (verbProcessor != m_verbDispatch.end())
115 {
116 PrefixRegOptions options;
Yingdi Yudefb5e42014-03-31 18:18:09 -0700117 if (!extractOptions(*request, options))
Obaid3f48fe52014-02-27 21:45:23 -0600118 {
119 sendResponse(command, 400, "Malformed command");
120 return;
121 }
122
123 /// \todo authorize command
124 if (false)
125 {
Yingdi Yudefb5e42014-03-31 18:18:09 -0700126 sendResponse(request->getName(), 403, "Unauthorized command");
Obaid3f48fe52014-02-27 21:45:23 -0600127 return;
128 }
129
130 // \todo add proper log support
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700131 std::cout << "Received options (name, faceid, cost): " << options.getName() <<
Yingdi Yudefb5e42014-03-31 18:18:09 -0700132 ", " << options.getFaceId() << ", " << options.getCost() << std::endl;
Obaid3f48fe52014-02-27 21:45:23 -0600133
134 nfd::ControlResponse response;
Yingdi Yudefb5e42014-03-31 18:18:09 -0700135 (verbProcessor->second)(this, *request, options);
Obaid3f48fe52014-02-27 21:45:23 -0600136 }
137 else
138 {
Yingdi Yudefb5e42014-03-31 18:18:09 -0700139 sendResponse(request->getName(), 501, "Unsupported command");
Obaid3f48fe52014-02-27 21:45:23 -0600140 }
141}
142
Yingdi Yudefb5e42014-03-31 18:18:09 -0700143void
144Nrd::onRibRequestValidationFailed(const shared_ptr<const Interest>& request,
145 const std::string& failureInfo)
146{
147 sendResponse(request->getName(), 403, failureInfo);
148}
149
Obaid3f48fe52014-02-27 21:45:23 -0600150bool
151Nrd::extractOptions(const Interest& request,
152 PrefixRegOptions& extractedOptions)
153{
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700154 // const Name& command = request.getName();
155 //REMOTE_COMMAND_PREFIX is same in size of NRD_COMMAND_PREFIX
Obaidea56c612014-03-17 22:50:47 -0500156 //so no extra processing is required.
Obaid3f48fe52014-02-27 21:45:23 -0600157 const size_t optionCompIndex = COMMAND_PREFIX.size() + 1;
158
159 try
160 {
161 Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
162 extractedOptions.wireDecode(rawOptions);
163 }
164 catch (const ndn::Tlv::Error& e)
165 {
166 return false;
167 }
168
169 if (extractedOptions.getFaceId() == 0)
170 {
171 std::cout <<"IncomingFaceId: " << request.getIncomingFaceId() << std::endl;
172 extractedOptions.setFaceId(request.getIncomingFaceId());
173 }
174 return true;
175}
176
177void
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700178Nrd::onCommandError(uint32_t code, const std::string& error,
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700179 const Interest& request,
Obaid3f48fe52014-02-27 21:45:23 -0600180 const PrefixRegOptions& options)
181{
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700182 std::cout << "NFD Error: " << error << " (code: " << code << ")" << std::endl;
183
Obaid3f48fe52014-02-27 21:45:23 -0600184 nfd::ControlResponse response;
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700185
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700186 if (code == 404)
187 {
188 response.setCode(code);
189 response.setText(error);
190 }
191 else
192 {
193 response.setCode(533);
194 std::ostringstream os;
195 os << "Failure to update NFD " << "(NFD Error: " << code << " " << error << ")";
196 response.setText(os.str());
197 }
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700198
Obaid3f48fe52014-02-27 21:45:23 -0600199 sendResponse(request.getName(), response);
200 m_managedRib.erase(options);
201}
202
203void
204Nrd::onUnRegSuccess(const Interest& request, const PrefixRegOptions& options)
205{
206 nfd::ControlResponse response;
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700207
Obaid3f48fe52014-02-27 21:45:23 -0600208 response.setCode(200);
209 response.setText("Success");
210 response.setBody(options.wireEncode());
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700211
212 std::cout << "Success: Name unregistered (" <<
Yingdi Yudefb5e42014-03-31 18:18:09 -0700213 options.getName() << ", " <<
214 options.getFaceId() << ")" << std::endl;
Obaid3f48fe52014-02-27 21:45:23 -0600215 sendResponse(request.getName(), response);
216 m_managedRib.erase(options);
217}
218
219void
220Nrd::onRegSuccess(const Interest& request, const PrefixRegOptions& options)
221{
222 nfd::ControlResponse response;
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700223
Obaid3f48fe52014-02-27 21:45:23 -0600224 response.setCode(200);
225 response.setText("Success");
226 response.setBody(options.wireEncode());
Alexander Afanasyev80f06a52014-03-27 14:40:00 -0700227
228 std::cout << "Success: Name registered (" << options.getName() << ", " <<
Yingdi Yudefb5e42014-03-31 18:18:09 -0700229 options.getFaceId() << ")" << std::endl;
Obaid3f48fe52014-02-27 21:45:23 -0600230 sendResponse(request.getName(), response);
231}
232
233
234void
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
251
252void
253Nrd::deleteEntry(const Interest& request, const PrefixRegOptions& options)
254{
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700255 m_nfdController->start<nfd::FibRemoveNextHopCommand>(
Yingdi Yudefb5e42014-03-31 18:18:09 -0700256 nfd::ControlParameters()
257 .setName(options.getName())
258 .setFaceId(options.getFaceId()),
259 bind(&Nrd::onUnRegSuccess, this, request, options),
260 bind(&Nrd::onCommandError, this, _1, _2, request, options));
Obaid3f48fe52014-02-27 21:45:23 -0600261}
262
263
264void
265Nrd::listen()
266{
267 std::cout << "NRD started: listening for incoming interests" << std::endl;
Yingdi Yudefb5e42014-03-31 18:18:09 -0700268 m_face->processEvents();
Obaid3f48fe52014-02-27 21:45:23 -0600269}
270
271
272void
273Nrd::onControlHeaderSuccess()
274{
275 std::cout << "Local control header enabled" << std::endl;
276}
277
278
279void
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700280Nrd::onControlHeaderError(uint32_t code, const std::string& reason)
Obaid3f48fe52014-02-27 21:45:23 -0600281{
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700282 std::cout << "Error: couldn't enable local control header "
283 << "(code: " << code << ", info: " << reason << ")" << std::endl;
Yingdi Yudefb5e42014-03-31 18:18:09 -0700284 m_face->shutdown();
Obaid3f48fe52014-02-27 21:45:23 -0600285}
286
Obaid3f48fe52014-02-27 21:45:23 -0600287void
288Nrd::enableLocalControlHeader()
289{
Alexander Afanasyevd9e98732014-03-27 16:09:10 -0700290 m_nfdController->start<nfd::FaceEnableLocalControlCommand>(
291 nfd::ControlParameters()
292 .setLocalControlFeature(nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
293 bind(&Nrd::onControlHeaderSuccess, this),
Yingdi Yudefb5e42014-03-31 18:18:09 -0700294 bind(&Nrd::onControlHeaderError, this, _1, _2));
Obaid3f48fe52014-02-27 21:45:23 -0600295}
296
Obaid68711872014-04-08 03:16:40 -0500297void
298Nrd::onNotification(const nfd::FaceEventNotification& notification)
299{
300 /// \todo A notification can be missed, in this case check Facelist
301 if (notification.getKind() == 2) { //face destroyed
302 m_managedRib.erase(notification.getFaceId());
303 }
304}
305
Obaid3f48fe52014-02-27 21:45:23 -0600306} // namespace nrd
307} // namespace ndn